summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRüdiger Timm <rt@openoffice.org>2008-12-15 12:14:02 +0000
committerRüdiger Timm <rt@openoffice.org>2008-12-15 12:14:02 +0000
commit6e26501b0c0ad3cbd98c0af9aab2f9afc8461886 (patch)
tree687e8545bf2975c2d83c6d7d20f982d141b0b275
parent587abd3cd7f1f25745347bc71717787d32fc620e (diff)
CWS-TOOLING: integrate CWS ooo301gsl3_DEV300
-rw-r--r--vcl/inc/vcl/ilstbox.hxx54
-rw-r--r--vcl/inc/vcl/lstbox.h9
-rw-r--r--vcl/source/control/combobox.cxx2
-rw-r--r--vcl/source/control/ilstbox.cxx363
-rw-r--r--vcl/source/control/lstbox.cxx2
-rw-r--r--vcl/source/gdi/outdev3.cxx24
6 files changed, 327 insertions, 127 deletions
diff --git a/vcl/inc/vcl/ilstbox.hxx b/vcl/inc/vcl/ilstbox.hxx
index be36d3a7dcc7..e5f6696005fa 100644
--- a/vcl/inc/vcl/ilstbox.hxx
+++ b/vcl/inc/vcl/ilstbox.hxx
@@ -70,11 +70,13 @@ struct ImplEntryType
void* mpUserData;
BOOL mbIsSelected;
long mnFlags;
+ long mnHeight;
ImplEntryType( const XubString& rStr, const Image& rImage ) :
maStr( rStr ),
maImage( rImage ),
- mnFlags(0)
+ mnFlags( 0 ),
+ mnHeight( 0 )
{
mbIsSelected = FALSE;
mpUserData = NULL;
@@ -82,7 +84,8 @@ struct ImplEntryType
ImplEntryType( const XubString& rStr ) :
maStr( rStr ),
- mnFlags(0)
+ mnFlags( 0 ),
+ mnHeight( 0 )
{
mbIsSelected = FALSE;
mpUserData = NULL;
@@ -90,7 +93,8 @@ struct ImplEntryType
ImplEntryType( const Image& rImage ) :
maImage( rImage ),
- mnFlags( 0 )
+ mnFlags( 0 ),
+ mnHeight( 0 )
{
mbIsSelected = FALSE;
mpUserData = NULL;
@@ -124,12 +128,20 @@ public:
USHORT InsertEntry( USHORT nPos, ImplEntryType* pNewEntry, BOOL bSort );
void RemoveEntry( USHORT nPos );
const ImplEntryType* GetEntryPtr( USHORT nPos ) const { return (const ImplEntryType*) GetObject( nPos ); }
+ ImplEntryType* GetMutableEntryPtr( USHORT nPos ) const { return (ImplEntryType*) GetObject( nPos ); }
void Clear();
USHORT FindMatchingEntry( const XubString& rStr, USHORT nStart = 0, BOOL bForward = TRUE, BOOL bLazy = TRUE ) const;
USHORT FindEntry( const XubString& rStr, BOOL bSearchMRUArea = FALSE ) const;
USHORT FindEntry( const void* pData ) const;
+ // helper: add up heights up to index nEndIndex.
+ // GetAddedHeight( 0 ) returns 0
+ // GetAddedHeight( LISTBOX_ENTRY_NOTFOUND ) returns 0
+ // GetAddedHeight( i, k ) with k > i is equivalent -GetAddedHeight( k, i )
+ long GetAddedHeight( USHORT nEndIndex, USHORT nBeginIndex = 0, long nBeginHeight = 0 ) const;
+ long GetEntryHeight( USHORT nPos ) const;
+
USHORT GetEntryCount() const { return (USHORT)List::Count(); }
BOOL HasImages() const { return mnImages ? TRUE : FALSE; }
@@ -194,17 +206,16 @@ private:
Size maUserItemSize;
- USHORT mnMaxTxtHeight; // Maximale Hoehe eines Text-Items
- USHORT mnMaxTxtWidth; // Maximale Breite eines Text-Items
+ long mnMaxTxtHeight; // Maximale Hoehe eines Text-Items
+ long mnMaxTxtWidth; // Maximale Breite eines Text-Items
// Entry ohne Image
- USHORT mnMaxImgTxtWidth;// Maximale Breite eines Text-Items
+ long mnMaxImgTxtWidth;// Maximale Breite eines Text-Items
// Entry UND Image
- USHORT mnMaxImgWidth; // Maximale Breite eines Image-Items
- USHORT mnMaxImgHeight; // Maximale Hoehe eines Image-Items
- USHORT mnMaxWidth; // Maximale Breite eines Eintrags
- USHORT mnMaxHeight; // Maximale Hoehe eines Eintrags
+ long mnMaxImgWidth; // Maximale Breite eines Image-Items
+ long mnMaxImgHeight; // Maximale Hoehe eines Image-Items
+ long mnMaxWidth; // Maximale Breite eines Eintrags
+ long mnMaxHeight; // Maximale Hoehe eines Eintrags
- USHORT mnMaxVisibleEntries; // Anzahl der sichtbaren Eintraege
USHORT mnCurrentPos; // Position (Focus)
USHORT mnTrackingSaveSelection; // Selektion vor Tracking();
@@ -213,9 +224,9 @@ private:
USHORT mnUserDrawEntry;
USHORT mnTop; // Ausgabe ab Zeile
- USHORT mnLeft; // Ausgabe ab Spalte
- USHORT mnBorder; // Abstand Rahmen - Text
- USHORT mnTextHeight; // Texthoehe
+ long mnLeft; // Ausgabe ab Spalte
+ long mnBorder; // Abstand Rahmen - Text
+ long mnTextHeight; // Texthoehe
USHORT mnSelectModifier; // Modifiers
@@ -261,7 +272,7 @@ protected:
void ImplPaint( USHORT nPos, BOOL bErase = FALSE, bool bLayout = false );
void ImplDoPaint( const Rectangle& rRect, bool bLayout = false );
void ImplCalcMetrics();
- void ImplCalcEntryMetrics( const ImplEntryType& rEntry, BOOL bUpdateMetrics );
+ void ImplUpdateEntryMetrics( ImplEntryType& rEntry );
void ImplCallSelect();
void ImplShowFocusRect();
@@ -285,23 +296,25 @@ public:
void ResetCurrentPos() { mnCurrentPos = LISTBOX_ENTRY_NOTFOUND; }
USHORT GetCurrentPos() const { return mnCurrentPos; }
USHORT GetDisplayLineCount() const;
+ void SetEntryFlags( USHORT nPos, long nFlags );
void DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImagePos = FALSE, bool bLayout = false );
void SelectEntry( USHORT nPos, BOOL bSelect );
void DeselectAll();
USHORT GetEntryPosForPoint( const Point& rPoint ) const;
+ USHORT GetLastVisibleEntry() const;
BOOL ProcessKeyInput( const KeyEvent& rKEvt );
void SetTopEntry( USHORT nTop );
USHORT GetTopEntry() const { return mnTop; }
using Window::IsVisible;
- BOOL IsVisible( USHORT nEntry ) const { return ( ( nEntry >= mnTop ) && ( nEntry < (mnTop+mnMaxVisibleEntries) ) ); }
+ BOOL IsVisible( USHORT nEntry ) const;
- USHORT GetLeftIndent() const { return mnLeft; }
- void SetLeftIndent( USHORT n );
- void ScrollHorz( short nDiff );
+ long GetLeftIndent() const { return mnLeft; }
+ void SetLeftIndent( long n );
+ void ScrollHorz( long nDiff );
void AllowGrabFocus( BOOL b ) { mbGrabFocus = b; }
BOOL IsGrabFocusAllowed() const { return mbGrabFocus; }
@@ -330,7 +343,6 @@ public:
BOOL IsMouseMoveSelect() const { return mbMouseMoveSelect||mbStackMode; }
Size CalcSize( USHORT nMaxLines ) const;
- void CalcMaxVisibleEntries( const Size& rFloatSize);
Rectangle GetBoundingRectangle( USHORT nItem ) const;
long GetEntryHeight() const { return mnMaxHeight; }
@@ -433,7 +445,7 @@ public:
using Window::IsVisible;
BOOL IsVisible( USHORT nEntry ) const { return maLBWindow.IsVisible( nEntry ); }
- USHORT GetLeftIndent() const { return maLBWindow.GetLeftIndent(); }
+ long GetLeftIndent() const { return maLBWindow.GetLeftIndent(); }
void SetLeftIndent( USHORT n ) { maLBWindow.SetLeftIndent( n ); }
void ScrollHorz( short nDiff ) { maLBWindow.ScrollHorz( nDiff ); }
diff --git a/vcl/inc/vcl/lstbox.h b/vcl/inc/vcl/lstbox.h
index 1c58f7f7700b..6097422b556b 100644
--- a/vcl/inc/vcl/lstbox.h
+++ b/vcl/inc/vcl/lstbox.h
@@ -49,8 +49,15 @@
/** this flag disables a selection of an entry completly. It is not
possible to select such entries either from the user interface
nor from the ListBox methods. Cursor traveling is handled correctly.
- This flag can be used to at titles to a ListBox.
+ This flag can be used to add titles to a ListBox.
*/
#define LISTBOX_ENTRY_FLAG_DISABLE_SELECTION 0x0000001
+/** this flag can be used to make an entry multine capable
+ A normal entry is single line and will therefore be clipped
+ at the right listbox border. Setting this flag enables
+ word breaks for the entry text.
+*/
+#define LISTBOX_ENTRY_FLAG_MULTILINE 0x0000002
+
#endif // _SV_LSTBOX_H
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index 0d9523fa357b..3038f60267ee 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -840,8 +840,6 @@ long ComboBox::Notify( NotifyEvent& rNEvt )
}
else
{
- if( mpFloatWin )
- mpImplLB->GetMainWindow()->CalcMaxVisibleEntries( mpFloatWin->CalcFloatSize() );
nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
}
}
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
index 50816de2aaf7..df77e088a7a4 100644
--- a/vcl/source/control/ilstbox.cxx
+++ b/vcl/source/control/ilstbox.cxx
@@ -54,6 +54,8 @@
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#endif
+#define MULTILINE_ENTRY_DRAW_FLAGS ( TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE | TEXT_DRAW_VCENTER )
+
using namespace ::com::sun::star;
// =======================================================================
@@ -328,6 +330,42 @@ USHORT ImplEntryList::FindEntry( const void* pData ) const
// -----------------------------------------------------------------------
+long ImplEntryList::GetAddedHeight( USHORT i_nEndIndex, USHORT i_nBeginIndex, long i_nBeginHeight ) const
+{
+ long nHeight = i_nBeginHeight;
+ USHORT nStart = i_nEndIndex > i_nBeginIndex ? i_nBeginIndex : i_nEndIndex;
+ USHORT nStop = i_nEndIndex > i_nBeginIndex ? i_nEndIndex : i_nBeginIndex;
+ USHORT nEntryCount = GetEntryCount();
+ if( nStop != LISTBOX_ENTRY_NOTFOUND && nEntryCount != 0 )
+ {
+ // sanity check
+ if( nStop > nEntryCount-1 )
+ nStop = nEntryCount-1;
+ if( nStart > nEntryCount-1 )
+ nStart = nEntryCount-1;
+
+ USHORT nIndex = nStart;
+ while( nIndex != LISTBOX_ENTRY_NOTFOUND && nIndex < nStop )
+ {
+ nHeight += GetEntryPtr( nIndex )-> mnHeight;
+ nIndex++;
+ }
+ }
+ else
+ nHeight = 0;
+ return i_nEndIndex > i_nBeginIndex ? nHeight : -nHeight;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplEntryList::GetEntryHeight( USHORT nPos ) const
+{
+ ImplEntryType* pImplEntry = GetEntry( nPos );
+ return pImplEntry ? pImplEntry->mnHeight : 0;
+}
+
+// -----------------------------------------------------------------------
+
XubString ImplEntryList::GetEntryText( USHORT nPos ) const
{
XubString aEntryText;
@@ -574,12 +612,15 @@ void ImplListBoxWindow::ImplCalcMetrics()
for ( USHORT n = mpEntryList->GetEntryCount(); n; )
{
- const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( --n );
- ImplCalcEntryMetrics( *pEntry, TRUE );
+ ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( --n );
+ ImplUpdateEntryMetrics( *pEntry );
}
- Size aSz( GetOutputSizePixel().Width(), mnMaxHeight );
- maFocusRect.SetSize( aSz );
+ if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
+ {
+ Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryPtr( mnCurrentPos )->mnHeight );
+ maFocusRect.SetSize( aSz );
+ }
}
// -----------------------------------------------------------------------
@@ -625,24 +666,17 @@ struct ImplEntryMetrics
{
BOOL bText;
BOOL bImage;
- USHORT nEntryWidth;
- USHORT nEntryHeight;
- USHORT nTextWidth;
- USHORT nImgWidth;
- USHORT nImgHeight;
+ long nEntryWidth;
+ long nEntryHeight;
+ long nTextWidth;
+ long nImgWidth;
+ long nImgHeight;
};
// -----------------------------------------------------------------------
-void ImplListBoxWindow::ImplCalcEntryMetrics( const ImplEntryType& rEntry, BOOL bUpdateMetrics )
+void ImplListBoxWindow::ImplUpdateEntryMetrics( ImplEntryType& rEntry )
{
- // bUpdateMetrics: Wenn Entry groesser als Max-Wert, dann uebernehmen
-
- // Diese Methode war mal auch fuer RemoveRentry gedacht, deshalb die
- // ImplEntryMetrics-Struktur, damit die Werte zurueckgegeben werden.
- // Jetzt werden die aktuellen Metriken aber doch immer angepasst, weil
- // bei RemoveEntry einmal komplett durchgegangen wird.
-
ImplEntryMetrics aMetrics;
aMetrics.bText = rEntry.maStr.Len() ? TRUE : FALSE;
aMetrics.bImage = !!rEntry.maImage;
@@ -654,10 +688,30 @@ void ImplListBoxWindow::ImplCalcEntryMetrics( const ImplEntryType& rEntry, BOOL
if ( aMetrics.bText )
{
- aMetrics.nTextWidth = (USHORT)GetTextWidth( rEntry.maStr );
- if( bUpdateMetrics && ( aMetrics.nTextWidth > mnMaxTxtWidth ) )
- mnMaxTxtWidth = aMetrics.nTextWidth;
- aMetrics.nEntryWidth = mnMaxTxtWidth;
+ if( (rEntry.mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
+ {
+ // multiline case
+ Size aCurSize( PixelToLogic( GetSizePixel() ) );
+ // set the current size to a large number
+ // GetTextRect should shrink it to the actual size
+ aCurSize.Height() = 0x7fffff;
+ Rectangle aTextRect( Point( 0, 0 ), aCurSize );
+ aTextRect = GetTextRect( aTextRect, rEntry.maStr, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE );
+ aMetrics.nTextWidth = aTextRect.GetWidth();
+ if( aMetrics.nTextWidth > mnMaxTxtWidth )
+ mnMaxTxtWidth = aMetrics.nTextWidth;
+ aMetrics.nEntryWidth = mnMaxTxtWidth;
+ aMetrics.nEntryHeight = aTextRect.GetHeight() + mnBorder;
+ }
+ else
+ {
+ // normal single line case
+ aMetrics.nTextWidth = (USHORT)GetTextWidth( rEntry.maStr );
+ if( aMetrics.nTextWidth > mnMaxTxtWidth )
+ mnMaxTxtWidth = aMetrics.nTextWidth;
+ aMetrics.nEntryWidth = mnMaxTxtWidth;
+ aMetrics.nEntryHeight = mnTextHeight + mnBorder;
+ }
}
if ( aMetrics.bImage )
{
@@ -665,36 +719,35 @@ void ImplListBoxWindow::ImplCalcEntryMetrics( const ImplEntryType& rEntry, BOOL
aMetrics.nImgWidth = (USHORT) CalcZoom( aImgSz.Width() );
aMetrics.nImgHeight = (USHORT) CalcZoom( aImgSz.Height() );
- if ( bUpdateMetrics )
- {
- if( mnMaxImgWidth && ( aMetrics.nImgWidth != mnMaxImgWidth ) )
- mbImgsDiffSz = TRUE;
- else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) )
- mbImgsDiffSz = TRUE;
+ if( mnMaxImgWidth && ( aMetrics.nImgWidth != mnMaxImgWidth ) )
+ mbImgsDiffSz = TRUE;
+ else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) )
+ mbImgsDiffSz = TRUE;
- if( aMetrics.nImgWidth > mnMaxImgWidth )
- mnMaxImgWidth = aMetrics.nImgWidth;
- if( aMetrics.nImgHeight > mnMaxImgHeight )
- mnMaxImgHeight = aMetrics.nImgHeight;
+ if( aMetrics.nImgWidth > mnMaxImgWidth )
+ mnMaxImgWidth = aMetrics.nImgWidth;
+ if( aMetrics.nImgHeight > mnMaxImgHeight )
+ mnMaxImgHeight = aMetrics.nImgHeight;
+
+ mnMaxImgTxtWidth = Max( mnMaxImgTxtWidth, aMetrics.nTextWidth );
+ aMetrics.nEntryHeight = Max( aMetrics.nImgHeight, aMetrics.nEntryHeight );
- mnMaxImgTxtWidth = Max( mnMaxImgTxtWidth, aMetrics.nTextWidth );
- }
}
if ( IsUserDrawEnabled() || aMetrics.bImage )
{
- aMetrics.nEntryWidth = Max( aMetrics.nImgWidth, (USHORT)maUserItemSize.Width() );
+ aMetrics.nEntryWidth = Max( aMetrics.nImgWidth, maUserItemSize.Width() );
if ( aMetrics.bText )
aMetrics.nEntryWidth += aMetrics.nTextWidth + IMG_TXT_DISTANCE;
- aMetrics.nEntryHeight = Max( mnMaxImgHeight, (USHORT)maUserItemSize.Height() ) + 2;
+ aMetrics.nEntryHeight = Max( Max( mnMaxImgHeight, maUserItemSize.Height() ) + 2,
+ aMetrics.nEntryHeight );
}
- if ( bUpdateMetrics )
- {
- if ( aMetrics.nEntryWidth > mnMaxWidth )
- mnMaxWidth = aMetrics.nEntryWidth;
- if ( aMetrics.nEntryHeight > mnMaxHeight )
- mnMaxHeight = aMetrics.nEntryHeight;
- }
+ if ( aMetrics.nEntryWidth > mnMaxWidth )
+ mnMaxWidth = aMetrics.nEntryWidth;
+ if ( aMetrics.nEntryHeight > mnMaxHeight )
+ mnMaxHeight = aMetrics.nEntryHeight;
+
+ rEntry.mnHeight = aMetrics.nEntryHeight;
}
// -----------------------------------------------------------------------
@@ -746,7 +799,10 @@ USHORT ImplListBoxWindow::InsertEntry( USHORT nPos, ImplEntryType* pNewEntry )
delete mpLayoutData, mpLayoutData = NULL;
USHORT nNewPos = mpEntryList->InsertEntry( nPos, pNewEntry, mbSort );
- ImplCalcEntryMetrics( *pNewEntry, TRUE );
+ if( (GetStyle() & WB_WORDBREAK) )
+ pNewEntry->mnFlags |= LISTBOX_ENTRY_FLAG_MULTILINE;
+
+ ImplUpdateEntryMetrics( *pNewEntry );
return nNewPos;
}
@@ -756,11 +812,23 @@ void ImplListBoxWindow::RemoveEntry( USHORT nPos )
{
delete mpLayoutData, mpLayoutData = NULL;
mpEntryList->RemoveEntry( nPos );
+ if( mnCurrentPos >= mpEntryList->GetEntryCount() )
+ mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
ImplCalcMetrics();
}
// -----------------------------------------------------------------------
+void ImplListBoxWindow::SetEntryFlags( USHORT nPos, long nFlags )
+{
+ mpEntryList->SetEntryFlags( nPos, nFlags );
+ ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( nPos );
+ if( pEntry )
+ ImplUpdateEntryMetrics( *pEntry );
+}
+
+// -----------------------------------------------------------------------
+
void ImplListBoxWindow::ImplShowFocusRect()
{
if ( mbHasFocusRect )
@@ -785,14 +853,57 @@ void ImplListBoxWindow::ImplHideFocusRect()
USHORT ImplListBoxWindow::GetEntryPosForPoint( const Point& rPoint ) const
{
- USHORT nSelect = (USHORT) ( ( rPoint.Y() + mnBorder ) / mnMaxHeight ) + (USHORT) mnTop;
- if( nSelect < mnTop || nSelect >= mpEntryList->GetEntryCount() )
+ long nY = mnBorder;
+
+ USHORT nSelect = mnTop;
+ const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nSelect );
+ while( pEntry && rPoint.Y() > pEntry->mnHeight + nY )
+ {
+ nY += pEntry->mnHeight;
+ pEntry = mpEntryList->GetEntryPtr( ++nSelect );
+ }
+ if( pEntry == NULL )
nSelect = LISTBOX_ENTRY_NOTFOUND;
+
return nSelect;
}
// -----------------------------------------------------------------------
+BOOL ImplListBoxWindow::IsVisible( USHORT i_nEntry ) const
+{
+ BOOL bRet = FALSE;
+
+ if( i_nEntry >= mnTop )
+ {
+ if( mpEntryList->GetAddedHeight( i_nEntry, mnTop ) <
+ PixelToLogic( GetSizePixel() ).Height() )
+ {
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplListBoxWindow::GetLastVisibleEntry() const
+{
+ USHORT nPos = mnTop;
+ long nWindowHeight = GetSizePixel().Height();
+ USHORT nCount = mpEntryList->GetEntryCount();
+ for( long nDiff = 0; nDiff < nWindowHeight && nPos < nCount; nDiff = mpEntryList->GetAddedHeight( nPos, mnTop ) )
+ nPos++;
+
+ if( nPos >= nCount )
+ nPos = nCount-1;
+
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
mbMouseMoveSelect = FALSE; // Nur bis zum ersten MouseButtonDown
@@ -863,8 +974,10 @@ void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt )
{
if ( IsMouseMoveSelect() )
{
- USHORT nSelect = (USHORT) ( ( rMEvt.GetPosPixel().Y() + mnBorder ) / mnMaxHeight ) + (USHORT) mnTop;
- nSelect = Min( nSelect, (USHORT) ( mnTop + mnMaxVisibleEntries ) );
+ USHORT nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
+ if( nSelect == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->GetEntryCount() - 1;
+ nSelect = Min( nSelect, GetLastVisibleEntry() );
nSelect = Min( nSelect, (USHORT) ( mpEntryList->GetEntryCount() - 1 ) );
// Select only visible Entries with MouseMove, otherwise Tracking...
if ( IsVisible( nSelect ) &&
@@ -944,14 +1057,15 @@ void ImplListBoxWindow::SelectEntry( USHORT nPos, BOOL bSelect )
if ( !IsVisible( nPos ) )
{
delete mpLayoutData, mpLayoutData = NULL;
- if ( !mnMaxVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
+ USHORT nVisibleEntries = GetLastVisibleEntry()-mnTop;
+ if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
{
Resize();
SetTopEntry( nPos );
}
else
{
- SetTopEntry( nPos-mnMaxVisibleEntries+1 );
+ SetTopEntry( nPos-nVisibleEntries+1 );
}
}
}
@@ -1105,7 +1219,11 @@ BOOL ImplListBoxWindow::SelectEntries( USHORT nSelect, LB_EVENT_TYPE eLET, BOOL
if( bFocusChanged )
{
- maFocusRect.SetPos( Point( 0, ( nSelect - mnTop ) * mnMaxHeight ) );
+ long nHeightDiff = mpEntryList->GetAddedHeight( nSelect, mnTop, 0 );
+ maFocusRect.SetPos( Point( 0, nHeightDiff ) );
+ Size aSz( maFocusRect.GetWidth(),
+ mpEntryList->GetEntryHeight( nSelect ) );
+ maFocusRect.SetSize( aSz );
if( HasFocus() )
ImplShowFocusRect();
}
@@ -1139,7 +1257,11 @@ void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
mbTrackingSelect = FALSE;
if ( mnTrackingSaveSelection != LISTBOX_ENTRY_NOTFOUND )
{
- maFocusRect.SetPos( Point( 0, ( mnCurrentPos - mnTop ) * mnMaxHeight ) );
+ long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
+ maFocusRect.SetPos( Point( 0, nHeightDiff ) );
+ Size aSz( maFocusRect.GetWidth(),
+ mpEntryList->GetEntryHeight( mnCurrentPos ) );
+ maFocusRect.SetSize( aSz );
ImplShowFocusRect();
}
}
@@ -1187,14 +1309,14 @@ void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
{
nSelect = Min( (USHORT)(mnCurrentPos+1), (USHORT)(mpEntryList->GetEntryCount()-1) );
- if( nSelect >= mnTop + mnMaxVisibleEntries )
+ if( nSelect >= GetLastVisibleEntry() )
SetTopEntry( mnTop+1 );
}
}
else
{
nSelect = (USHORT) ( ( aPt.Y() + mnBorder ) / mnMaxHeight ) + (USHORT) mnTop;
- nSelect = Min( nSelect, (USHORT) ( mnTop + mnMaxVisibleEntries ) );
+ nSelect = Min( nSelect, GetLastVisibleEntry() );
nSelect = Min( nSelect, (USHORT) ( mpEntryList->GetEntryCount() - 1 ) );
}
@@ -1268,7 +1390,10 @@ void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
}
else
{
- maFocusRect.SetPos( Point( 0, ( mnCurrentPos - mnTop ) * mnMaxHeight ) );
+ long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
+ maFocusRect.SetPos( Point( 0, nHeightDiff ) );
+ Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
+ maFocusRect.SetSize( aSz );
ImplShowFocusRect();
}
}
@@ -1351,7 +1476,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos + 1, true );
}
- if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= ( mnTop + mnMaxVisibleEntries ) ) )
+ if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= GetLastVisibleEntry() ) )
SetTopEntry( mnTop+1 );
bDone = TRUE;
@@ -1364,8 +1489,9 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
{
if ( IsReadOnly() )
{
- SetTopEntry( ( mnTop > mnMaxVisibleEntries ) ?
- (mnTop-mnMaxVisibleEntries) : 0 );
+ USHORT nCurVis = GetLastVisibleEntry() - mnTop +1;
+ SetTopEntry( ( mnTop > nCurVis ) ?
+ (mnTop-nCurVis) : 0 );
}
else if ( !bCtrl && !bMod2 )
{
@@ -1376,7 +1502,10 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
else if ( mnCurrentPos )
{
if( mnCurrentPos == mnTop )
- SetTopEntry( ( mnTop > mnMaxVisibleEntries ) ? ( mnTop-mnMaxVisibleEntries+1 ) : 0 );
+ {
+ USHORT nCurVis = GetLastVisibleEntry() - mnTop +1;
+ SetTopEntry( ( mnTop > nCurVis ) ? ( mnTop-nCurVis+1 ) : 0 );
+ }
// find first selectable starting from mnTop looking foreward
nSelect = mpEntryList->FindFirstSelectable( mnTop, true );
@@ -1391,7 +1520,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
{
if ( IsReadOnly() )
{
- SetTopEntry( mnTop + mnMaxVisibleEntries );
+ SetTopEntry( GetLastVisibleEntry() );
}
else if ( !bCtrl && !bMod2 )
{
@@ -1402,13 +1531,14 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
{
USHORT nCount = mpEntryList->GetEntryCount();
- USHORT nTmp = Min( mnMaxVisibleEntries, nCount );
+ USHORT nCurVis = GetLastVisibleEntry() - mnTop +1;
+ USHORT nTmp = Min( nCurVis, nCount );
nTmp += mnTop - 1;
if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 )
{
- long nTmp2 = Min( (long)(nCount-mnMaxVisibleEntries), (long)((long)mnTop+(long)mnMaxVisibleEntries-1) );
+ long nTmp2 = Min( (long)(nCount-nCurVis), (long)((long)mnTop+(long)nCurVis-1) );
nTmp2 = Max( (long)0 , nTmp2 );
- nTmp = (USHORT)(nTmp2+(mnMaxVisibleEntries-1) );
+ nTmp = (USHORT)(nTmp2+(nCurVis-1) );
SetTopEntry( (USHORT)nTmp2 );
}
// find first selectable starting from nTmp looking backwards
@@ -1457,8 +1587,9 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
{
USHORT nCount = mpEntryList->GetEntryCount();
nSelect = mpEntryList->FindFirstSelectable( nCount - 1, false );
- if( nCount > mnMaxVisibleEntries )
- SetTopEntry( nCount - mnMaxVisibleEntries );
+ USHORT nCurVis = GetLastVisibleEntry() - mnTop + 1;
+ if( nCount > nCurVis )
+ SetTopEntry( nCount - nCurVis );
}
bDone = TRUE;
}
@@ -1565,10 +1696,11 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
if ( nSelect != LISTBOX_ENTRY_NOTFOUND )
{
+ USHORT nCurVis = GetLastVisibleEntry() - mnTop + 1;
if( nSelect < mnTop )
SetTopEntry( nSelect );
- else if( nSelect >= (mnTop + mnMaxVisibleEntries) )
- SetTopEntry( nSelect - mnMaxVisibleEntries + 1 );
+ else if( nSelect >= (mnTop + nCurVis) )
+ SetTopEntry( nSelect - nCurVis + 1 );
if ( mpEntryList->IsEntryPosSelected( nSelect ) )
nSelect = LISTBOX_ENTRY_NOTFOUND;
@@ -1610,9 +1742,13 @@ void ImplListBoxWindow::ImplPaint( USHORT nPos, BOOL bErase, bool bLayout )
{
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
+ if( ! pEntry )
+ return;
+
long nWidth = GetOutputSizePixel().Width();
- long nY = ( nPos - mnTop ) * mnMaxHeight;
- Rectangle aRect( Point( 0, nY ), Size( nWidth, mnMaxHeight ) );
+ long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
+ Rectangle aRect( Point( 0, nY ), Size( nWidth, pEntry->mnHeight ) );
if( ! bLayout )
{
@@ -1656,12 +1792,16 @@ void ImplListBoxWindow::ImplPaint( USHORT nPos, BOOL bErase, bool bLayout )
void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImagePos, bool bLayout )
{
+ const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
+ if( ! pEntry )
+ return;
+
// Bei Aenderungen in dieser Methode ggf. auch ImplWin::DrawEntry() anpassen.
if ( mbInUserDraw )
nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU
- long nY = ( nPos - mnTop ) * mnMaxHeight;
+ long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
Size aImgSz;
if( bDrawImage && mpEntryList->HasImages() && !bLayout )
@@ -1670,7 +1810,7 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
if( !!aImage )
{
aImgSz = aImage.GetSizePixel();
- Point aPtImg( mnBorder - mnLeft, nY + ( ( mnMaxHeight - aImgSz.Height() ) / 2 ) );
+ Point aPtImg( mnBorder - mnLeft, nY + ( ( pEntry->mnHeight - aImgSz.Height() ) / 2 ) );
// pb: #106948# explicit mirroring for calc
if ( mbMirroring )
@@ -1699,13 +1839,16 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
{
long nMaxWidth = Max( static_cast< long >( mnMaxWidth ),
GetOutputSizePixel().Width() - 2*mnBorder );
+ // a multiline entry should only be as wide a the window
+ if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
+ nMaxWidth = GetOutputSizePixel().Width() - 2*mnBorder;
Rectangle aTextRect( Point( mnBorder - mnLeft, nY ),
- Size( nMaxWidth, mnMaxHeight ) );
+ Size( nMaxWidth, pEntry->mnHeight ) );
if( !bDrawTextAtImagePos && ( mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled() ) )
{
- USHORT nImageWidth = Max( mnMaxImgWidth, (USHORT)maUserItemSize.Width() );
+ long nImageWidth = Max( mnMaxImgWidth, maUserItemSize.Width() );
aTextRect.Left() += nImageWidth + IMG_TXT_DISTANCE;
}
@@ -1721,7 +1864,11 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
aTextRect.Left() -= ( aImgSz.Width() + IMG_TXT_DISTANCE );
}
- DrawText( aTextRect, aStr, ImplGetTextStyle(), pVector, pDisplayText );
+ USHORT nDrawStyle = ImplGetTextStyle();
+ if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
+ nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS;
+
+ DrawText( aTextRect, aStr, nDrawStyle, pVector, pDisplayText );
}
}
@@ -1734,7 +1881,7 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
SetLineColor( ( GetBackground().GetColor() != COL_LIGHTGRAY ) ? COL_LIGHTGRAY : COL_GRAY );
Point aStartPos( 0, nY );
if ( nPos == mnSeparatorPos )
- aStartPos.Y() += mnMaxHeight-1;
+ aStartPos.Y() += pEntry->mnHeight-1;
Point aEndPos( aStartPos );
aEndPos.X() = GetOutputSizePixel().Width();
DrawLine( aStartPos, aEndPos );
@@ -1767,15 +1914,19 @@ void ImplListBoxWindow::ImplDoPaint( const Rectangle& rRect, bool bLayout )
for( USHORT i = (USHORT)mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++ )
{
- if( nY + mnMaxHeight >= rRect.Top() &&
+ const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( i );
+ if( nY + pEntry->mnHeight >= rRect.Top() &&
nY <= rRect.Bottom() + mnMaxHeight )
{
ImplPaint( i, FALSE, bLayout );
}
- nY += mnMaxHeight;
+ nY += pEntry->mnHeight;
}
- maFocusRect.SetPos( Point( 0, ( mnCurrentPos - mnTop ) * mnMaxHeight ) );
+ long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
+ maFocusRect.SetPos( Point( 0, nHeightDiff ) );
+ Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
+ maFocusRect.SetSize( aSz );
if( HasFocus() && bShowFocusRect && !bLayout )
ImplShowFocusRect();
}
@@ -1791,6 +1942,8 @@ void ImplListBoxWindow::Paint( const Rectangle& rRect )
USHORT ImplListBoxWindow::GetDisplayLineCount() const
{
+ // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
+
USHORT nCount = mpEntryList->GetEntryCount();
long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
USHORT nEntries = static_cast< USHORT >( ( nHeight + mnMaxHeight - 1 ) / mnMaxHeight );
@@ -1810,9 +1963,11 @@ void ImplListBoxWindow::Resize()
if ( bShowFocusRect )
ImplHideFocusRect();
- Size aSz( GetOutputSizePixel().Width(), mnMaxHeight );
- maFocusRect.SetSize( aSz );
- mnMaxVisibleEntries = (USHORT) ( GetOutputSizePixel().Height() / mnMaxHeight );
+ if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
+ {
+ Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
+ maFocusRect.SetSize( aSz );
+ }
if ( bShowFocusRect )
ImplShowFocusRect();
@@ -1822,20 +1977,15 @@ void ImplListBoxWindow::Resize()
// -----------------------------------------------------------------------
-void ImplListBoxWindow::CalcMaxVisibleEntries( const Size& rFloatSize )
-{
- if( mnMaxHeight )
- mnMaxVisibleEntries = (USHORT) ( (rFloatSize.Height()-4) / mnMaxHeight );
-}
-
-// -----------------------------------------------------------------------
-
void ImplListBoxWindow::GetFocus()
{
USHORT nPos = mnCurrentPos;
if ( nPos == LISTBOX_ENTRY_NOTFOUND )
nPos = 0;
- maFocusRect.SetPos( Point( 0, ( nPos - mnTop ) * mnMaxHeight ) );
+ long nHeightDiff = mpEntryList->GetAddedHeight( nPos, mnTop, 0 );
+ maFocusRect.SetPos( Point( 0, nHeightDiff ) );
+ Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( nPos ) );
+ maFocusRect.SetSize( aSz );
ImplShowFocusRect();
Control::GetFocus();
}
@@ -1864,14 +2014,22 @@ void ImplListBoxWindow::RequestHelp( const HelpEvent& rHEvt )
void ImplListBoxWindow::SetTopEntry( USHORT nTop )
{
- USHORT nMaxTop = 0;
- if ( GetEntryList()->GetEntryCount() > mnMaxVisibleEntries )
- nMaxTop = GetEntryList()->GetEntryCount() - mnMaxVisibleEntries;
- nTop = Min( nTop, nMaxTop );
+ if( mpEntryList->GetEntryCount() == 0 )
+ return;
+
+ long nWHeight = PixelToLogic( GetSizePixel() ).Height();
+
+ USHORT nLastEntry = mpEntryList->GetEntryCount()-1;
+ if( nTop > nLastEntry )
+ nTop = nLastEntry;
+ const ImplEntryType* pLast = mpEntryList->GetEntryPtr( nLastEntry );
+ while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->mnHeight < nWHeight )
+ nTop--;
+
if ( nTop != mnTop )
{
delete mpLayoutData, mpLayoutData = NULL;
- long nDiff = ( mnTop - nTop ) * mnMaxHeight;
+ long nDiff = mpEntryList->GetAddedHeight( mnTop, nTop, 0 );
Update();
ImplHideFocusRect();
mnTop = nTop;
@@ -1887,16 +2045,16 @@ void ImplListBoxWindow::SetTopEntry( USHORT nTop )
// -----------------------------------------------------------------------
-void ImplListBoxWindow::SetLeftIndent( USHORT n )
+void ImplListBoxWindow::SetLeftIndent( long n )
{
ScrollHorz( n - mnLeft );
}
// -----------------------------------------------------------------------
-void ImplListBoxWindow::ScrollHorz( short n )
+void ImplListBoxWindow::ScrollHorz( long n )
{
- short nDiff = 0;
+ long nDiff = 0;
if ( n > 0 )
{
long nWidth = GetOutputSizePixel().Width();
@@ -1907,7 +2065,7 @@ void ImplListBoxWindow::ScrollHorz( short n )
{
if( mnLeft )
{
- USHORT nAbs = -n;
+ long nAbs = -n;
nDiff = - ( ( mnLeft > nAbs ) ? nAbs : mnLeft );
}
}
@@ -1930,6 +2088,8 @@ void ImplListBoxWindow::ScrollHorz( short n )
Size ImplListBoxWindow::CalcSize( USHORT nMaxLines ) const
{
+ // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
+
Size aSz;
// USHORT nL = Min( nMaxLines, mpEntryList->GetEntryCount() );
aSz.Height() = nMaxLines * mnMaxHeight;
@@ -1941,8 +2101,9 @@ Size ImplListBoxWindow::CalcSize( USHORT nMaxLines ) const
Rectangle ImplListBoxWindow::GetBoundingRectangle( USHORT nItem ) const
{
- Size aSz( GetSizePixel().Width(), GetEntryHeight() );
- long nY = ( nItem - GetTopEntry() ) * GetEntryHeight();
+ const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem );
+ Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() );
+ long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) - mpEntryList->GetAddedHeight( GetTopEntry() );
Rectangle aRect( Point( 0, nY ), aSz );
return aRect;
}
@@ -2112,7 +2273,7 @@ void ImplListBox::RemoveEntry( USHORT nPos )
void ImplListBox::SetEntryFlags( USHORT nPos, long nFlags )
{
- maLBWindow.GetEntryList()->SetEntryFlags( nPos, nFlags );
+ maLBWindow.SetEntryFlags( nPos, nFlags );
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index df79f1580583..2fcf24478ffe 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -934,8 +934,6 @@ long ListBox::PreNotify( NotifyEvent& rNEvt )
default:
{
- if( mpFloatWin )
- mpImplLB->GetMainWindow()->CalcMaxVisibleEntries( mpFloatWin->CalcFloatSize() );
nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
}
}
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index f61525f9a483..5bb7b0d9afcf 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -5285,6 +5285,30 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
}
nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
}
+ else
+ {
+ // fallback to something really simple
+ USHORT nSpacePos = STRING_LEN;
+ long nW = 0;
+ do
+ {
+ nSpacePos = rStr.SearchBackward( sal_Unicode(' '), nSpacePos );
+ if( nSpacePos != STRING_NOTFOUND )
+ {
+ if( nSpacePos > nPos )
+ nSpacePos--;
+ nW = GetTextWidth( rStr, nPos, nSpacePos-nPos );
+ }
+ } while( nW > nWidth );
+
+ if( nSpacePos != STRING_NOTFOUND )
+ {
+ nBreakPos = nSpacePos;
+ nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
+ if( nBreakPos < rStr.Len()-1 )
+ nBreakPos++;
+ }
+ }
}
if ( nLineWidth > nMaxLineWidth )