diff options
Diffstat (limited to 'svtools/source/brwbox')
-rw-r--r-- | svtools/source/brwbox/brwbox1.cxx | 2396 | ||||
-rw-r--r-- | svtools/source/brwbox/brwbox2.cxx | 2021 | ||||
-rw-r--r-- | svtools/source/brwbox/brwhead.cxx | 144 | ||||
-rw-r--r-- | svtools/source/brwbox/datwin.cxx | 694 | ||||
-rw-r--r-- | svtools/source/brwbox/datwin.hxx | 269 | ||||
-rw-r--r-- | svtools/source/brwbox/makefile.mk | 99 |
6 files changed, 5623 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; +} + + diff --git a/svtools/source/brwbox/brwbox2.cxx b/svtools/source/brwbox/brwbox2.cxx new file mode 100644 index 000000000000..916db78bc5c5 --- /dev/null +++ b/svtools/source/brwbox/brwbox2.cxx @@ -0,0 +1,2021 @@ +/************************************************************************* + * + * $RCSfile: brwbox2.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 <tools/debug.hxx> +#include <brwbox.hxx> +#include "datwin.hxx" + +#ifndef _SV_SALGTYPE_HXX +#include <vcl/salgtype.hxx> +#endif + +#pragma hdrstop + +#ifndef _SV_MULTISEL_HXX +#include <tools/multisel.hxx> +#endif + +#if SUPD<558 +BOOL BrowseBox::m_bFocusOnlyCursor; +Color BrowseBox::m_aCursorColor; +BrowserMode BrowseBox::m_nCurrentMode; +#endif + + +//=================================================================== + +DBG_NAMEEX(BrowseBox); + +//=================================================================== + +extern const char* BrowseBoxCheckInvariants( const void * pVoid ); + +DECLARE_LIST( BrowserColumns, BrowserColumn* ); + +//=================================================================== + +void BrowseBox::Command( const CommandEvent& rEvt ) +{ + if ( !((BrowserDataWin*)pDataWin)->bInCommand ) + Control::Command( rEvt ); +} + +//=================================================================== + +BOOL BrowseBox::IsInCommandEvent() const +{ + return ((BrowserDataWin*)pDataWin)->bInCommand; +} + +//=================================================================== + +void BrowseBox::StateChanged( StateChangedType nStateChange ) +{ + if ( STATE_CHANGE_INITSHOW == nStateChange ) + { + bBootstrapped = TRUE; // muss zuerst gesetzt werden! + + Resize(); + if ( bMultiSelection ) + uRow.pSel->SetTotalRange( Range( 0, nRowCount - 1 ) ); + if ( nRowCount == 0 ) + nCurRow = BROWSER_ENDOFSELECTION; + else if ( nCurRow == BROWSER_ENDOFSELECTION ) + nCurRow = 0; + + + if ( HasFocus() ) + { + bSelectionIsVisible = TRUE; + bHasFocus = TRUE; + } + UpdateScrollbars(); + AutoSizeLastColumn(); + CursorMoved(); + } + else if (STATE_CHANGE_ZOOM == nStateChange) + { + pDataWin->SetZoom(GetZoom()); + HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar; + if (pHeaderBar) + pHeaderBar->SetZoom(GetZoom()); + + // let the cols calc their new widths and adjust the header bar + for ( USHORT nPos = 0; nPos < pCols->Count(); ++nPos ) + { + pCols->GetObject(nPos)->ZoomChanged(GetZoom()); + if ( pHeaderBar ) + pHeaderBar->SetItemSize( pCols->GetObject(nPos)->GetId(), pCols->GetObject(nPos)->Width() ); + } + + // all our controls have to be repositioned + Resize(); + } +} + +//=================================================================== + +void BrowseBox::Select() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); +} + +//------------------------------------------------------------------- + +void BrowseBox::DoubleClick( const BrowserMouseEvent & ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); +} + +//------------------------------------------------------------------- + +void BrowseBox::CursorMoved() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); +} + +//------------------------------------------------------------------- + +long BrowseBox::QueryColumnResize( USHORT nId, long nWidth ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + return nWidth; +} + +//------------------------------------------------------------------- + +void BrowseBox::ColumnResized( USHORT nId ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); +} + +//------------------------------------------------------------------- + +void BrowseBox::ColumnMoved( USHORT nId ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); +} + +//------------------------------------------------------------------- + +void BrowseBox::StartScroll() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + //((Control*)pDataWin)->HideFocus(); + DoHideCursor( "StartScroll" ); +} + +//------------------------------------------------------------------- + +void BrowseBox::EndScroll() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + UpdateScrollbars(); + AutoSizeLastColumn(); + DoShowCursor( "EndScroll" ); +} + +//------------------------------------------------------------------- + +#pragma optimize( "", off ) + +void BrowseBox::ToggleSelection( BOOL bForce ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + // selection highlight-toggling allowed? + if ( bHideSelect ) + return; + if ( !bForce && + ( bNotToggleSel || !IsUpdateMode() || !bSelectionIsVisible ) ) + return; +//MI, 28.01.98 +// if ( !((BrowserDataWin*)pDataWin)->bHighlightToggle && +// !((BrowserDataWin*)pDataWin)->bHighlightAuto ) +// return; + + // only highlight painted areas! + bNotToggleSel = TRUE; + if ( FALSE && !((BrowserDataWin*)pDataWin)->bInPaint ) + pDataWin->Update(); + + // accumulate areas of rows to highlight + RectangleList aHighlightList; + long nLastRowInRect = 0; // fuer den CFront + + // Handle-Column nicht highlighten + BrowserColumn *pFirstCol = pCols->GetObject(0); + long nOfsX = (!pFirstCol || pFirstCol->GetId()) ? 0 : pFirstCol->Width(); + + // accumulate old row selection + long nBottomRow = nTopRow + + pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight(); + if ( nBottomRow > GetRowCount() && GetRowCount() ) + nBottomRow = GetRowCount(); + for ( long nRow = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel; + nRow != BROWSER_ENDOFSELECTION && nRow <= nBottomRow; + nRow = bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION ) + { + if ( nRow < nTopRow ) + continue; + + Rectangle aAddRect( + Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ), + Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ); + if ( aHighlightList.Count() && nLastRowInRect == ( nRow - 1 ) ) + aHighlightList.First()->Union( aAddRect ); + else + aHighlightList.Insert( new Rectangle( aAddRect ), (ULONG) 0 ); + nLastRowInRect = nRow; + } + + // unhighlight the old selection (if any) + while ( aHighlightList.Count() ) + { + Rectangle *pRect = aHighlightList.Remove( aHighlightList.Count() - 1 ); + pDataWin->Invalidate( *pRect ); + delete pRect; + } + + // unhighlight old column selection (if any) + for ( long nColId = pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION; + nColId != BROWSER_ENDOFSELECTION; + nColId = pColSel->NextSelected() ) + { + Rectangle aRect( GetFieldRectPixel(nCurRow, + pCols->GetObject(nColId)->GetId(), + FALSE ) ); + aRect.Left() -= MIN_COLUMNWIDTH; + aRect.Right() += MIN_COLUMNWIDTH; + aRect.Top() = 0; + aRect.Bottom() = pDataWin->GetOutputSizePixel().Height(); + pDataWin->Invalidate( aRect ); + } + + bNotToggleSel = FALSE; +} + +#pragma optimize( "", on ) + +//------------------------------------------------------------------- + +void BrowseBox::DrawCursor() +{ + short nCursorHideCount = GetCursorHideCount(); + BOOL bHidden = bHideCursor || !bSelectionIsVisible || + !IsUpdateMode() || bScrolling || nCurRow < 0; + + if (PaintCursorIfHiddenOnce()) + bHidden |= ( GetCursorHideCount() > 1 ); + else + bHidden |= ( GetCursorHideCount() > 0 ); +// bHidden |= ( GetCursorHideCount() > 0 ) && !( ( !m_bFocusOnlyCursor && GetCursorHideCount() == 1 ) && !HasFocus() ); + // hidden if the hide count non-zero + // exception : we hided the cursor exactly once in LoseFocus and we have to show the cursor + + // keine Cursor auf Handle-Column + if ( nCurColId == 0 ) + nCurColId = GetColumnId(1); + + // Cursor-Rechteck berechnen + Rectangle aCursor; + if ( bColumnCursor ) + { + aCursor = GetFieldRectPixel( nCurRow, nCurColId, FALSE ); + //! --aCursor.Bottom(); + aCursor.Left() -= MIN_COLUMNWIDTH; + aCursor.Right() += 1; + aCursor.Bottom() += 1; + } + else + aCursor = Rectangle( + Point( ( pCols->Count() && pCols->GetObject(0)->GetId() == 0 ) ? + pCols->GetObject(0)->Width() : 0, + (nCurRow - nTopRow) * GetDataRowHeight() + 1 ), + Size( pDataWin->GetOutputSizePixel().Width() + 1, + GetDataRowHeight() - 2 ) ); + if ( bHLines ) + { + if ( !bMultiSelection ) + --aCursor.Top(); + --aCursor.Bottom(); + } + + //!mi_mac pDataWin->Update(); + + if (m_aCursorColor == COL_TRANSPARENT) + { + // auf diesem Plattformen funktioniert der StarView-Focus richtig + if ( bHidden ) + ((Control*)pDataWin)->HideFocus(); + else + ((Control*)pDataWin)->ShowFocus( aCursor ); + } + else + { + Color rCol = bHidden ? pDataWin->GetFillColor() : m_aCursorColor; + Color aOldFillColor = pDataWin->GetFillColor(); + Color aOldLineColor = pDataWin->GetLineColor(); + pDataWin->SetFillColor(); + pDataWin->SetLineColor( rCol ); + pDataWin->DrawRect( aCursor ); + pDataWin->SetLineColor( aOldLineColor ); + pDataWin->SetFillColor( aOldFillColor ); + } +} + +//------------------------------------------------------------------- + +ULONG BrowseBox::GetColumnWidth( USHORT nId ) const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + USHORT nItemPos = GetColumnPos( nId ); + if ( nItemPos >= pCols->Count() ) + return 0; + return pCols->GetObject(nItemPos)->Width(); +} + +//------------------------------------------------------------------- + +USHORT BrowseBox::GetColumnId( USHORT nPos ) const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + if ( nPos >= pCols->Count() ) + return 0; + return pCols->GetObject(nPos)->GetId(); +} + +//------------------------------------------------------------------- + +USHORT BrowseBox::GetColumnPos( USHORT nId ) const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + for ( USHORT nPos = 0; nPos < pCols->Count(); ++nPos ) + if ( pCols->GetObject(nPos)->GetId() == nId ) + return nPos; + return BROWSER_INVALIDID; +} + +//------------------------------------------------------------------- + +BOOL BrowseBox::IsFrozen( USHORT nColumnId ) const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + for ( USHORT nPos = 0; nPos < pCols->Count(); ++nPos ) + if ( pCols->GetObject(nPos)->GetId() == nColumnId ) + return pCols->GetObject(nPos)->IsFrozen(); + return FALSE; +} + +//------------------------------------------------------------------- + +void BrowseBox::ExpandRowSelection( const BrowserMouseEvent& rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + DoHideCursor( "ExpandRowSelection" ); + + // expand the last selection + if ( bMultiSelection ) + { + Range aJustifiedRange( aSelRange ); + aJustifiedRange.Justify(); + + BOOL bSelectThis = + ( bSelect && !aJustifiedRange.IsInside( rEvt.GetRow() ) ) || + ( !bSelect && aJustifiedRange.IsInside( rEvt.GetRow() ) ); + + if ( aJustifiedRange.IsInside( rEvt.GetRow() ) ) + { + // down and up + while ( rEvt.GetRow() < aSelRange.Max() ) + { // ZTC/Mac bug - dont put these statemants together! + SelectRow( aSelRange.Max(), bSelectThis, TRUE ); + --aSelRange.Max(); + } + while ( rEvt.GetRow() > aSelRange.Max() ) + { // ZTC/Mac bug - dont put these statemants together! + SelectRow( aSelRange.Max(), bSelectThis, TRUE ); + ++aSelRange.Max(); + } + } + else + { + // up and down + BOOL bOldSelecting = bSelecting; + bSelecting = TRUE; + while ( rEvt.GetRow() < aSelRange.Max() ) + { // ZTC/Mac bug - dont put these statemants together! + --aSelRange.Max(); + if ( !IsRowSelected( aSelRange.Max() ) ) + { + SelectRow( aSelRange.Max(), bSelectThis, TRUE ); + bSelect = TRUE; + } + } + while ( rEvt.GetRow() > aSelRange.Max() ) + { // ZTC/Mac bug - dont put these statemants together! + ++aSelRange.Max(); + if ( !IsRowSelected( aSelRange.Max() ) ) + { + SelectRow( aSelRange.Max(), bSelectThis, TRUE ); + bSelect = TRUE; + } + } + bSelecting = bOldSelecting; + if ( bSelect ) + Select(); + } + } + else + if ( !bMultiSelection || !IsRowSelected( rEvt.GetRow() ) ) + SelectRow( rEvt.GetRow(), TRUE ); + + GoToRow( rEvt.GetRow(), FALSE ); + DoShowCursor( "ExpandRowSelection" ); +} + +//------------------------------------------------------------------- + +void BrowseBox::Resize() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + if ( !bBootstrapped && IsReallyVisible() ) + BrowseBox::StateChanged( STATE_CHANGE_INITSHOW ); + if ( !pCols->Count() ) + { + ((BrowserDataWin*)pDataWin)->bResizeOnPaint = TRUE; + return; + } + ((BrowserDataWin*)pDataWin)->bResizeOnPaint = FALSE; + + // calc the size of the scrollbars + // (we can't ask the scrollbars for their widths cause if we're zoomed they still have to be + // resized - which is done in UpdateScrollbars) + ULONG nSBSize = GetSettings().GetStyleSettings().GetScrollBarSize(); + if (IsZoom()) + nSBSize = (ULONG)(nSBSize * (double)GetZoom()); + + long nSize = pDataWin->GetPosPixel().Y(); + if( !((BrowserDataWin*)pDataWin)->bNoHScroll ) + nSize += aHScroll.GetSizePixel().Height(); + if ( GetOutputSizePixel().Height() < nSize ) return; + + DoHideCursor( "Resize" ); + USHORT nOldVisibleRows = + (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1); + + // did we need a horiz. scroll bar oder gibt es eine Control Area? + if ( !((BrowserDataWin*)pDataWin)->bNoHScroll && + ( ( pCols->Count() - FrozenColCount() ) > 1 || nControlAreaWidth > 0 ) ) + aHScroll.Show(); + else + aHScroll.Hide(); + + // calculate the size of the data window + long nDataHeight = GetOutputSizePixel().Height() - GetTitleHeight(); + if ( aHScroll.IsVisible() ) + nDataHeight -= nSBSize; + + long nDataWidth = GetOutputSizePixel().Width(); + if ( pVScroll->IsVisible() ) + nDataWidth -= nSBSize; + + // adjust position and size of data window + pDataWin->SetPosSizePixel( + Point( 0, GetTitleHeight() ), + Size( nDataWidth, nDataHeight ) ); + + USHORT nVisibleRows = + (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1); + + // TopRow ist unveraendert, aber die Anzahl sichtbarer Zeilen hat sich + // geaendert + if ( nVisibleRows != nOldVisibleRows ) + VisibleRowsChanged(nTopRow, nVisibleRows); + + UpdateScrollbars(); + + // Control-Area + Rectangle aInvalidArea( GetControlArea() ); + aInvalidArea.Right() = GetOutputSizePixel().Width(); + aInvalidArea.Left() = 0; + Invalidate( aInvalidArea ); + + // external header-bar + HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar; + if ( pHeaderBar ) + { + // Handle-Column beruecksichtigen + BrowserColumn *pFirstCol = pCols->GetObject(0); + long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width(); + pHeaderBar->SetPosPixel( Point( nOfsX, 0 ) ); + pHeaderBar->SetSizePixel( Size( GetOutputSizePixel().Width() - nOfsX, GetTitleHeight() ) ); + } + + AutoSizeLastColumn(); // adjust last column width + DoShowCursor( "Resize" ); +} + +//------------------------------------------------------------------- + +void BrowseBox::Paint( const Rectangle& rRect ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + // initializations + if ( !bBootstrapped && IsReallyVisible() ) + BrowseBox::StateChanged( STATE_CHANGE_INITSHOW ); + if ( !pCols->Count() ) + return; + + BrowserColumn *pFirstCol = pCols->GetObject(0); + BOOL bHandleCol = pFirstCol && pFirstCol->GetId() == 0; + BOOL bHeaderBar = ((BrowserDataWin*)pDataWin)->pHeaderBar != NULL; + + // draw delimitational lines + if ( !((BrowserDataWin*)pDataWin)->bNoHScroll ) + DrawLine( Point( 0, aHScroll.GetPosPixel().Y() ), + Point( GetOutputSizePixel().Width(), + aHScroll.GetPosPixel().Y() ) ); + + if ( nTitleLines ) + { + if ( !bHeaderBar ) + DrawLine( Point( 0, GetTitleHeight() - 1 ), + Point( GetOutputSizePixel().Width(), + GetTitleHeight() - 1 ) ); + else if ( bHandleCol ) + DrawLine( Point( 0, GetTitleHeight() - 1 ), + Point( pFirstCol->Width(), GetTitleHeight() - 1 ) ); + } + + // Title Bar + // Wenn es eine Handle Column gibt und die Headerbar verfuegbar ist, dann nur + // die HandleColumn + // Handle-Column beruecksichtigen + if ( nTitleLines && (!bHeaderBar || bHandleCol) ) + { + // iterate through columns to redraw + long nX = 0; + USHORT nCol; + for ( nCol = 0; + nCol < pCols->Count() && nX < rRect.Right(); + ++nCol ) + { + // skip invisible colums between frozen and scrollable area + if ( nCol < nFirstCol && !pCols->GetObject(nCol)->IsFrozen() ) + nCol = nFirstCol; + + // nur die HandleCol ? + if (bHeaderBar && bHandleCol && nCol > 0) + break; + + BrowserColumn *pCol = pCols->GetObject(nCol); + + // draw the column and increment position + if ( pCol->Width() > 4 ) + { + ButtonFrame aButtonFrame( Point( nX, 0 ), + Size( pCol->Width()-1, GetTitleHeight()-1 ), + pCol->Title(), FALSE, FALSE, + 0 != (BROWSER_COLUMN_TITLEABBREVATION&pCol->Flags()) ); + aButtonFrame .Draw( *this ); + DrawLine( Point( nX + pCol->Width() - 1, 0 ), + Point( nX + pCol->Width() - 1, GetTitleHeight()-1 ) ); + } + else + { + Color aOldFillColor = GetFillColor(); + SetFillColor( Color( COL_BLACK ) ); + DrawRect( Rectangle( Point( nX, 0 ), Size( pCol->Width(), GetTitleHeight() - 1 ) ) ); + SetFillColor( aOldFillColor ); + } + + // skip column + nX += pCol->Width(); + } + + // retouching + if ( !bHeaderBar && nCol == pCols->Count() ) + { + const StyleSettings &rSettings = GetSettings().GetStyleSettings(); + Color aColFace( rSettings.GetFaceColor() ); + Color aOldFillColor = GetFillColor(); + Color aOldLineColor = GetLineColor(); + SetFillColor( aColFace ); + SetLineColor( aColFace ); + DrawRect( Rectangle( + Point( nX, 0 ), + Point( rRect.Right(), GetTitleHeight() - 2 ) ) ); + SetFillColor( aOldLineColor ); + SetLineColor( aOldFillColor ); + } + } +} + +//------------------------------------------------------------------- + +void BrowseBox::PaintRow( OutputDevice &rDev, const Rectangle &rRect ) +{ +} + +//------------------------------------------------------------------- + +void BrowseBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags ) +{ + BOOL bDrawSelection = (nFlags & WINDOW_DRAW_NOSELECTION) == 0; + + // we need pixel coordinates + Size aRealSize = pDev->LogicToPixel(rSize); + Point aRealPos = pDev->LogicToPixel(rPos); + + if ((rSize.Width() < 3) || (rSize.Height() < 3)) + // we want to have two pixels frame ... + return; + + Font aFont = GetDataWindow().GetDrawPixelFont( pDev ); + // the 'normal' painting uses always the data window as device to output to, so we have to calc the new font + // relative to the data wins current settings + + pDev->Push(); + pDev->SetMapMode(); + pDev->SetFont( aFont ); + + // draw a frame + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + pDev->SetLineColor(rStyleSettings.GetDarkShadowColor()); + pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()), + Point(aRealPos.X(), aRealPos.Y() + aRealSize.Height() - 1)); + pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()), + Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y())); + pDev->SetLineColor(rStyleSettings.GetShadowColor()); + pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + 1), + Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1)); + pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1), + Point(aRealPos.X() + 1, aRealPos.Y() + aRealSize.Height() - 1)); + + HeaderBar* pBar = ((BrowserDataWin*)pDataWin)->pHeaderBar; + + // we're drawing onto a foreign device, so we have to fake the DataRowHeight for the subsequent ImplPaintData + // (as it is based on the settings of our data window, not the foreign device) + if (!nDataRowHeight) + ImpGetDataRowHeight(); + long nHeightLogic = PixelToLogic(Size(0, nDataRowHeight), MAP_10TH_MM).Height(); + long nForeignHeightPixel = pDev->LogicToPixel(Size(0, nHeightLogic), MAP_10TH_MM).Height(); + + long nOriginalHeight = nDataRowHeight; + nDataRowHeight = nForeignHeightPixel; + + // this counts for the column widths, too + USHORT nPos; + for ( nPos = 0; nPos < pCols->Count(); ++nPos ) + { + BrowserColumn* pCurrent = pCols->GetObject(nPos); + + long nWidthLogic = PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width(); + long nForeignWidthPixel = pDev->LogicToPixel(Size(nWidthLogic, 0), MAP_10TH_MM).Width(); + + pCurrent->SetWidth(nForeignWidthPixel, GetZoom()); + if ( pBar ) + pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() ); + } + + // a smaller area for the content + ++aRealPos.X(); + ++aRealPos.Y(); + aRealSize.Width() -= 2; + aRealSize.Height() -= 2; + + // let the header bar draw itself + if ( pBar ) + { + // the title height with respect to the font set for the given device + long nTitleHeight = PixelToLogic(Size(0, GetTitleHeight()), MAP_10TH_MM).Height(); + nTitleHeight = pDev->LogicToPixel(Size(0, nTitleHeight), MAP_10TH_MM).Height(); + + BrowserColumn* pFirstCol = pCols->Count() ? pCols->GetObject(0) : NULL; + + Point aHeaderPos(pFirstCol && (pFirstCol->GetId() == 0) ? pFirstCol->Width() : 0, 0); + Size aHeaderSize(aRealSize.Width() - aHeaderPos.X(), nTitleHeight); + + aHeaderPos += aRealPos; + // do this before converting to logics ! + + // the header's draw expects logic coordinates, again + aHeaderPos = pDev->PixelToLogic(aHeaderPos); + aHeaderSize = pDev->PixelToLogic(aHeaderSize); + + pBar->Draw(pDev, aHeaderPos, aHeaderSize, nFlags); + + // draw the "upper left cell" (the intersection between the header bar and the handle column) + if (( pFirstCol->GetId() == 0 ) && ( pFirstCol->Width() > 4 )) + { + ButtonFrame aButtonFrame( aRealPos, + Size( pFirstCol->Width()-1, nTitleHeight-1 ), + pFirstCol->Title(), FALSE, FALSE, FALSE); + aButtonFrame.Draw( *pDev ); + + Color aOldColor = pDev->GetLineColor(); + pDev->SetLineColor( Color( COL_BLACK ) ); + + pDev->DrawLine( Point( aRealPos.X(), aRealPos.Y() + nTitleHeight-1 ), + Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) ); + pDev->DrawLine( Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() ), + Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) ); + + pDev->SetLineColor( aOldColor ); + } + + aRealPos.Y() += aHeaderSize.Height(); + aRealSize.Height() -= aHeaderSize.Height(); + } + + // draw our own content (with clipping) + Region aRegion(Rectangle(aRealPos, aRealSize)); + pDev->SetClipRegion( pDev->PixelToLogic( aRegion ) ); + + // do we have to paint the background + BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && GetDataWindow().IsControlBackground(); + if ( bBackground ) + { + Rectangle aRect( aRealPos, aRealSize ); + pDev->SetFillColor( GetDataWindow().GetControlBackground() ); + pDev->DrawRect( aRect ); + } + + ImplPaintData( *pDev, Rectangle( aRealPos, aRealSize ), TRUE, bDrawSelection ); + + // restore the column widths/data row height + nDataRowHeight = nOriginalHeight; + for ( nPos = 0; nPos < pCols->Count(); ++nPos ) + { + BrowserColumn* pCurrent = pCols->GetObject(nPos); + + long nForeignWidthLogic = pDev->PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width(); + long nWidthPixel = LogicToPixel(Size(nForeignWidthLogic, 0), MAP_10TH_MM).Width(); + + pCurrent->SetWidth(nWidthPixel, GetZoom()); + if ( pBar ) + pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() ); + } + + pDev->Pop(); +} + +//------------------------------------------------------------------- + +void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, BOOL _bForeignDevice, BOOL _bDrawSelections) +{ + Point aOverallAreaPos = _bForeignDevice ? _rRect.TopLeft() : Point(0,0); + Size aOverallAreaSize = _bForeignDevice ? _rRect.GetSize() : GetDataWindow().GetOutputSizePixel(); + Point aOverallAreaBRPos = _bForeignDevice ? _rRect.BottomRight() : Point( aOverallAreaSize.Width(), aOverallAreaSize.Height() ); + + long nDataRowHeigt = GetDataRowHeight(); + + // compute relative rows to redraw + ULONG nRelTopRow = _bForeignDevice ? 0 : ((ULONG)_rRect.Top() / nDataRowHeigt); + ULONG nRelBottomRow = (ULONG)(_bForeignDevice ? aOverallAreaSize.Height() : _rRect.Bottom()) / nDataRowHeigt; + + // cache frequently used values + Point aPos( aOverallAreaPos.X(), nRelTopRow * nDataRowHeigt + aOverallAreaPos.Y() ); + _rOut.SetLineColor( Color( COL_WHITE ) ); + const StyleSettings &rSettings = _rOut.GetSettings().GetStyleSettings(); + const Color &rHighlightTextColor = rSettings.GetHighlightTextColor(); + const Color &rHighlightFillColor = rSettings.GetHighlightColor(); + Color aOldTextColor = _rOut.GetTextColor(); + Color aOldFillColor = _rOut.GetFillColor(); + Color aOldLineColor = _rOut.GetLineColor(); + long nHLineX = 0 == pCols->GetObject(0)->GetId() + ? pCols->GetObject(0)->Width() + : 0; + nHLineX += aOverallAreaPos.X(); + + // redraw the invalid fields + BOOL bRetouching = FALSE; + for ( ULONG nRelRow = nRelTopRow; + nRelRow <= nRelBottomRow && (ULONG)nTopRow+nRelRow < (ULONG)nRowCount; + ++nRelRow, aPos.Y() += nDataRowHeigt ) + { + // get row + // Zur Sicherheit auf zul"assigen Bereich abfragen: + DBG_ASSERT( (USHORT)(nTopRow+nRelRow) >= 0 && (USHORT)(nTopRow+nRelRow) < nRowCount, + "BrowseBox::ImplPaintData: invalid seek" ); + if ( (nTopRow+nRelRow) < 0 || (USHORT)(nTopRow+nRelRow) >= nRowCount ) + continue; + + // prepare row + ULONG nCurRow = nTopRow+nRelRow; + if ( !SeekRow( nCurRow) ) + DBG_ERROR("BrowseBox::ImplPaintData: SeekRow gescheitert"); + _rOut.SetClipRegion(); + aPos.X() = aOverallAreaPos.X(); + + + // #73325# don't paint the row outside the painting rectangle (DG) + // prepare auto-highlight + Rectangle aRowRect( Point( _rRect.TopLeft().X(), aPos.Y() ), + Size( _rRect.GetSize().Width(), nDataRowHeigt ) ); + PaintRow( _rOut, aRowRect ); + + BOOL bRowAutoHighlight = _bDrawSelections + && !bHideSelect + && ((BrowserDataWin&)GetDataWindow()).bHighlightAuto + && IsRowSelected( nCurRow ); + if ( bRowAutoHighlight ) + { + _rOut.SetTextColor( rHighlightTextColor ); + _rOut.SetFillColor( rHighlightFillColor ); + _rOut.SetLineColor(); + _rOut.DrawRect( aRowRect ); + } + + // iterate through columns to redraw + USHORT nCol; + for ( nCol = 0; nCol < pCols->Count(); ++nCol ) + { + // get column + BrowserColumn *pCol = pCols->GetObject(nCol); + + // at end of invalid area + if ( aPos.X() >= _rRect.Right() ) + break; + + // skip invisible colums between frozen and scrollable area + if ( nCol < nFirstCol && !pCol->IsFrozen() ) + { + nCol = nFirstCol; + pCol = pCols->GetObject(nCol); + if (!pCol) + { // FS - 21.05.99 - 66325 + // ist zwar eigentlich woanders (an der richtigen Stelle) gefixt, aber sicher ist sicher ... + DBG_ERROR("BrowseBox::PaintData : nFirstCol is probably invalid !"); + break; + } + } + + // prepare Column-AutoHighlight + BOOL bColAutoHighlight = _bDrawSelections + && bColumnCursor + && IsColumnSelected( pCol->GetId() ); + if ( bColAutoHighlight ) + { + _rOut.SetClipRegion(); + _rOut.SetTextColor( rHighlightTextColor ); + _rOut.SetFillColor( rHighlightFillColor ); + _rOut.SetLineColor(); + Rectangle aFieldRect( aPos, + Size( pCol->Width(), nDataRowHeigt ) ); + _rOut.DrawRect( aFieldRect ); + } + + if (!m_bFocusOnlyCursor && (pCol->GetId() == GetCurColumnId()) && (nCurRow == GetCurRow())) + DrawCursor(); + + // draw a single field + // #63864#, Sonst wird auch etwas gezeichnet, bsp Handle Column + if (pCol->Width()) + { + // clip the column's output to the field area + if (_bForeignDevice) + { // (not neccessary if painting onto the data window) + Size aFieldSize(pCol->Width(), nDataRowHeigt); + + if (aPos.X() + aFieldSize.Width() > aOverallAreaBRPos.X()) + aFieldSize.Width() = aOverallAreaBRPos.X() - aPos.X(); + + if (aPos.Y() + aFieldSize.Height() > aOverallAreaBRPos.Y() + 1) + { + // for non-handle cols we don't clip vertically : we just don't draw the cell if the line isn't completely visible + if (pCol->GetId() != 0) + continue; + aFieldSize.Height() = aOverallAreaBRPos.Y() + 1 - aPos.Y(); + } + + Region aClipToField(Rectangle(aPos, aFieldSize)); + _rOut.SetClipRegion(aClipToField); + } + pCol->Draw( *this, _rOut, aPos, FALSE ); + if (_bForeignDevice) + _rOut.SetClipRegion(); + } + + // reset Column-auto-highlight + if ( bColAutoHighlight ) + { + _rOut.SetTextColor( aOldTextColor ); + _rOut.SetFillColor( aOldFillColor ); + _rOut.SetLineColor( aOldLineColor ); + } + + // skip column + aPos.X() += pCol->Width(); + } + + if ( nCol == pCols->Count() ) + bRetouching = TRUE; + + // reset auto-highlight + if ( bRowAutoHighlight ) + { + _rOut.SetTextColor( aOldTextColor ); + _rOut.SetFillColor( aOldFillColor ); + _rOut.SetLineColor( aOldLineColor ); + } + + if ( bHLines ) + { + // draw horizontal delimitation lines + _rOut.SetClipRegion(); + Color aOldColor = _rOut.GetLineColor(); + _rOut.SetLineColor( aLineColor ); + long nY = aPos.Y() + nDataRowHeigt - 1; + if (nY <= aOverallAreaBRPos.Y()) + _rOut.DrawLine( Point( nHLineX, nY ), + Point( bVLines + ? min(long(long(aPos.X()) - 1), aOverallAreaBRPos.X()) + : aOverallAreaBRPos.X(), + nY ) ); + _rOut.SetLineColor( aOldColor ); + } + } + + if (aPos.Y() > aOverallAreaBRPos.Y() + 1) + aPos.Y() = aOverallAreaBRPos.Y() + 1; + // needed for some of the following drawing + + // retouching + _rOut.SetClipRegion(); + aOldLineColor = _rOut.GetLineColor(); + aOldFillColor = _rOut.GetFillColor(); + _rOut.SetFillColor( rSettings.GetFaceColor() ); + if ( pCols->Count() && ( pCols->GetObject(0)->GetId() == 0 ) && ( aPos.Y() <= _rRect.Bottom() ) ) + { + // fill rectangle gray below handle column + // DG: fill it only until the end of the drawing rect and not to the end, as this may overpaint handle columns + _rOut.SetLineColor( Color( COL_BLACK ) ); + _rOut.DrawRect( Rectangle( + Point( aOverallAreaPos.X() - 1, aPos.Y() - 1 ), + Point( aOverallAreaPos.X() + pCols->GetObject(0)->Width() - 1, + _rRect.Bottom() + 1) ) ); + } + _rOut.SetFillColor( aOldFillColor ); + + // draw vertical delimitational line between frozen and scrollable cols + _rOut.SetLineColor( COL_BLACK ); + long nFrozenWidth = GetFrozenWidth()-1; + _rOut.DrawLine( Point( aOverallAreaPos.X() + nFrozenWidth, aPos.Y() ), + Point( aOverallAreaPos.X() + nFrozenWidth, bHLines + ? aPos.Y() - 1 + : aOverallAreaBRPos.Y() ) ); + + // draw vertical delimitational lines? + if ( bVLines ) + { + _rOut.SetLineColor( aLineColor ); + Point aVertPos( aOverallAreaPos.X() - 1, aOverallAreaPos.Y() ); + long nDeltaY = aOverallAreaBRPos.Y(); + for ( USHORT nCol = 0; nCol < pCols->Count(); ++nCol ) + { + // get column + BrowserColumn *pCol = pCols->GetObject(nCol); + + // skip invisible colums between frozen and scrollable area + if ( nCol < nFirstCol && !pCol->IsFrozen() ) + { + nCol = nFirstCol; + pCol = pCols->GetObject(nCol); + } + + // skip column + aVertPos.X() += pCol->Width(); + + // at end of invalid area + // invalid area is first reached when X > Right + // and not >= + if ( aVertPos.X() > _rRect.Right() ) + break; + + // draw a single line + if ( pCol->GetId() != 0 ) + _rOut.DrawLine( aVertPos, Point( aVertPos.X(), + bHLines + ? aPos.Y() - 1 + : aPos.Y() + nDeltaY ) ); + } + } + + _rOut.SetLineColor( aOldLineColor ); +} + +//------------------------------------------------------------------- + +void BrowseBox::PaintData( Window& rWin, const Rectangle& rRect ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + if ( !bBootstrapped && IsReallyVisible() ) + BrowseBox::StateChanged( STATE_CHANGE_INITSHOW ); + + // initializations + if ( !pCols || !pCols->Count() || !rWin.IsUpdateMode() ) + return; + if ( ((BrowserDataWin*)pDataWin)->bResizeOnPaint ) + Resize(); + // MI: wer war das denn? Window::Update(); + + ImplPaintData(rWin, rRect, FALSE, TRUE); +} + +//------------------------------------------------------------------- + +void BrowseBox::UpdateScrollbars() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + if ( !bBootstrapped || !IsUpdateMode() ) + return; + + // Rekursionsschutz + BrowserDataWin *pBDW = (BrowserDataWin*) pDataWin; + if ( pBDW->bInUpdateScrollbars ) + { + pBDW->bHadRecursion = TRUE; + return; + } + pBDW->bInUpdateScrollbars = TRUE; + + // the size of the corner window (and the width of the VSB/height of the HSB) + ULONG nCornerSize = GetSettings().GetStyleSettings().GetScrollBarSize(); + if (IsZoom()) + nCornerSize = (ULONG)(nCornerSize * (double)GetZoom()); + + // needs VScroll? + long nMaxRows = (pDataWin->GetSizePixel().Height()) / GetDataRowHeight(); + BOOL bNeedsVScroll = ((BrowserDataWin*)pDataWin)->bAutoVScroll + ? nTopRow || nRowCount > nMaxRows + : TRUE; + Size aDataWinSize = pDataWin->GetSizePixel(); + if ( !bNeedsVScroll ) + { + if ( pVScroll->IsVisible() ) + { + pVScroll->Hide(); + Size aNewSize( aDataWinSize ); + aNewSize.Width() = GetOutputSizePixel().Width(); + aDataWinSize = aNewSize; + } + } + else if ( !pVScroll->IsVisible() ) + { + Size aNewSize( aDataWinSize ); + aNewSize.Width() = GetOutputSizePixel().Width() - nCornerSize; + aDataWinSize = aNewSize; + } + + // needs HScroll? + ULONG nLastCol = GetColumnAtXPosPixel( aDataWinSize.Width() - 1 ); + + USHORT nFrozenCols = FrozenColCount(); + BOOL bNeedsHScroll = ((BrowserDataWin*)pDataWin)->bAutoHScroll + ? nFirstCol > nFrozenCols || nLastCol <= pCols->Count() + : !((BrowserDataWin*)pDataWin)->bNoHScroll; + if ( !bNeedsHScroll ) + { + if ( aHScroll.IsVisible() ) + { + aHScroll.Hide(); + Size aNewSize( aDataWinSize ); + aNewSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight(); + aDataWinSize = aNewSize; + } + } + else if ( !aHScroll.IsVisible() ) + { + Size aNewSize( aDataWinSize ); + aNewSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight() - nCornerSize; + aDataWinSize = aNewSize; + } + + // adjust position and Width of horizontal scrollbar + ULONG nHScrX = nControlAreaWidth == USHRT_MAX + ? GetFrozenWidth() - 1 + : nControlAreaWidth; + + aHScroll.SetPosSizePixel( + Point( nHScrX, GetOutputSizePixel().Height() - nCornerSize ), + Size( aDataWinSize.Width() - nHScrX, nCornerSize ) ); + + // Scrollable Columns insgesamt + short nScrollCols = short(pCols->Count()) - (short)nFrozenCols; + /*short nVisibleHSize= max(nLastCol == BROWSER_INVALIDID + ? pCols->Count() - nFirstCol -1 + : nLastCol - nFirstCol - 1, 0); + + aHScroll.SetVisibleSize( nVisibleHSize ); + aHScroll.SetRange( Range( 0, Max( min(nScrollCols, nVisibleHSize), (short)0 ) ) ); + if ( bNeedsHScroll && !aHScroll.IsVisible() ) + aHScroll.Show();*/ + + // Sichtbare Columns + short nVisibleHSize = nLastCol == BROWSER_INVALIDID + ? (short)( pCols->Count() - nFirstCol ) + : (short)( nLastCol - nFirstCol ); + + short nRange = Max( nScrollCols, (short)0 ); + aHScroll.SetVisibleSize( nVisibleHSize ); + aHScroll.SetRange( Range( 0, nRange )); + if ( bNeedsHScroll && !aHScroll.IsVisible() ) + aHScroll.Show(); + + // adjust position and height of vertical scrollbar + pVScroll->SetPageSize( nMaxRows ); + + if ( nTopRow > nRowCount ) + { + nTopRow = nRowCount - 1; + DBG_ERROR("BrowseBox: nTopRow > nRowCount"); + } + + if ( pVScroll->GetThumbPos() != nTopRow ) + pVScroll->SetThumbPos( nTopRow ); + long nVisibleSize = Min( Min( nRowCount, nMaxRows ), long(nRowCount-nTopRow) ); + pVScroll->SetVisibleSize( nVisibleSize ? nVisibleSize : 1 ); + pVScroll->SetRange( Range( 0, nRowCount ) ); + pVScroll->SetPosSizePixel( + Point( aDataWinSize.Width(), GetTitleHeight() ), + Size( nCornerSize, aDataWinSize.Height() ) ); + if ( nRowCount < + long( aDataWinSize.Height() / GetDataRowHeight() ) ) + ScrollRows( -nTopRow ); + long nDelta = nCornerSize; + if ( bNeedsVScroll && !pVScroll->IsVisible() ) + pVScroll->Show(); + + pDataWin->SetSizePixel( aDataWinSize ); + + // needs corner-window? + // (do that AFTER positioning BOTH scrollbars) + if ( aHScroll.IsVisible() && pVScroll && pVScroll->IsVisible() ) + { + if ( !( (BrowserDataWin*)pDataWin )->pCornerWin ) + ( (BrowserDataWin*)pDataWin )->pCornerWin = new ScrollBarBox( this, WB_3DLOOK ); + ( (BrowserDataWin*)pDataWin )->pCornerWin->SetPosSizePixel( + Point( pVScroll->GetPosPixel().X(), aHScroll.GetPosPixel().Y() ), + Size( nCornerSize, nCornerSize ) ); + ( (BrowserDataWin*)pDataWin )->pCornerWin->Show(); + } + else + DELETEZ( ( (BrowserDataWin*)pDataWin )->pCornerWin ); + + // ggf. Headerbar mitscrollen + 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 ); + } + + pBDW->bInUpdateScrollbars = FALSE; + if ( pBDW->bHadRecursion ) + { + pBDW->bHadRecursion = FALSE; + UpdateScrollbars(); + } +} + +//------------------------------------------------------------------- + +void BrowseBox::Invalidate() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + // readjust cursor and selection + if ( bMultiSelection ) + uRow.pSel->SetTotalRange( Range( 0, nRowCount-1 ) ); + else + uRow.nSel = Min( uRow.nSel, (long)(nRowCount-1) ); + nCurRow = Min( nCurRow, (long)(nRowCount-1 )); + + // BowseBox::Resize(); if Size not set, last Culumn will be cuttet ?!? + Control::Invalidate(INVALIDATE_NOCHILDREN /*OV*/ ); + ((BrowserDataWin*)pDataWin)->Invalidate(); +} + +//------------------------------------------------------------------- + +void BrowseBox::SetUpdateMode( BOOL bUpdate ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + BOOL bWasUpdate = IsUpdateMode(); + if ( bWasUpdate == bUpdate ) + return; + + Control::SetUpdateMode( bUpdate ); + // OV + // Wenn an der BrowseBox WB_CLIPCHILDREN gesetzt ist (wg. Flackerminimierung), + // wird das Datenfenster nicht von SetUpdateMode invalidiert. + if( bUpdate ) + ((BrowserDataWin*)pDataWin)->Invalidate(); + ((BrowserDataWin*)pDataWin)->SetUpdateMode( bUpdate ); + + + if ( bUpdate ) + { + if ( bBootstrapped ) + { + UpdateScrollbars(); + AutoSizeLastColumn(); + } + DoShowCursor( "SetUpdateMode" ); + } + else + DoHideCursor( "SetUpdateMode" ); +} + +//------------------------------------------------------------------- + +BOOL BrowseBox::GetUpdateMode() const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + return ((BrowserDataWin*)pDataWin)->IsUpdateMode(); +} + +//------------------------------------------------------------------- + +long BrowseBox::GetFrozenWidth() const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + long nWidth = 0; + for ( USHORT nCol = 0; + nCol < pCols->Count() && pCols->GetObject(nCol)->IsFrozen(); + ++nCol ) + nWidth += pCols->GetObject(nCol)->Width(); + return nWidth; +} + +//------------------------------------------------------------------- + +void BrowseBox::ColumnInserted( USHORT nPos ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + if ( pColSel ) + pColSel->Insert( nPos ); + UpdateScrollbars(); +} + +//------------------------------------------------------------------- + +USHORT BrowseBox::FrozenColCount() const +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + USHORT nCol; + for ( nCol = 0; + nCol < pCols->Count() && pCols->GetObject(nCol)->IsFrozen(); + ++nCol ) + /* empty loop */; + return nCol; +} + +//------------------------------------------------------------------- + +IMPL_LINK(BrowseBox,ScrollHdl,ScrollBar*,pBar) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + if ( pBar->GetDelta() == 0 ) + return 0; + + if ( pBar->GetDelta() < 0 && ((BrowserDataWin*)pDataWin)->bNoScrollBack ) + { + UpdateScrollbars(); + return 0; + } + + if ( pBar == &aHScroll ) + ScrollColumns( aHScroll.GetDelta() ); + if ( pBar == pVScroll ) + ScrollRows( pVScroll->GetDelta() ); + + return 0; +} + +//------------------------------------------------------------------- + +IMPL_LINK( BrowseBox,EndScrollHdl,ScrollBar*, pBar ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + // kein Focus grabben! + /// GrabFocus(); + + if ( /*pBar->GetDelta() <= 0 &&*/ ((BrowserDataWin*)pDataWin)->bNoScrollBack ) + { + // UpdateScrollbars(); + EndScroll(); + return 0; + } + + return 0; +} + +//------------------------------------------------------------------- + +IMPL_LINK( BrowseBox, StartDragHdl, HeaderBar*, pBar ) +{ + pBar->SetDragSize( pDataWin->GetOutputSizePixel().Height() ); + return 0; +} + +//------------------------------------------------------------------- +// MI: es wurde immer nur die 1. Spalte resized +#pragma optimize("elg",off) + +void BrowseBox::MouseButtonDown( const MouseEvent& rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + GrabFocus(); + + // onl< mouse events in the title-line are supported + const Point &rEvtPos = rEvt.GetPosPixel(); + if ( rEvtPos.Y() >= GetTitleHeight() ) + return; + + long nX = 0; + long nWidth = GetOutputSizePixel().Width(); + for ( USHORT nCol = 0; nCol < pCols->Count() && nX < nWidth; ++nCol ) + { + // is this column visible? + BrowserColumn *pCol = pCols->GetObject(nCol); + if ( pCol->IsFrozen() || nCol >= nFirstCol ) + { + // compute right end of column + long nR = nX + pCol->Width() - 1; + + // at the end of a column (and not handle column)? + if ( pCol->GetId() && Abs( nR - rEvtPos.X() ) < 2 ) + { + // start resizing the column + bResizing = TRUE; + nResizeCol = nCol; + nDragX = nResizeX = rEvtPos.X(); + SetPointer( Pointer( POINTER_HSPLIT ) ); + CaptureMouse(); + pDataWin->DrawLine( Point( nDragX, 0 ), + Point( nDragX, pDataWin->GetSizePixel().Height() ) ); + nMinResizeX = nX + MIN_COLUMNWIDTH; + return; + } + else if ( nX < rEvtPos.X() && nR > rEvtPos.X() ) + { + MouseButtonDown( BrowserMouseEvent( + this, rEvt, -1, nCol, pCol->GetId(), Rectangle() ) ); + return; + } + nX = nR + 1; + } + } + + // event occured out of data area + if ( rEvt.IsRight() ) + pDataWin->Command( + CommandEvent( Point( 1, LONG_MAX ), COMMAND_CONTEXTMENU, TRUE ) ); + else + SetNoSelection(); +} + +#pragma optimize("",on) + +//------------------------------------------------------------------- + +void BrowseBox::MouseMove( const MouseEvent& rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + Pointer aNewPointer; + + USHORT nX = 0; + for ( USHORT nCol = 0; + nCol < USHORT(pCols->Count()) && + ( nX + pCols->GetObject(nCol)->Width() ) < USHORT(GetOutputSizePixel().Width()); + ++nCol ) + // is this column visible? + if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol ) + { + // compute right end of column + BrowserColumn *pCol = pCols->GetObject(nCol); + USHORT nR = (USHORT)(nX + pCol->Width() - 1); + + // show resize-pointer? + if ( bResizing || ( pCol->GetId() && + Abs( ((long) nR ) - rEvt.GetPosPixel().X() ) < MIN_COLUMNWIDTH ) ) + { + aNewPointer = Pointer( POINTER_HSPLIT ); + if ( bResizing ) + { + // alte Hilfslinie loeschen + pDataWin->HideTracking() ; + + // erlaubte breite abholen und neues Delta + nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX ); + long nDeltaX = nDragX - nResizeX; + USHORT nId = GetColumnId(nResizeCol); + ULONG nOldWidth = GetColumnWidth(nId); + nDragX = QueryColumnResize( GetColumnId(nResizeCol), + nOldWidth + nDeltaX ) + + nResizeX - nOldWidth; + + // neue Hilfslinie zeichnen + pDataWin->ShowTracking( Rectangle( Point( nDragX, 0 ), + Size( 1, pDataWin->GetSizePixel().Height() ) ), + SHOWTRACK_SPLIT|SHOWTRACK_WINDOW ); + } + + } + + nX = nR + 1; + } + + SetPointer( aNewPointer ); +} + +//------------------------------------------------------------------- + +void BrowseBox::MouseButtonUp( const MouseEvent & rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + if ( bResizing ) + { + // Hilfslinie loeschen + pDataWin->HideTracking(); + + // width changed? + nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX ); + if ( (nDragX - nResizeX) != (long)pCols->GetObject(nResizeCol)->Width() ) + { + // resize column + long nMaxX = pDataWin->GetSizePixel().Width(); + nDragX = Min( nDragX, nMaxX ); + long nDeltaX = nDragX - nResizeX; + USHORT nId = GetColumnId(nResizeCol); + SetColumnWidth( GetColumnId(nResizeCol), GetColumnWidth(nId) + nDeltaX ); + ColumnResized( nId ); + } + + // end action + SetPointer( Pointer() ); + ReleaseMouse(); + bResizing = FALSE; + } + else + MouseButtonUp( BrowserMouseEvent( (BrowserDataWin*)pDataWin, + MouseEvent( Point( rEvt.GetPosPixel().X(), + rEvt.GetPosPixel().Y() - pDataWin->GetPosPixel().Y() ), + rEvt.GetClicks(), rEvt.GetMode(), rEvt.GetButtons(), + rEvt.GetModifier() ) ) ); +} + +//------------------------------------------------------------------- + +BOOL bExtendedMode = FALSE; +BOOL bFieldMode = FALSE; + +void BrowseBox::MouseButtonDown( const BrowserMouseEvent& rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + GrabFocus(); + + // adjust selection while and after double-click + if ( rEvt.GetClicks() == 2 ) + { + SetNoSelection(); + if ( rEvt.GetRow() >= 0 ) + { + GoToRow( rEvt.GetRow() ); + SelectRow( rEvt.GetRow(), TRUE, FALSE ); + } + else if ( bColumnCursor && rEvt.GetColumn() != 0 ) + SelectColumnPos( rEvt.GetColumn(), TRUE, FALSE); + DoubleClick( rEvt ); + } + // selections + else if ( ( rEvt.GetMode() & ( MOUSE_SELECT | MOUSE_SIMPLECLICK ) ) && + ( bColumnCursor || rEvt.GetRow() >= 0 ) ) + { + if ( rEvt.GetClicks() == 1 ) + { + // initialise flags + bDrag = FALSE; + bHit = FALSE; + bRubber = FALSE; + a1stPoint = + a2ndPoint = PixelToLogic( rEvt.GetPosPixel() ); + + // selection out of range? + if ( rEvt.GetRow() >= nRowCount || + rEvt.GetColumnId() == BROWSER_INVALIDID ) + { + SetNoSelection(); + return; + } + + // while selecting, no cursor + bSelecting = TRUE; + DoHideCursor( "MouseButtonDown" ); + + // DataRow? + if ( rEvt.GetRow() >= 0 ) + { + // Zeilenselektion? + if ( rEvt.GetColumnId() == 0 || !bColumnCursor ) + { + if ( bMultiSelection ) + { + // remove column-selection, if exists + if ( pColSel && pColSel->GetSelectCount() ) + { + ToggleSelection(); + if ( bMultiSelection ) + uRow.pSel->SelectAll(FALSE); + else + uRow.nSel = BROWSER_ENDOFSELECTION; + if ( pColSel ) + pColSel->SelectAll(FALSE); + bSelect = TRUE; + } + + // expanding mode? + if ( rEvt.GetMode() & MOUSE_RANGESELECT ) + { + // select the further touched rows too + bSelect = TRUE; + ExpandRowSelection( rEvt ); + return; + } + + // click in the selected area? + else if ( IsRowSelected( rEvt.GetRow() ) ) + { + // auf Drag&Drop warten + bHit = TRUE; + bExtendedMode = MOUSE_MULTISELECT == + ( rEvt.GetMode() & MOUSE_MULTISELECT ); + return; + } + + // extension mode? + else if ( rEvt.GetMode() & MOUSE_MULTISELECT ) + { + // determine the new selection range + // and selection/deselection + aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() ); + SelectRow( rEvt.GetRow(), + !uRow.pSel->IsSelected( rEvt.GetRow() ) ); + bSelect = TRUE; + return; + } + } + + // select directly + SetNoSelection(); + GoToRow( rEvt.GetRow() ); + SelectRow( rEvt.GetRow(), TRUE ); + aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() ); + bSelect = TRUE; + } + else // Column/Field-Selection + { + // click in selected column + if ( IsColumnSelected( rEvt.GetColumn() ) || + IsRowSelected( rEvt.GetRow() ) ) + { + bHit = TRUE; + bFieldMode = TRUE; + return; + } + + SetNoSelection(); + GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() ); + bSelect = TRUE; + } + } + else + { + if ( bMultiSelection && rEvt.GetColumnId() == 0 ) + { + // toggle all-selection + if ( uRow.pSel->GetSelectCount() > ( GetRowCount() / 2 ) ) + SetNoSelection(); + else + SelectAll(); + } + else + SelectColumnId( rEvt.GetColumnId(), TRUE, FALSE ); + } + + // ggf. Cursor wieder an + bSelecting = FALSE; + DoShowCursor( "MouseButtonDown" ); + if ( bSelect ) + Select(); + } + } +} + +//------------------------------------------------------------------- + +void BrowseBox::MouseMove( const BrowserMouseEvent &rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); +} + +//------------------------------------------------------------------- + +void BrowseBox::MouseButtonUp( const BrowserMouseEvent &rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + // D&D was possible, but did not occur + if ( bHit ) + { + aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() ); + if ( bExtendedMode ) + SelectRow( rEvt.GetRow(), FALSE ); + else + { + SetNoSelection(); + if ( bFieldMode ) + GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() ); + else + { + GoToRow( rEvt.GetRow() ); + SelectRow( rEvt.GetRow(), TRUE ); + } + } + bSelect = TRUE; + bExtendedMode = FALSE; + bFieldMode = FALSE; + bHit = FALSE; + } + + // activate cursor + if ( bSelecting ) + { + bSelecting = FALSE; + DoShowCursor( "MouseButtonUp" ); + if ( bSelect ) + Select(); + } +} + +//------------------------------------------------------------------- + +BOOL BrowseBox::Drop( const BrowserDropEvent& ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + return FALSE; +} + +//------------------------------------------------------------------- + +BOOL BrowseBox::QueryDrop( const BrowserDropEvent& ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + return FALSE; +} + +//------------------------------------------------------------------- + +void BrowseBox::KeyInput( const KeyEvent& rEvt ) +{ + if ( !ProcessKey( rEvt ) ) + Control::KeyInput( rEvt ); +} + +//------------------------------------------------------------------- + +BOOL BrowseBox::ProcessKey( const KeyEvent& rEvt ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + USHORT nCode = rEvt.GetKeyCode().GetCode(); + BOOL bShift = rEvt.GetKeyCode().IsShift(); + BOOL bCtrl = rEvt.GetKeyCode().IsMod1(); + BOOL bAlt = rEvt.GetKeyCode().IsMod2(); + + USHORT nId = BROWSER_NONE; + + if ( !bAlt && !bCtrl && !bShift ) + { + switch ( nCode ) + { + case KEY_DOWN: nId = BROWSER_CURSORDOWN; break; + case KEY_UP: nId = BROWSER_CURSORUP; break; + case KEY_HOME: nId = BROWSER_CURSORHOME; break; + case KEY_END: nId = BROWSER_CURSOREND; break; + case KEY_TAB: + if ( !bColumnCursor ) + break; + case KEY_RIGHT: nId = BROWSER_CURSORRIGHT; break; + case KEY_LEFT: nId = BROWSER_CURSORLEFT; break; + case KEY_SPACE: nId = BROWSER_SELECT; break; + } + if ( BROWSER_NONE != nId ) + SetNoSelection(); + + switch ( nCode ) + { + case KEY_PAGEDOWN: nId = BROWSER_CURSORPAGEDOWN; break; + case KEY_PAGEUP: nId = BROWSER_CURSORPAGEUP; break; + } + } + + if ( !bAlt && !bCtrl && bShift ) + switch ( nCode ) + { + case KEY_DOWN: nId = BROWSER_SELECTDOWN; break; + case KEY_UP: nId = BROWSER_SELECTUP; break; + case KEY_TAB: + if ( !bColumnCursor ) + break; + nId = BROWSER_CURSORLEFT; break; + case KEY_HOME: nId = BROWSER_SELECTHOME; break; + case KEY_END: nId = BROWSER_SELECTEND; break; + } + + + if ( !bAlt && bCtrl && !bShift ) + switch ( nCode ) + { + case KEY_DOWN: nId = BROWSER_CURSORDOWN; break; + case KEY_UP: nId = BROWSER_CURSORUP; break; + case KEY_PAGEDOWN: nId = BROWSER_CURSORENDOFFILE; break; + case KEY_PAGEUP: nId = BROWSER_CURSORTOPOFFILE; break; + case KEY_HOME: nId = BROWSER_CURSORTOPOFSCREEN; break; + case KEY_END: nId = BROWSER_CURSORENDOFSCREEN; break; + case KEY_SPACE: nId = BROWSER_ENHANCESELECTION; break; + } + + if ( nId != BROWSER_NONE ) + Dispatch( nId ); + return nId != BROWSER_NONE; +} + +//------------------------------------------------------------------- + +void BrowseBox::Dispatch( USHORT nId ) +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + + long nRowsOnPage = pDataWin->GetSizePixel().Height() / GetDataRowHeight(); + BOOL bDone = FALSE; + + switch ( nId ) + { + case BROWSER_CURSORDOWN: + if ( ( GetCurRow() + 1 ) < nRowCount ) + bDone = GoToRow( GetCurRow() + 1, FALSE ); + break; + case BROWSER_CURSORUP: + if ( GetCurRow() > 0 ) + bDone = GoToRow( GetCurRow() - 1, FALSE ); + break; + case BROWSER_SELECTHOME: + { + DoHideCursor( "BROWSER_SELECTHOME" ); + for ( long nRow = GetCurRow(); nRow >= 0; --nRow ) + SelectRow( nRow ); + GoToRow( 0, TRUE ); + DoShowCursor( "BROWSER_SELECTHOME" ); + break; + } + case BROWSER_SELECTEND: + { + DoHideCursor( "BROWSER_SELECTEND" ); + long nRowCount = GetRowCount(); + for ( long nRow = GetCurRow(); nRow < nRowCount; ++nRow ) + SelectRow( nRow ); + GoToRow( GetRowCount() - 1, TRUE ); + DoShowCursor( "BROWSER_SELECTEND" ); + break; + } + case BROWSER_SELECTDOWN: + { + if ( ( GetCurRow() + 1 ) < nRowCount ) + { + // deselect the current row, if it isn't the first + // and there is no other selected row above + long nCurRow = GetCurRow(); + BOOL bSelect = ( !IsRowSelected( nCurRow ) || + GetSelectRowCount() == 1 || IsRowSelected( nCurRow - 1 ) ); + SelectRow( nCurRow, bSelect, TRUE ); + if ( bDone = GoToRow( GetCurRow() + 1 , FALSE ) ) + SelectRow( GetCurRow(), TRUE, TRUE ); + } + else + bDone = ScrollRows( 1 ) != 0; + break; + } + case BROWSER_SELECTUP: + { + // deselect the current row, if it isn't the first + // and there is no other selected row under + long nCurRow = GetCurRow(); + BOOL bSelect = ( !IsRowSelected( nCurRow ) || + GetSelectRowCount() == 1 || IsRowSelected( nCurRow + 1 ) ); + SelectRow( nCurRow, bSelect, TRUE ); + if ( bDone = GoToRow( nCurRow - 1 , FALSE ) ) + SelectRow( GetCurRow(), TRUE, TRUE ); + break; + } + case BROWSER_CURSORPAGEDOWN: + bDone = (BOOL)ScrollRows( nRowsOnPage ); + break; + case BROWSER_CURSORPAGEUP: + bDone = (BOOL)ScrollRows( -nRowsOnPage ); + break; + case BROWSER_CURSOREND: + if ( bColumnCursor ) + { + USHORT nNewId = GetColumnId(ColCount() -1); + bDone = (nNewId != 0) && GoToColumnId( nNewId ); + break; + } + case BROWSER_CURSORENDOFFILE: + bDone = GoToRow( nRowCount - 1, FALSE ); + break; + case BROWSER_CURSORRIGHT: + if ( bColumnCursor ) + { + USHORT nNewPos = GetColumnPos( GetCurColumnId() ) + 1; + USHORT nNewId = GetColumnId( nNewPos ); + if (nNewId != 0) // Am Zeilenende ? + bDone = GoToColumnId( nNewId ); + else + { + USHORT nColId = ( GetColumnId(0) == 0 ) ? GetColumnId(1) : GetColumnId(0); + bDone = ( nCurRow < GetRowCount() - 1 ) && GoToRowColumnId( nCurRow + 1, nColId ); + } + } + else + bDone = ScrollColumns( 1 ) != 0; + break; + case BROWSER_CURSORHOME: + if ( bColumnCursor ) + { + USHORT nNewId = GetColumnId(1); + bDone = (nNewId != 0) && GoToColumnId( nNewId ); + break; + } + case BROWSER_CURSORTOPOFFILE: + bDone = GoToRow( 0, FALSE ); + break; + case BROWSER_CURSORLEFT: + if ( bColumnCursor ) + { + USHORT nNewPos = GetColumnPos( GetCurColumnId() ) - 1; + USHORT nNewId = GetColumnId( nNewPos ); + if (nNewId != 0) + bDone = GoToColumnId( nNewId ); + else + bDone = (nCurRow > 0) && GoToRowColumnId(nCurRow - 1, GetColumnId(ColCount() -1)); + } + else + bDone = ScrollColumns( -1 ) != 0; + break; + case BROWSER_ENHANCESELECTION: + SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), TRUE ); + bDone = TRUE; + break; + case BROWSER_SELECT: + SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), FALSE ); + bDone = TRUE; + break; + } + + //! return bDone; +} + +//------------------------------------------------------------------- + +void BrowseBox::LoseFocus() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + DBG_TRACE1( "BrowseBox: %p->LoseFocus", this ); + + if ( bHasFocus ) + { + DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); + DoHideCursor( "LoseFocus" ); + + if ( !bKeepHighlight ) + { + ToggleSelection(); + bSelectionIsVisible = FALSE; + } + + bHasFocus = FALSE; + } + Control::LoseFocus(); +} + +//------------------------------------------------------------------- + +void BrowseBox::GetFocus() +{ + DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); + DBG_TRACE1( "BrowseBox: %p->GetFocus", this ); + + if ( !bHasFocus ) + { + if ( !bSelectionIsVisible ) + { + bSelectionIsVisible = TRUE; + if ( bBootstrapped ) + ToggleSelection(); + } + + bHasFocus = TRUE; + DoShowCursor( "GetFocus" ); + } + Control::GetFocus(); +} + +//------------------------------------------------------------------- + +void BrowseBox::SetCursorColor(const Color& _rCol) +{ + if (_rCol == m_aCursorColor) + return; + + // ensure the cursor is hidden + DoHideCursor("SetCursorColor"); + if (!m_bFocusOnlyCursor) + DoHideCursor("SetCursorColor - force"); + + m_aCursorColor = _rCol; + + if (!m_bFocusOnlyCursor) + DoShowCursor("SetCursorColor - force"); + DoShowCursor("SetCursorColor"); +} + + diff --git a/svtools/source/brwbox/brwhead.cxx b/svtools/source/brwbox/brwhead.cxx new file mode 100644 index 000000000000..f38be0045746 --- /dev/null +++ b/svtools/source/brwbox/brwhead.cxx @@ -0,0 +1,144 @@ +/************************************************************************* + * + * $RCSfile: brwhead.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 "brwhead.hxx" +#include "brwbox.hxx" + +#pragma hdrstop + +//=================================================================== + +BrowserHeader::BrowserHeader( BrowseBox* pParent, WinBits nWinBits ) +: HeaderBar( pParent, nWinBits ), + _pBrowseBox( pParent ) +{ + long nHeight = pParent->IsZoom() ? pParent->CalcZoom(nHeight) : pParent->GetTitleHeight(); + + SetPosSizePixel( Point( 0, 0), + Size( pParent->GetOutputSizePixel().Width(), + nHeight ) ); + Show(); +} + +//------------------------------------------------------------------- + +void BrowserHeader::Command( const CommandEvent& rCEvt ) +{ + if ( !GetCurItemId() && COMMAND_CONTEXTMENU == rCEvt.GetCommand() ) + { + Point aPos( rCEvt.GetMousePosPixel() ); + _pBrowseBox->GetDataWindow().Command( CommandEvent( + Point( aPos.X(), aPos.Y() - GetSizePixel().Height() ), + COMMAND_CONTEXTMENU, rCEvt.IsMouseEvent() ) ); + } +} + +//------------------------------------------------------------------- + +void BrowserHeader::Select() +{ + HeaderBar::Select(); +} + +//------------------------------------------------------------------- + +void BrowserHeader::EndDrag() +{ + // call before other actions, it looks more nice in most cases + HeaderBar::EndDrag(); + Update(); + + // not aborted? + USHORT nId = GetCurItemId(); + if ( nId ) + { + // Handle-Column? + if ( nId == USHRT_MAX-1 ) + nId = 0; + + if ( !IsItemMode() ) + { + // column resize + _pBrowseBox->SetColumnWidth( nId, GetItemSize( nId ) ); + _pBrowseBox->ColumnResized( nId ); + SetItemSize( nId, _pBrowseBox->GetColumnWidth( nId ) ); + } + else + { + // column drag + // Hat sich die Position eigentlich veraendert + // Handlecolumn beruecksichtigen + USHORT nOldPos = _pBrowseBox->GetColumnPos(nId), + nNewPos = GetItemPos( nId ); + + if (!_pBrowseBox->GetColumnId(0)) // Handle + nNewPos++; + + if (nOldPos != nNewPos) + { + _pBrowseBox->SetColumnPos( nId, nNewPos ); + _pBrowseBox->ColumnMoved( nId ); + } + } + } +} + + diff --git a/svtools/source/brwbox/datwin.cxx b/svtools/source/brwbox/datwin.cxx new file mode 100644 index 000000000000..3bf03276acf7 --- /dev/null +++ b/svtools/source/brwbox/datwin.cxx @@ -0,0 +1,694 @@ +/************************************************************************* + * + * $RCSfile: datwin.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 "datwin.hxx" + +#pragma hdrstop + +#ifndef _APP_HXX //autogen +#include <vcl/svapp.hxx> +#endif + +#ifndef _HELP_HXX +#include <vcl/help.hxx> +#endif +#ifndef _IMAGE_HXX +#include <vcl/image.hxx> +#endif + +#include <tools/debug.hxx> + +DECLARE_LIST( BrowserColumns, BrowserColumn* ); + +//=================================================================== + +static String FitInWidth( OutputDevice& rWin, String aVal, ULONG nWidth, BOOL bAbbr ) +{ + if ( nWidth < 8 ) + return String(); + ULONG nValWidth = rWin.GetTextWidth( aVal ); + if ( nValWidth > nWidth ) + { + String aDots( "...", RTL_TEXTENCODING_IBM_850 ); + ULONG nDotsWidth = 2; + if ( bAbbr ) + nDotsWidth = rWin.GetTextWidth( aDots ); + if ( nDotsWidth > nWidth ) + aVal.Erase(); + else + { + aVal.Erase( aVal.Len() - 1 ); + while ( aVal.Len() && rWin.GetTextWidth( aVal ) + nDotsWidth > nWidth ) + aVal.Erase( aVal.Len() - 1 ); + if ( bAbbr ) + aVal += aDots; + } + } + + return aVal; +} + +//------------------------------------------------------------------- + +void ButtonFrame::Draw( OutputDevice& rDev ) +{ + Color aOldFillColor = rDev.GetFillColor(); + Color aOldLineColor = rDev.GetLineColor(); + + const StyleSettings &rSettings = rDev.GetSettings().GetStyleSettings(); + Color aColLight( rSettings.GetLightColor() ); + Color aColShadow( rSettings.GetShadowColor() ); + Color aColFace( rSettings.GetFaceColor() ); + + rDev.SetLineColor( bPressed ? aColShadow : aColLight ); + rDev.DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) ); + rDev.DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() - 1 ) ); + rDev.SetLineColor( bPressed ? aColLight : aColShadow ); + rDev.DrawLine( aRect.BottomRight(), Point( aRect.Right(), aRect.Top() ) ); + rDev.DrawLine( aRect.BottomRight(), Point( aRect.Left(), aRect.Bottom() ) ); + + rDev.SetLineColor( aColFace ); + rDev.SetFillColor( aColFace ); + rDev.DrawRect( aInnerRect ); + + if ( aText.Len() ) + { + String aVal( FitInWidth( rDev, aText, aInnerRect.GetWidth() - 2*MIN_COLUMNWIDTH, bAbbr ) ); + Font aFont( rDev.GetFont() ); + BOOL bOldTransp = aFont.IsTransparent(); + if ( !bOldTransp ) + { + aFont.SetTransparent( TRUE ); + rDev.SetFont( aFont ); + } + + rDev.DrawText( Point( + ( aInnerRect.Left() + aInnerRect.Right() ) / 2 - ( rDev.GetTextWidth(aVal) / 2 ), + aInnerRect.Top() ), aVal ); + + if ( !bOldTransp ) + { + aFont.SetTransparent(FALSE); + rDev.SetFont( aFont ); + } + } + + if ( bCurs ) + { + rDev.SetLineColor( Color( COL_BLACK ) ); + rDev.SetFillColor(); + rDev.DrawRect( Rectangle( + Point( aRect.Left(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) ) ); + } + + rDev.SetLineColor( aOldLineColor ); + rDev.SetFillColor( aOldFillColor ); +} + +//------------------------------------------------------------------- + +BrowserColumn::BrowserColumn( USHORT nItemId, const class Image &rImage, + const String& rTitle, ULONG nWidthPixel, const Fraction& rCurrentZoom, + HeaderBarItemBits nFlags ) +: _nId( nItemId ), + _nWidth( nWidthPixel ), + _aImage( rImage ), + _aTitle( rTitle ), + _bFrozen( FALSE ), + _nFlags( nFlags ) +{ + double n = (double)_nWidth; + n *= (double)rCurrentZoom.GetDenominator(); + n /= (double)rCurrentZoom.GetNumerator(); + _nOriginalWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5); +} + +//------------------------------------------------------------------- + +void BrowserColumn::SetWidth(ULONG nNewWidthPixel, const Fraction& rCurrentZoom) +{ + _nWidth = nNewWidthPixel; + double n = (double)_nWidth; + n *= (double)rCurrentZoom.GetDenominator(); + n /= (double)rCurrentZoom.GetNumerator(); + _nOriginalWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5); +} + +//------------------------------------------------------------------- + +void BrowserColumn::Draw( BrowseBox& rBox, OutputDevice& rDev, const Point& rPos, BOOL bCurs ) +{ + if ( _nId == 0 ) + { + // paint handle column + ButtonFrame( rPos, Size( Width()-1, rBox.GetDataRowHeight()-1 ), + String(), FALSE, bCurs, + 0 != (BROWSER_COLUMN_TITLEABBREVATION&_nFlags) ).Draw( rDev ); + Color aOldLineColor = rDev.GetLineColor(); + rDev.SetLineColor( Color( COL_BLACK ) ); + rDev.DrawLine( + Point( rPos.X(), rPos.Y()+rBox.GetDataRowHeight()-1 ), + Point( rPos.X() + Width() - 1, rPos.Y()+rBox.GetDataRowHeight()-1 ) ); + rDev.DrawLine( + Point( rPos.X() + Width() - 1, rPos.Y() ), + Point( rPos.X() + Width() - 1, rPos.Y()+rBox.GetDataRowHeight()-1 ) ); + rDev.SetLineColor( aOldLineColor ); + + if ( rBox.bHasBitmapHandle ) + rBox.PaintField( rDev, + Rectangle( + Point( rPos.X() + 2, rPos.Y() + 2 ), + Size( Width()-1, rBox.GetDataRowHeight()-1 ) ), + GetId() ); + } + else + { + // paint data column + long nWidth = Width() == LONG_MAX ? rBox.GetDataWindow().GetSizePixel().Width() : Width(); + + rBox.PaintField( rDev, + Rectangle( + Point( rPos.X() + MIN_COLUMNWIDTH, rPos.Y() ), + Size( nWidth-2*MIN_COLUMNWIDTH, rBox.GetDataRowHeight()-1 ) ), + GetId() ); + } +} + +//------------------------------------------------------------------- + +void BrowserColumn::ZoomChanged(const Fraction& rNewZoom) +{ + double n = (double)_nOriginalWidth; + n *= (double)rNewZoom.GetNumerator(); + n /= (double)rNewZoom.GetDenominator(); + + _nWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5); +} + +//------------------------------------------------------------------- + +BrowserDataWin::BrowserDataWin( BrowseBox* pParent ) : + Control( pParent, WinBits(WB_CLIPCHILDREN) ), + pHeaderBar( 0 ), + pEventWin( pParent ), + pCornerWin( 0 ), + bInPaint( FALSE ), + bInCommand( FALSE ), + bNoScrollBack( FALSE ), + bUpdateMode( TRUE ), + bResizeOnPaint( FALSE ), + bUpdateOnUnlock( FALSE ), + bInUpdateScrollbars( FALSE ), + bHadRecursion( FALSE ), + bOwnDataChangedHdl( FALSE ), + nUpdateLock( 0 ), + nCursorHidden( 0 ), + pDtorNotify( 0 ) +{ + aMouseTimer.SetTimeoutHdl( LINK( this, BrowserDataWin, RepeatedMouseMove ) ); + aMouseTimer.SetTimeout( 100 ); +} + +//------------------------------------------------------------------- +BrowserDataWin::~BrowserDataWin() +{ + if( pDtorNotify ) + *pDtorNotify = TRUE; + if ( IsMouseCaptured() ) + ReleaseMouse(); +} + +//------------------------------------------------------------------- +void BrowserDataWin::LeaveUpdateLock() +{ + if ( !--nUpdateLock ) + { + DoOutstandingInvalidations(); + if (bUpdateOnUnlock ) + { + Control::Update(); + bUpdateOnUnlock = FALSE; + } + } +} + +//------------------------------------------------------------------- +void InitSettings_Impl( Window *pWin, + BOOL bFont, BOOL bForeground, BOOL bBackground ) +{ + const StyleSettings& rStyleSettings = + pWin->GetSettings().GetStyleSettings(); + + if ( bFont ) + { + Font aFont = rStyleSettings.GetAppFont(); + if ( pWin->IsControlFont() ) + aFont.Merge( pWin->GetControlFont() ); + pWin->SetPointFont( aFont ); + } + + if ( bFont || bForeground ) + { + Color aTextColor = rStyleSettings.GetWindowTextColor(); + if ( pWin->IsControlForeground() ) + aTextColor = pWin->GetControlForeground(); + pWin->SetTextColor( aTextColor ); + } + + if ( bBackground ) + { + if( pWin->IsControlBackground() ) + pWin->SetBackground( pWin->GetControlBackground() ); + else + pWin->SetBackground( rStyleSettings.GetWindowColor() ); + } +} + +//------------------------------------------------------------------- +void BrowserDataWin::Update() +{ + if ( !nUpdateLock ) + Control::Update(); + else + bUpdateOnUnlock = TRUE; +} + +//------------------------------------------------------------------- +void BrowserDataWin::DataChanged( const DataChangedEvent& rDCEvt ) +{ + if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && + (rDCEvt.GetFlags() & SETTINGS_STYLE) ) + { + if( !bOwnDataChangedHdl ) + { + InitSettings_Impl( this, TRUE, TRUE, TRUE ); + Invalidate(); + InitSettings_Impl( GetParent(), TRUE, TRUE, TRUE ); + GetParent()->Invalidate(); + } + } + else + Control::DataChanged( rDCEvt ); +} + +//------------------------------------------------------------------- +void BrowserDataWin::Paint( const Rectangle& rRect ) +{ + if ( !nUpdateLock && GetUpdateMode() ) + { + bInPaint = TRUE; + ( (BrowseBox*) GetParent() )->PaintData( *this, rRect ); + bInPaint = FALSE; + } + else + aInvalidRegion.Insert( new Rectangle( rRect ) ); +} + +//------------------------------------------------------------------- + +BrowseEvent BrowserDataWin::CreateBrowseEvent( const Point& rPosPixel ) +{ + BrowseBox *pBox = GetParent(); + + // seek to row under mouse + short nRelRow = rPosPixel.Y() < 0 + ? -1 + : rPosPixel.Y() / pBox->GetDataRowHeight(); + long nRow = nRelRow < 0 ? -1 : nRelRow + pBox->nTopRow; + + // find column under mouse + long nMouseX = rPosPixel.X(); + long nColX = 0; + USHORT nCol; + for ( nCol = 0; + nCol < pBox->pCols->Count() && nColX < GetSizePixel().Width(); + ++nCol ) + if ( pBox->pCols->GetObject(nCol)->IsFrozen() || nCol >= pBox->nFirstCol ) + { + nColX += pBox->pCols->GetObject(nCol)->Width(); + if ( nMouseX < nColX ) + break; + } + USHORT nColId = BROWSER_INVALIDID; + if ( nCol < pBox->pCols->Count() ) + nColId = pBox->pCols->GetObject(nCol)->GetId(); + + // compute the field rectangle and field relative MouseEvent + Rectangle aFieldRect; + MouseEvent aRelEvt; + if ( nCol < pBox->pCols->Count() ) + { + nColX -= pBox->pCols->GetObject(nCol)->Width(); + aFieldRect = Rectangle( + Point( nColX, nRelRow * pBox->GetDataRowHeight() ), + Size( pBox->pCols->GetObject(nCol)->Width(), + pBox->GetDataRowHeight() ) ); + } + + // assemble and return the BrowseEvent + return BrowseEvent( this, nRow, nCol, nColId, aFieldRect ); +} + +//------------------------------------------------------------------- +void BrowserDataWin::Command( const CommandEvent& rEvt ) +{ + // Scrollmaus-Event? + BrowseBox *pBox = GetParent(); + if ( ( (rEvt.GetCommand() == COMMAND_WHEEL) || + (rEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) || + (rEvt.GetCommand() == COMMAND_AUTOSCROLL) ) && + ( HandleScrollCommand( rEvt, &pBox->aHScroll, pBox->pVScroll ) ) ) + return; + + Point aEventPos( rEvt.GetMousePosPixel() ); + long nRow = pBox->GetRowAtYPosPixel( aEventPos.Y(), FALSE); + MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT ); + if ( COMMAND_CONTEXTMENU == rEvt.GetCommand() && rEvt.IsMouseEvent() && + nRow < pBox->GetRowCount() && !pBox->IsRowSelected(nRow) ) + { + BOOL bDeleted = FALSE; + pDtorNotify = &bDeleted; + bInCommand = TRUE; + MouseButtonDown( aMouseEvt ); + if( bDeleted ) + return; + MouseButtonUp( aMouseEvt ); + if( bDeleted ) + return; + pDtorNotify = 0; + bInCommand = FALSE; + } + + aEventPos.Y() += GetParent()->GetTitleHeight(); + CommandEvent aEvt( aEventPos, rEvt.GetCommand(), + rEvt.IsMouseEvent(), rEvt.GetData() ); + bInCommand = TRUE; + BOOL bDeleted = FALSE; + pDtorNotify = &bDeleted; + GetParent()->Command( aEvt ); + if( bDeleted ) + return; + pDtorNotify = 0; + bInCommand = FALSE; + + if ( COMMAND_STARTDRAG == rEvt.GetCommand() ) + MouseButtonUp( aMouseEvt ); + + Control::Command( rEvt ); +} + +//------------------------------------------------------------------- + +void BrowserDataWin::MouseButtonDown( const MouseEvent& rEvt ) +{ + aLastMousePos = OutputToScreenPixel( rEvt.GetPosPixel() ); + CaptureMouse(); + GetParent()->MouseButtonDown( BrowserMouseEvent( this, rEvt ) ); +} + +//------------------------------------------------------------------- + +void BrowserDataWin::MouseMove( const MouseEvent& rEvt ) +{ + // Pseudo MouseMoves verhindern + Point aNewPos = OutputToScreenPixel( rEvt.GetPosPixel() ); + if ( aNewPos == aLastMousePos ) + return; + aLastMousePos = aNewPos; + + // Paint-Probleme abfangen + if ( !IsMouseCaptured() ) + return; + + // transform to a BrowseEvent + GetParent()->MouseMove( BrowserMouseEvent( this, rEvt ) ); + + // dragging out of the visible area? + if ( rEvt.IsLeft() && + ( rEvt.GetPosPixel().Y() > GetSizePixel().Height() || + rEvt.GetPosPixel().Y() < 0 ) ) + { + // repeat the event + aRepeatEvt = rEvt; + aMouseTimer.Start(); + } + else + // killing old repeat-event + if ( aMouseTimer.IsActive() ) + aMouseTimer.Stop(); +} + +//------------------------------------------------------------------- + +IMPL_LINK_INLINE_START( BrowserDataWin, RepeatedMouseMove, void *, pvoid ) +{ + GetParent()->MouseMove( BrowserMouseEvent( this, aRepeatEvt ) ); + return 0; +} +IMPL_LINK_INLINE_END( BrowserDataWin, RepeatedMouseMove, void *, pvoid ) + +//------------------------------------------------------------------- + +void BrowserDataWin::MouseButtonUp( const MouseEvent& rEvt ) +{ + // Pseudo MouseMoves verhindern + Point aNewPos = OutputToScreenPixel( rEvt.GetPosPixel() ); + aLastMousePos = aNewPos; + + // Paint-Probleme abfangen + if ( !IsMouseCaptured() ) + return; + + // Move an die aktuelle Position simulieren + MouseMove( rEvt ); + + // eigentliches Up-Handling + ReleaseMouse(); + if ( aMouseTimer.IsActive() ) + aMouseTimer.Stop(); + GetParent()->MouseButtonUp( BrowserMouseEvent( this, rEvt ) ); +} + +//------------------------------------------------------------------- + +void BrowserDataWin::KeyInput( const KeyEvent& rEvt ) +{ + // pass to parent window + if ( !GetParent()->ProcessKey( rEvt ) ) + Control::KeyInput( rEvt ); +} + +//------------------------------------------------------------------- + +void BrowserDataWin::RequestHelp( const HelpEvent& rHEvt ) +{ + pEventWin = this; + GetParent()->RequestHelp( rHEvt ); + pEventWin = GetParent(); +} + +//------------------------------------------------------------------- + +BOOL BrowserDataWin::Drop( const DropEvent& rEvt ) +{ + return GetParent()->Drop( BrowserDropEvent( this, rEvt ) ); +} + +//------------------------------------------------------------------- + +BOOL BrowserDataWin::QueryDrop( DropEvent& rEvt ) +{ + BrowserDropEvent aBrwDEvt( this, rEvt ); + BOOL bRet = GetParent()->QueryDrop( aBrwDEvt ); + rEvt = aBrwDEvt; + return bRet; +} + +//=================================================================== + +BrowseEvent::BrowseEvent( Window* pWindow, + long nAbsRow, USHORT nColumn, USHORT nColumnId, + const Rectangle& rRect ): + pWin(pWindow), + nRow(nAbsRow), + nCol(nColumn), + nColId(nColumnId), + aRect(rRect) +{ +} + +//=================================================================== + +BrowserMouseEvent::BrowserMouseEvent( BrowserDataWin *pWin, + const MouseEvent& rEvt ): + MouseEvent(rEvt), + BrowseEvent( pWin->CreateBrowseEvent( rEvt.GetPosPixel() ) ) +{ +} + +//------------------------------------------------------------------- + +BrowserMouseEvent::BrowserMouseEvent( Window *pWin, const MouseEvent& rEvt, + long nAbsRow, USHORT nColumn, USHORT nColumnId, + const Rectangle& rRect ): + MouseEvent(rEvt), + BrowseEvent( pWin, nAbsRow, nColumn, nColumnId, rRect ) +{ +} + +//=================================================================== + +BrowserDropEvent::BrowserDropEvent( BrowserDataWin *pWin, const DropEvent& rEvt ): + DropEvent(rEvt), + BrowseEvent( pWin->CreateBrowseEvent( rEvt.GetPosPixel() ) ) +{ +} + +//------------------------------------------------------------------- + +void BrowserDataWin::SetUpdateMode( BOOL bMode ) +{ + DBG_ASSERT( !bUpdateMode || aInvalidRegion.Count() == 0, + "invalid region not empty" ); + if ( bMode == bUpdateMode ) + return; + + bUpdateMode = bMode; + if ( bMode ) + DoOutstandingInvalidations(); +} + +//------------------------------------------------------------------- +void BrowserDataWin::DoOutstandingInvalidations() +{ + for ( Rectangle* pRect = aInvalidRegion.First(); + pRect; + pRect = aInvalidRegion.Next() ) + { + Window::Invalidate( *pRect, INVALIDATE_NOCHILDREN /*OV*/); + delete pRect; + } + aInvalidRegion.Clear(); +} + +//------------------------------------------------------------------- + +void BrowserDataWin::Invalidate() +{ + if ( !GetUpdateMode() ) + { + for ( Rectangle* pRect = aInvalidRegion.First(); + pRect; + pRect = aInvalidRegion.Next() ) + delete pRect; + aInvalidRegion.Clear(); + aInvalidRegion.Insert( + new Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) ); + } + else + Window::Invalidate(INVALIDATE_NOCHILDREN /*OV*/ ); +} + +//------------------------------------------------------------------- + +void BrowserDataWin::Invalidate( const Rectangle& rRect ) +{ + if ( !GetUpdateMode() ) + aInvalidRegion.Insert( new Rectangle( rRect ) ); + else + Window::Invalidate( rRect, INVALIDATE_NOCHILDREN /*OV*/ ); +} + +//=================================================================== + +void BrowserScrollBar::Tracking( const TrackingEvent& rTEvt ) +{ + ULONG nPos = GetThumbPos(); + if ( nPos != _nLastPos ) + { + if ( _nTip ) + Help::HideTip( _nTip ); + + String aTip( String::CreateFromInt32(nPos) ); + aTip += '/'; + if ( _pDataWin->GetRealRowCount().Len() ) + aTip += _pDataWin->GetRealRowCount(); + else + aTip += String::CreateFromInt32(GetRangeMax()); + Rectangle aRect( GetPointerPosPixel(), Size( GetTextHeight(), GetTextWidth( aTip ) ) ); + _nTip = Help::ShowTip( this, aRect, aTip ); + _nLastPos = nPos; + } + + ScrollBar::Tracking( rTEvt ); +} + +//------------------------------------------------------------------- + +void BrowserScrollBar::EndScroll() +{ + if ( _nTip ) + Help::HideTip( _nTip ); + _nTip = 0; + ScrollBar::EndScroll(); +} + + diff --git a/svtools/source/brwbox/datwin.hxx b/svtools/source/brwbox/datwin.hxx new file mode 100644 index 000000000000..3fcd002e392d --- /dev/null +++ b/svtools/source/brwbox/datwin.hxx @@ -0,0 +1,269 @@ +/************************************************************************* + * + * $RCSfile: datwin.hxx,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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SFXDATWIN_HXX +#define _SFXDATWIN_HXX + +#ifndef _BRWBOX_HXX +#include <brwbox.hxx> +#endif + +#ifndef _BRWHEAD_HXX +#include <brwhead.hxx> +#endif + +#ifndef _TIMER_HXX //autogen +#include <vcl/timer.hxx> +#endif +#ifndef _IMAGE_HXX //autogen +#include <vcl/image.hxx> +#endif +#ifndef _LIST_HXX //autogen +#include <tools/list.hxx> +#endif +//=================================================================== + +#define MIN_COLUMNWIDTH 2 +#define DRAG_CRITICAL 4 + +DECLARE_LIST( RectangleList, Rectangle* ); + +//=================================================================== + +class ButtonFrame +{ + Rectangle aRect; + Rectangle aInnerRect; + String aText; + BOOL bPressed; + BOOL bCurs; + BOOL bAbbr; + +public: + ButtonFrame( const Point& rPt, const Size& rSz, + const String &rText, + BOOL bPress = FALSE, BOOL bCursor = FALSE, + BOOL bAbbreviate = TRUE ) : + aRect( rPt, rSz ), + aInnerRect( Point( aRect.Left()+1, aRect.Top()+1 ), + Size( aRect.GetWidth()-2, aRect.GetHeight()-2 ) ), + aText(rText), + bPressed(bPress), + bCurs(bCursor), + bAbbr(bAbbreviate) + {} + + void Draw( OutputDevice& rDev ); +}; + +//=================================================================== + +class BrowserColumn +{ + USHORT _nId; + ULONG _nOriginalWidth; + ULONG _nWidth; + Image _aImage; + String _aTitle; + BOOL _bFrozen; + HeaderBarItemBits _nFlags; + +public: + BrowserColumn( USHORT nItemId, const Image &rImage, + const String& rTitle, ULONG nWidthPixel, const Fraction& rCurrentZoom, + HeaderBarItemBits nFlags ); + + USHORT GetId() const { return _nId; } + + ULONG Width() { return _nWidth; } + Image& GetImage() { return _aImage; } + String& Title() { return _aTitle; } + HeaderBarItemBits& Flags() { return _nFlags; } + + BOOL IsFrozen() const { return _bFrozen; } + void Freeze( BOOL bFreeze = TRUE ) { _bFrozen = bFreeze; } + + virtual void Draw( BrowseBox& rBox, OutputDevice& rDev, + const Point& rPos, BOOL bCurs ); + + void SetWidth(ULONG nNewWidthPixel, const Fraction& rCurrentZoom); + void ZoomChanged(const Fraction& rNewZoom); +}; + +//=================================================================== + +class BrowserDataWin: public Control +{ +friend class BrowseBox; + BrowserHeader* pHeaderBar; // only for BROWSER_HEADERBAR_NEW + Window* pEventWin; // Window of forwarded events + ScrollBarBox* pCornerWin; // Window in the corner btw the ScrollBars + BOOL* pDtorNotify; + AutoTimer aMouseTimer; // recalls MouseMove on dragging out + MouseEvent aRepeatEvt; // a MouseEvent to repeat + Point aLastMousePos; // verhindert pseudo-MouseMoves + + String aRealRowCount; // zur Anzeige im VScrollBar + + RectangleList aInvalidRegion; // invalidated Rectangles during !UpdateMode + FASTBOOL bInPaint; // TRUE while in Paint + FASTBOOL bInCommand; // TRUE while in Command + FASTBOOL bNoScrollBack; // nur vorwaerts scrollen + FASTBOOL bNoHScroll; // kein horizontaler Scrollbar + FASTBOOL bAutoHScroll; // autohide horizontaler Scrollbar + FASTBOOL bAutoVScroll; // autohide horizontaler Scrollbar + FASTBOOL bUpdateMode; // nicht SV-UpdateMode wegen Invalidate() + FASTBOOL bAutoSizeLastCol;// last column always fills up window + FASTBOOL bHighlightAuto; // new auto-highlight by SetFont() etc. + FASTBOOL bResizeOnPaint; // outstanding resize-event + FASTBOOL bUpdateOnUnlock; // Update() while locked + FASTBOOL bInUpdateScrollbars; // Rekursionsschutz + FASTBOOL bHadRecursion; // Rekursion war aufgetreten + FASTBOOL bOwnDataChangedHdl; // dont change colors in DataChanged + USHORT nUpdateLock; // lock count, dont call Control::Update()! + short nCursorHidden; // new conuter for DoHide/ShowCursor + +public: + BrowserDataWin( BrowseBox* pParent ); + ~BrowserDataWin(); + + virtual void DataChanged( const DataChangedEvent& rDCEvt ); + virtual void Paint( const Rectangle& rRect ); + virtual void RequestHelp( const HelpEvent& rHEvt ); + virtual void Command( const CommandEvent& rEvt ); + virtual void MouseButtonDown( const MouseEvent& rEvt ); + virtual void MouseMove( const MouseEvent& rEvt ); + DECL_LINK( RepeatedMouseMove, void * ); + + virtual void MouseButtonUp( const MouseEvent& rEvt ); + virtual void KeyInput( const KeyEvent& rEvt ); + + virtual BOOL QueryDrop( DropEvent& rEvt ); + virtual BOOL Drop( const DropEvent& rEvt ); + + BrowseEvent CreateBrowseEvent( const Point& rPosPixel ); + void Repaint(); + BrowseBox* GetParent() const + { return (BrowseBox*) Window::GetParent(); } + const String& GetRealRowCount() const { return aRealRowCount; } + + void SetUpdateMode( BOOL bMode ); + FASTBOOL GetUpdateMode() const { return bUpdateMode; } + void EnterUpdateLock() { ++nUpdateLock; } + void LeaveUpdateLock(); + void Update(); + void DoOutstandingInvalidations(); + void Invalidate(); + void Invalidate( const Rectangle& rRect ); +}; + +//------------------------------------------------------------------- + +inline void BrowserDataWin::Repaint() +{ + if ( GetUpdateMode() ) + Update(); + Paint( Rectangle( Point(), GetOutputSizePixel() ) ); +} + +//=================================================================== + +class BrowserScrollBar: public ScrollBar +{ + ULONG _nTip; + ULONG _nLastPos; + BrowserDataWin* _pDataWin; + +public: + BrowserScrollBar( Window* pParent, WinBits nStyle, + BrowserDataWin *pDataWin ) + : ScrollBar( pParent, nStyle ), + _nTip( 0 ), + _nLastPos( ULONG_MAX ), + _pDataWin( pDataWin ) + {} + //ScrollBar( Window* pParent, const ResId& rResId ); + + virtual void Tracking( const TrackingEvent& rTEvt ); + virtual void EndScroll(); +}; + +//=================================================================== + +void InitSettings_Impl( Window *pWin, + BOOL bFont = TRUE, BOOL bForeground = TRUE, BOOL bBackground = TRUE ); + +//=================================================================== + +#ifdef DBG_MI + +void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho ); +#define LOG(pThis,what,who) DoLog_Impl(pThis,what,who) + +#else + +#define LOG(pThis,what,who) + +#endif + + +#endif + diff --git a/svtools/source/brwbox/makefile.mk b/svtools/source/brwbox/makefile.mk new file mode 100644 index 000000000000..2379c21e72c1 --- /dev/null +++ b/svtools/source/brwbox/makefile.mk @@ -0,0 +1,99 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,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): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=SVTOOLS +TARGET=browse + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +CXXFILES= \ + brwbox1.cxx \ + brwbox2.cxx \ + brwhead.cxx \ + datwin.cxx + +.IF "$(GUI)" == "WIN" +CXXFILES+= \ + brwdll.cxx +.ENDIF + +SLOFILES= \ + $(SLO)$/brwbox1.obj \ + $(SLO)$/brwbox2.obj \ + $(SLO)$/brwhead.obj \ + $(SLO)$/datwin.obj + +.IF "$(GUI)" == "WIN" +SLOFILES+= \ + $(SLO)$/brwdll.obj +.ENDIF +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk |