1*9f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9f62ea84SAndrew Rist * distributed with this work for additional information 6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an 15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 17*9f62ea84SAndrew Rist * specific language governing permissions and limitations 18*9f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9f62ea84SAndrew Rist *************************************************************/ 21*9f62ea84SAndrew Rist 22*9f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <tools/debug.hxx> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <vcl/svapp.hxx> 30cdf0e10cSrcweir #include <vcl/settings.hxx> 31cdf0e10cSrcweir #include <vcl/event.hxx> 32cdf0e10cSrcweir #include <vcl/scrbar.hxx> 33cdf0e10cSrcweir #include <vcl/help.hxx> 34cdf0e10cSrcweir #include <vcl/lstbox.h> 35cdf0e10cSrcweir #include <vcl/unohelp.hxx> 36cdf0e10cSrcweir #include <vcl/i18nhelp.hxx> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <ilstbox.hxx> 39cdf0e10cSrcweir #include <controldata.hxx> 40cdf0e10cSrcweir #include <svdata.hxx> 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include <com/sun/star/i18n/XCollator.hpp> 43cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessible.hpp> 44cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp> 45cdf0e10cSrcweir 46cdf0e10cSrcweir #define MULTILINE_ENTRY_DRAW_FLAGS ( TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE | TEXT_DRAW_VCENTER ) 47cdf0e10cSrcweir 48cdf0e10cSrcweir using namespace ::com::sun::star; 49cdf0e10cSrcweir 50cdf0e10cSrcweir // ======================================================================= 51cdf0e10cSrcweir 52cdf0e10cSrcweir void ImplInitFieldSettings( Window* pWin, sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground ) 53cdf0e10cSrcweir { 54cdf0e10cSrcweir const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings(); 55cdf0e10cSrcweir 56cdf0e10cSrcweir if ( bFont ) 57cdf0e10cSrcweir { 58cdf0e10cSrcweir Font aFont = rStyleSettings.GetFieldFont(); 59cdf0e10cSrcweir if ( pWin->IsControlFont() ) 60cdf0e10cSrcweir aFont.Merge( pWin->GetControlFont() ); 61cdf0e10cSrcweir pWin->SetZoomedPointFont( aFont ); 62cdf0e10cSrcweir } 63cdf0e10cSrcweir 64cdf0e10cSrcweir if ( bFont || bForeground ) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir Color aTextColor = rStyleSettings.GetFieldTextColor(); 67cdf0e10cSrcweir if ( pWin->IsControlForeground() ) 68cdf0e10cSrcweir aTextColor = pWin->GetControlForeground(); 69cdf0e10cSrcweir pWin->SetTextColor( aTextColor ); 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir if ( bBackground ) 73cdf0e10cSrcweir { 74cdf0e10cSrcweir if( pWin->IsControlBackground() ) 75cdf0e10cSrcweir pWin->SetBackground( pWin->GetControlBackground() ); 76cdf0e10cSrcweir else 77cdf0e10cSrcweir pWin->SetBackground( rStyleSettings.GetFieldColor() ); 78cdf0e10cSrcweir } 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir // ----------------------------------------------------------------------- 82cdf0e10cSrcweir 83cdf0e10cSrcweir void ImplInitDropDownButton( PushButton* pButton ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir if ( pButton->GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN ) 86cdf0e10cSrcweir pButton->SetSymbol( SYMBOL_SPIN_UPDOWN ); 87cdf0e10cSrcweir else 88cdf0e10cSrcweir pButton->SetSymbol( SYMBOL_SPIN_DOWN ); 89cdf0e10cSrcweir 90cdf0e10cSrcweir if ( pButton->IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) 91cdf0e10cSrcweir && ! pButton->IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) ) 92cdf0e10cSrcweir pButton->SetBackground(); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir 95cdf0e10cSrcweir // ======================================================================= 96cdf0e10cSrcweir 97cdf0e10cSrcweir ImplEntryList::ImplEntryList( Window* pWindow ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir mpWindow = pWindow; 100cdf0e10cSrcweir mnLastSelected = LISTBOX_ENTRY_NOTFOUND; 101cdf0e10cSrcweir mnSelectionAnchor = LISTBOX_ENTRY_NOTFOUND; 102cdf0e10cSrcweir mnImages = 0; 103cdf0e10cSrcweir mbCallSelectionChangedHdl = sal_True; 104cdf0e10cSrcweir 105cdf0e10cSrcweir mnMRUCount = 0; 106cdf0e10cSrcweir mnMaxMRUCount = 0; 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir // ----------------------------------------------------------------------- 110cdf0e10cSrcweir 111cdf0e10cSrcweir ImplEntryList::~ImplEntryList() 112cdf0e10cSrcweir { 113cdf0e10cSrcweir Clear(); 114cdf0e10cSrcweir } 115cdf0e10cSrcweir 116cdf0e10cSrcweir // ----------------------------------------------------------------------- 117cdf0e10cSrcweir 118cdf0e10cSrcweir void ImplEntryList::Clear() 119cdf0e10cSrcweir { 120cdf0e10cSrcweir mnImages = 0; 121cdf0e10cSrcweir for ( sal_uInt16 n = GetEntryCount(); n; ) 122cdf0e10cSrcweir { 123cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( --n ); 124cdf0e10cSrcweir delete pImplEntry; 125cdf0e10cSrcweir } 126cdf0e10cSrcweir List::Clear(); 127cdf0e10cSrcweir } 128cdf0e10cSrcweir 129cdf0e10cSrcweir // ----------------------------------------------------------------------- 130cdf0e10cSrcweir 131cdf0e10cSrcweir void ImplEntryList::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect ) 132cdf0e10cSrcweir { 133cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( nPos ); 134cdf0e10cSrcweir if ( pImplEntry && 135cdf0e10cSrcweir ( pImplEntry->mbIsSelected != bSelect ) && 136cdf0e10cSrcweir ( (pImplEntry->mnFlags & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION) == 0 ) ) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir pImplEntry->mbIsSelected = bSelect; 139cdf0e10cSrcweir if ( mbCallSelectionChangedHdl ) 140cdf0e10cSrcweir maSelectionChangedHdl.Call( (void*)sal_IntPtr(nPos) ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir // ----------------------------------------------------------------------- 145cdf0e10cSrcweir 146cdf0e10cSrcweir uno::Reference< i18n::XCollator > ImplGetCollator (lang::Locale &rLocale) 147cdf0e10cSrcweir { 148cdf0e10cSrcweir static uno::Reference< i18n::XCollator > xCollator; 149cdf0e10cSrcweir if ( !xCollator.is() ) 150cdf0e10cSrcweir xCollator = vcl::unohelper::CreateCollator(); 151cdf0e10cSrcweir if( xCollator.is() ) 152cdf0e10cSrcweir xCollator->loadDefaultCollator (rLocale, 0); 153cdf0e10cSrcweir 154cdf0e10cSrcweir return xCollator; 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir sal_uInt16 ImplEntryList::InsertEntry( sal_uInt16 nPos, ImplEntryType* pNewEntry, sal_Bool bSort ) 158cdf0e10cSrcweir { 159cdf0e10cSrcweir if ( !!pNewEntry->maImage ) 160cdf0e10cSrcweir mnImages++; 161cdf0e10cSrcweir 162cdf0e10cSrcweir if ( !bSort || !Count() ) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir Insert( pNewEntry, nPos ); 165cdf0e10cSrcweir } 166cdf0e10cSrcweir else 167cdf0e10cSrcweir { 168cdf0e10cSrcweir lang::Locale aLocale = Application::GetSettings().GetLocale(); 169cdf0e10cSrcweir uno::Reference< i18n::XCollator > xCollator = ImplGetCollator(aLocale); 170cdf0e10cSrcweir 171cdf0e10cSrcweir const XubString& rStr = pNewEntry->maStr; 172cdf0e10cSrcweir sal_uLong nLow, nHigh, nMid; 173cdf0e10cSrcweir 174cdf0e10cSrcweir nHigh = Count(); 175cdf0e10cSrcweir 176cdf0e10cSrcweir ImplEntryType* pTemp = GetEntry( (sal_uInt16)(nHigh-1) ); 177cdf0e10cSrcweir 178cdf0e10cSrcweir try 179cdf0e10cSrcweir { 180cdf0e10cSrcweir // XXX even though XCollator::compareString returns a sal_Int32 the only 181cdf0e10cSrcweir // defined values are {-1, 0, 1} which is compatible with StringCompare 182cdf0e10cSrcweir StringCompare eComp = xCollator.is() ? 183cdf0e10cSrcweir (StringCompare)xCollator->compareString (rStr, pTemp->maStr) 184cdf0e10cSrcweir : COMPARE_EQUAL; 185cdf0e10cSrcweir 186cdf0e10cSrcweir // Schnelles Einfuegen bei sortierten Daten 187cdf0e10cSrcweir if ( eComp != COMPARE_LESS ) 188cdf0e10cSrcweir { 189cdf0e10cSrcweir Insert( pNewEntry, LIST_APPEND ); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir else 192cdf0e10cSrcweir { 193cdf0e10cSrcweir nLow = mnMRUCount; 194cdf0e10cSrcweir pTemp = (ImplEntryType*)GetEntry( (sal_uInt16)nLow ); 195cdf0e10cSrcweir 196cdf0e10cSrcweir eComp = (StringCompare)xCollator->compareString (rStr, pTemp->maStr); 197cdf0e10cSrcweir if ( eComp != COMPARE_GREATER ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir Insert( pNewEntry, (sal_uLong)0 ); 200cdf0e10cSrcweir } 201cdf0e10cSrcweir else 202cdf0e10cSrcweir { 203cdf0e10cSrcweir // Binaeres Suchen 204cdf0e10cSrcweir nHigh--; 205cdf0e10cSrcweir do 206cdf0e10cSrcweir { 207cdf0e10cSrcweir nMid = (nLow + nHigh) / 2; 208cdf0e10cSrcweir pTemp = (ImplEntryType*)GetObject( nMid ); 209cdf0e10cSrcweir 210cdf0e10cSrcweir eComp = (StringCompare)xCollator->compareString (rStr, pTemp->maStr); 211cdf0e10cSrcweir 212cdf0e10cSrcweir if ( eComp == COMPARE_LESS ) 213cdf0e10cSrcweir nHigh = nMid-1; 214cdf0e10cSrcweir else 215cdf0e10cSrcweir { 216cdf0e10cSrcweir if ( eComp == COMPARE_GREATER ) 217cdf0e10cSrcweir nLow = nMid + 1; 218cdf0e10cSrcweir else 219cdf0e10cSrcweir break; 220cdf0e10cSrcweir } 221cdf0e10cSrcweir } 222cdf0e10cSrcweir while ( nLow <= nHigh ); 223cdf0e10cSrcweir 224cdf0e10cSrcweir if ( eComp != COMPARE_LESS ) 225cdf0e10cSrcweir nMid++; 226cdf0e10cSrcweir 227cdf0e10cSrcweir Insert( pNewEntry, nMid ); 228cdf0e10cSrcweir } 229cdf0e10cSrcweir } 230cdf0e10cSrcweir } 231cdf0e10cSrcweir catch (uno::RuntimeException& ) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir // XXX this is arguable, if the exception occured because pNewEntry is 234cdf0e10cSrcweir // garbage you wouldn't insert it. If the exception occured because the 235cdf0e10cSrcweir // Collator implementation is garbage then give the user a chance to see 236cdf0e10cSrcweir // his stuff 237cdf0e10cSrcweir Insert( pNewEntry, (sal_uLong)0 ); 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir } 241cdf0e10cSrcweir 242cdf0e10cSrcweir return (sal_uInt16)GetPos( pNewEntry ); 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir // ----------------------------------------------------------------------- 246cdf0e10cSrcweir 247cdf0e10cSrcweir void ImplEntryList::RemoveEntry( sal_uInt16 nPos ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::Remove( nPos ); 250cdf0e10cSrcweir if ( pImplEntry ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir if ( !!pImplEntry->maImage ) 253cdf0e10cSrcweir mnImages--; 254cdf0e10cSrcweir 255cdf0e10cSrcweir delete pImplEntry; 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir // ----------------------------------------------------------------------- 260cdf0e10cSrcweir 261cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindEntry( const XubString& rString, sal_Bool bSearchMRUArea ) const 262cdf0e10cSrcweir { 263cdf0e10cSrcweir sal_uInt16 nEntries = GetEntryCount(); 264cdf0e10cSrcweir for ( sal_uInt16 n = bSearchMRUArea ? 0 : GetMRUCount(); n < nEntries; n++ ) 265cdf0e10cSrcweir { 266cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( n ); 267cdf0e10cSrcweir String aComp( vcl::I18nHelper::filterFormattingChars( pImplEntry->maStr ) ); 268cdf0e10cSrcweir if ( aComp == rString ) 269cdf0e10cSrcweir return n; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir return LISTBOX_ENTRY_NOTFOUND; 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir // ----------------------------------------------------------------------- 275cdf0e10cSrcweir 276cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindMatchingEntry( const XubString& rStr, sal_uInt16 nStart, sal_Bool bForward, sal_Bool bLazy ) const 277cdf0e10cSrcweir { 278cdf0e10cSrcweir sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND; 279cdf0e10cSrcweir sal_uInt16 nEntryCount = GetEntryCount(); 280cdf0e10cSrcweir if ( !bForward ) 281cdf0e10cSrcweir nStart++; // wird sofort dekrementiert 282cdf0e10cSrcweir 283cdf0e10cSrcweir const vcl::I18nHelper& rI18nHelper = mpWindow->GetSettings().GetLocaleI18nHelper(); 284cdf0e10cSrcweir for ( sal_uInt16 n = nStart; bForward ? ( n < nEntryCount ) : n; ) 285cdf0e10cSrcweir { 286cdf0e10cSrcweir if ( !bForward ) 287cdf0e10cSrcweir n--; 288cdf0e10cSrcweir 289cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( n ); 290cdf0e10cSrcweir sal_Bool bMatch = bLazy ? rI18nHelper.MatchString( rStr, pImplEntry->maStr ) != 0 : ( rStr.Match( pImplEntry->maStr ) == STRING_MATCH ); 291cdf0e10cSrcweir if ( bMatch ) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir nPos = n; 294cdf0e10cSrcweir break; 295cdf0e10cSrcweir } 296cdf0e10cSrcweir 297cdf0e10cSrcweir if ( bForward ) 298cdf0e10cSrcweir n++; 299cdf0e10cSrcweir } 300cdf0e10cSrcweir 301cdf0e10cSrcweir return nPos; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir 304cdf0e10cSrcweir // ----------------------------------------------------------------------- 305cdf0e10cSrcweir 306cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindEntry( const void* pData ) const 307cdf0e10cSrcweir { 308cdf0e10cSrcweir sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND; 309cdf0e10cSrcweir for ( sal_uInt16 n = GetEntryCount(); n; ) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( --n ); 312cdf0e10cSrcweir if ( pImplEntry->mpUserData == pData ) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir nPos = n; 315cdf0e10cSrcweir break; 316cdf0e10cSrcweir } 317cdf0e10cSrcweir } 318cdf0e10cSrcweir return nPos; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir // ----------------------------------------------------------------------- 322cdf0e10cSrcweir 323cdf0e10cSrcweir long ImplEntryList::GetAddedHeight( sal_uInt16 i_nEndIndex, sal_uInt16 i_nBeginIndex, long i_nBeginHeight ) const 324cdf0e10cSrcweir { 325cdf0e10cSrcweir long nHeight = i_nBeginHeight; 326cdf0e10cSrcweir sal_uInt16 nStart = i_nEndIndex > i_nBeginIndex ? i_nBeginIndex : i_nEndIndex; 327cdf0e10cSrcweir sal_uInt16 nStop = i_nEndIndex > i_nBeginIndex ? i_nEndIndex : i_nBeginIndex; 328cdf0e10cSrcweir sal_uInt16 nEntryCount = GetEntryCount(); 329cdf0e10cSrcweir if( nStop != LISTBOX_ENTRY_NOTFOUND && nEntryCount != 0 ) 330cdf0e10cSrcweir { 331cdf0e10cSrcweir // sanity check 332cdf0e10cSrcweir if( nStop > nEntryCount-1 ) 333cdf0e10cSrcweir nStop = nEntryCount-1; 334cdf0e10cSrcweir if( nStart > nEntryCount-1 ) 335cdf0e10cSrcweir nStart = nEntryCount-1; 336cdf0e10cSrcweir 337cdf0e10cSrcweir sal_uInt16 nIndex = nStart; 338cdf0e10cSrcweir while( nIndex != LISTBOX_ENTRY_NOTFOUND && nIndex < nStop ) 339cdf0e10cSrcweir { 340cdf0e10cSrcweir nHeight += GetEntryPtr( nIndex )-> mnHeight; 341cdf0e10cSrcweir nIndex++; 342cdf0e10cSrcweir } 343cdf0e10cSrcweir } 344cdf0e10cSrcweir else 345cdf0e10cSrcweir nHeight = 0; 346cdf0e10cSrcweir return i_nEndIndex > i_nBeginIndex ? nHeight : -nHeight; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir 349cdf0e10cSrcweir // ----------------------------------------------------------------------- 350cdf0e10cSrcweir 351cdf0e10cSrcweir long ImplEntryList::GetEntryHeight( sal_uInt16 nPos ) const 352cdf0e10cSrcweir { 353cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( nPos ); 354cdf0e10cSrcweir return pImplEntry ? pImplEntry->mnHeight : 0; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir 357cdf0e10cSrcweir // ----------------------------------------------------------------------- 358cdf0e10cSrcweir 359cdf0e10cSrcweir XubString ImplEntryList::GetEntryText( sal_uInt16 nPos ) const 360cdf0e10cSrcweir { 361cdf0e10cSrcweir XubString aEntryText; 362cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( nPos ); 363cdf0e10cSrcweir if ( pImplEntry ) 364cdf0e10cSrcweir aEntryText = pImplEntry->maStr; 365cdf0e10cSrcweir return aEntryText; 366cdf0e10cSrcweir } 367cdf0e10cSrcweir 368cdf0e10cSrcweir // ----------------------------------------------------------------------- 369cdf0e10cSrcweir 370cdf0e10cSrcweir sal_Bool ImplEntryList::HasEntryImage( sal_uInt16 nPos ) const 371cdf0e10cSrcweir { 372cdf0e10cSrcweir sal_Bool bImage = sal_False; 373cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos ); 374cdf0e10cSrcweir if ( pImplEntry ) 375cdf0e10cSrcweir bImage = !!pImplEntry->maImage; 376cdf0e10cSrcweir return bImage; 377cdf0e10cSrcweir } 378cdf0e10cSrcweir 379cdf0e10cSrcweir // ----------------------------------------------------------------------- 380cdf0e10cSrcweir 381cdf0e10cSrcweir Image ImplEntryList::GetEntryImage( sal_uInt16 nPos ) const 382cdf0e10cSrcweir { 383cdf0e10cSrcweir Image aImage; 384cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos ); 385cdf0e10cSrcweir if ( pImplEntry ) 386cdf0e10cSrcweir aImage = pImplEntry->maImage; 387cdf0e10cSrcweir return aImage; 388cdf0e10cSrcweir } 389cdf0e10cSrcweir 390cdf0e10cSrcweir // ----------------------------------------------------------------------- 391cdf0e10cSrcweir 392cdf0e10cSrcweir void ImplEntryList::SetEntryData( sal_uInt16 nPos, void* pNewData ) 393cdf0e10cSrcweir { 394cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos ); 395cdf0e10cSrcweir if ( pImplEntry ) 396cdf0e10cSrcweir pImplEntry->mpUserData = pNewData; 397cdf0e10cSrcweir } 398cdf0e10cSrcweir 399cdf0e10cSrcweir // ----------------------------------------------------------------------- 400cdf0e10cSrcweir 401cdf0e10cSrcweir void* ImplEntryList::GetEntryData( sal_uInt16 nPos ) const 402cdf0e10cSrcweir { 403cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos ); 404cdf0e10cSrcweir return pImplEntry ? pImplEntry->mpUserData : NULL; 405cdf0e10cSrcweir } 406cdf0e10cSrcweir 407cdf0e10cSrcweir // ----------------------------------------------------------------------- 408cdf0e10cSrcweir 409cdf0e10cSrcweir void ImplEntryList::SetEntryFlags( sal_uInt16 nPos, long nFlags ) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos ); 412cdf0e10cSrcweir if ( pImplEntry ) 413cdf0e10cSrcweir pImplEntry->mnFlags = nFlags; 414cdf0e10cSrcweir } 415cdf0e10cSrcweir 416cdf0e10cSrcweir // ----------------------------------------------------------------------- 417cdf0e10cSrcweir 418cdf0e10cSrcweir long ImplEntryList::GetEntryFlags( sal_uInt16 nPos ) const 419cdf0e10cSrcweir { 420cdf0e10cSrcweir ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos ); 421cdf0e10cSrcweir return pImplEntry ? pImplEntry->mnFlags : 0; 422cdf0e10cSrcweir } 423cdf0e10cSrcweir 424cdf0e10cSrcweir // ----------------------------------------------------------------------- 425cdf0e10cSrcweir 426cdf0e10cSrcweir sal_uInt16 ImplEntryList::GetSelectEntryCount() const 427cdf0e10cSrcweir { 428cdf0e10cSrcweir sal_uInt16 nSelCount = 0; 429cdf0e10cSrcweir for ( sal_uInt16 n = GetEntryCount(); n; ) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( --n ); 432cdf0e10cSrcweir if ( pImplEntry->mbIsSelected ) 433cdf0e10cSrcweir nSelCount++; 434cdf0e10cSrcweir } 435cdf0e10cSrcweir return nSelCount; 436cdf0e10cSrcweir } 437cdf0e10cSrcweir 438cdf0e10cSrcweir // ----------------------------------------------------------------------- 439cdf0e10cSrcweir 440cdf0e10cSrcweir XubString ImplEntryList::GetSelectEntry( sal_uInt16 nIndex ) const 441cdf0e10cSrcweir { 442cdf0e10cSrcweir return GetEntryText( GetSelectEntryPos( nIndex ) ); 443cdf0e10cSrcweir } 444cdf0e10cSrcweir 445cdf0e10cSrcweir // ----------------------------------------------------------------------- 446cdf0e10cSrcweir 447cdf0e10cSrcweir sal_uInt16 ImplEntryList::GetSelectEntryPos( sal_uInt16 nIndex ) const 448cdf0e10cSrcweir { 449cdf0e10cSrcweir sal_uInt16 nSelEntryPos = LISTBOX_ENTRY_NOTFOUND; 450cdf0e10cSrcweir sal_uInt16 nSel = 0; 451cdf0e10cSrcweir sal_uInt16 nEntryCount = GetEntryCount(); 452cdf0e10cSrcweir 453cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < nEntryCount; n++ ) 454cdf0e10cSrcweir { 455cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( n ); 456cdf0e10cSrcweir if ( pImplEntry->mbIsSelected ) 457cdf0e10cSrcweir { 458cdf0e10cSrcweir if ( nSel == nIndex ) 459cdf0e10cSrcweir { 460cdf0e10cSrcweir nSelEntryPos = n; 461cdf0e10cSrcweir break; 462cdf0e10cSrcweir } 463cdf0e10cSrcweir nSel++; 464cdf0e10cSrcweir } 465cdf0e10cSrcweir } 466cdf0e10cSrcweir 467cdf0e10cSrcweir return nSelEntryPos; 468cdf0e10cSrcweir } 469cdf0e10cSrcweir 470cdf0e10cSrcweir // ----------------------------------------------------------------------- 471cdf0e10cSrcweir 472cdf0e10cSrcweir sal_Bool ImplEntryList::IsEntrySelected( const XubString& rStr ) const 473cdf0e10cSrcweir { 474cdf0e10cSrcweir return IsEntryPosSelected( FindEntry( rStr ) ); 475cdf0e10cSrcweir } 476cdf0e10cSrcweir 477cdf0e10cSrcweir // ----------------------------------------------------------------------- 478cdf0e10cSrcweir 479cdf0e10cSrcweir sal_Bool ImplEntryList::IsEntryPosSelected( sal_uInt16 nIndex ) const 480cdf0e10cSrcweir { 481cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( nIndex ); 482cdf0e10cSrcweir return pImplEntry ? pImplEntry->mbIsSelected : sal_False; 483cdf0e10cSrcweir } 484cdf0e10cSrcweir 485cdf0e10cSrcweir // ----------------------------------------------------------------------- 486cdf0e10cSrcweir 487cdf0e10cSrcweir bool ImplEntryList::IsEntrySelectable( sal_uInt16 nPos ) const 488cdf0e10cSrcweir { 489cdf0e10cSrcweir ImplEntryType* pImplEntry = GetEntry( nPos ); 490cdf0e10cSrcweir return pImplEntry ? ((pImplEntry->mnFlags & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION) == 0) : true; 491cdf0e10cSrcweir } 492cdf0e10cSrcweir 493cdf0e10cSrcweir // ----------------------------------------------------------------------- 494cdf0e10cSrcweir 495cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindFirstSelectable( sal_uInt16 nPos, bool bForward /* = true */ ) 496cdf0e10cSrcweir { 497cdf0e10cSrcweir if( IsEntrySelectable( nPos ) ) 498cdf0e10cSrcweir return nPos; 499cdf0e10cSrcweir 500cdf0e10cSrcweir if( bForward ) 501cdf0e10cSrcweir { 502cdf0e10cSrcweir for( nPos = nPos + 1; nPos < GetEntryCount(); nPos++ ) 503cdf0e10cSrcweir { 504cdf0e10cSrcweir if( IsEntrySelectable( nPos ) ) 505cdf0e10cSrcweir return nPos; 506cdf0e10cSrcweir } 507cdf0e10cSrcweir } 508cdf0e10cSrcweir else 509cdf0e10cSrcweir { 510cdf0e10cSrcweir while( nPos ) 511cdf0e10cSrcweir { 512cdf0e10cSrcweir nPos--; 513cdf0e10cSrcweir if( IsEntrySelectable( nPos ) ) 514cdf0e10cSrcweir return nPos; 515cdf0e10cSrcweir } 516cdf0e10cSrcweir } 517cdf0e10cSrcweir 518cdf0e10cSrcweir return LISTBOX_ENTRY_NOTFOUND; 519cdf0e10cSrcweir } 520cdf0e10cSrcweir 521cdf0e10cSrcweir // ======================================================================= 522cdf0e10cSrcweir 523cdf0e10cSrcweir ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) : 524cdf0e10cSrcweir Control( pParent, 0 ), 525cdf0e10cSrcweir maQuickSelectionEngine( *this ) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir mpEntryList = new ImplEntryList( this ); 528cdf0e10cSrcweir 529cdf0e10cSrcweir mnTop = 0; 530cdf0e10cSrcweir mnLeft = 0; 531cdf0e10cSrcweir mnBorder = 1; 532cdf0e10cSrcweir mnSelectModifier = 0; 533cdf0e10cSrcweir mnUserDrawEntry = LISTBOX_ENTRY_NOTFOUND; 534cdf0e10cSrcweir mbTrack = sal_False; 535cdf0e10cSrcweir mbImgsDiffSz = sal_False; 536cdf0e10cSrcweir mbTravelSelect = sal_False; 537cdf0e10cSrcweir mbTrackingSelect = sal_False; 538cdf0e10cSrcweir mbSelectionChanged = sal_False; 539cdf0e10cSrcweir mbMouseMoveSelect = sal_False; 540cdf0e10cSrcweir mbMulti = sal_False; 541cdf0e10cSrcweir mbStackMode = sal_False; 542cdf0e10cSrcweir mbGrabFocus = sal_False; 543cdf0e10cSrcweir mbUserDrawEnabled = sal_False; 544cdf0e10cSrcweir mbInUserDraw = sal_False; 545cdf0e10cSrcweir mbReadOnly = sal_False; 546cdf0e10cSrcweir mbHasFocusRect = sal_False; 547cdf0e10cSrcweir mbRight = ( nWinStyle & WB_RIGHT ) ? sal_True : sal_False; 548cdf0e10cSrcweir mbCenter = ( nWinStyle & WB_CENTER ) ? sal_True : sal_False; 549cdf0e10cSrcweir mbSimpleMode = ( nWinStyle & WB_SIMPLEMODE ) ? sal_True : sal_False; 550cdf0e10cSrcweir mbSort = ( nWinStyle & WB_SORT ) ? sal_True : sal_False; 551cdf0e10cSrcweir 552cdf0e10cSrcweir // pb: #106948# explicit mirroring for calc 553cdf0e10cSrcweir mbMirroring = sal_False; 554cdf0e10cSrcweir 555cdf0e10cSrcweir mnCurrentPos = LISTBOX_ENTRY_NOTFOUND; 556cdf0e10cSrcweir mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND; 557cdf0e10cSrcweir mnSeparatorPos = LISTBOX_ENTRY_NOTFOUND; 558cdf0e10cSrcweir meProminentType = PROMINENT_TOP; 559cdf0e10cSrcweir 560cdf0e10cSrcweir SetLineColor(); 561cdf0e10cSrcweir SetTextFillColor(); 562cdf0e10cSrcweir SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) ); 563cdf0e10cSrcweir 564cdf0e10cSrcweir ImplInitSettings( sal_True, sal_True, sal_True ); 565cdf0e10cSrcweir ImplCalcMetrics(); 566cdf0e10cSrcweir } 567cdf0e10cSrcweir 568cdf0e10cSrcweir // ----------------------------------------------------------------------- 569cdf0e10cSrcweir 570cdf0e10cSrcweir ImplListBoxWindow::~ImplListBoxWindow() 571cdf0e10cSrcweir { 572cdf0e10cSrcweir delete mpEntryList; 573cdf0e10cSrcweir } 574cdf0e10cSrcweir 575cdf0e10cSrcweir // ----------------------------------------------------------------------- 576cdf0e10cSrcweir 577cdf0e10cSrcweir void ImplListBoxWindow::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground ) 578cdf0e10cSrcweir { 579cdf0e10cSrcweir ImplInitFieldSettings( this, bFont, bForeground, bBackground ); 580cdf0e10cSrcweir } 581cdf0e10cSrcweir 582cdf0e10cSrcweir // ----------------------------------------------------------------------- 583cdf0e10cSrcweir 584cdf0e10cSrcweir void ImplListBoxWindow::ImplCalcMetrics() 585cdf0e10cSrcweir { 586cdf0e10cSrcweir mnMaxWidth = 0; 587cdf0e10cSrcweir mnMaxTxtWidth = 0; 588cdf0e10cSrcweir mnMaxImgWidth = 0; 589cdf0e10cSrcweir mnMaxImgTxtWidth= 0; 590cdf0e10cSrcweir mnMaxImgHeight = 0; 591cdf0e10cSrcweir 592cdf0e10cSrcweir mnTextHeight = (sal_uInt16)GetTextHeight(); 593cdf0e10cSrcweir mnMaxTxtHeight = mnTextHeight + mnBorder; 594cdf0e10cSrcweir mnMaxHeight = mnMaxTxtHeight; 595cdf0e10cSrcweir 596cdf0e10cSrcweir if ( maUserItemSize.Height() > mnMaxHeight ) 597cdf0e10cSrcweir mnMaxHeight = (sal_uInt16) maUserItemSize.Height(); 598cdf0e10cSrcweir if ( maUserItemSize.Width() > mnMaxWidth ) 599cdf0e10cSrcweir mnMaxWidth= (sal_uInt16) maUserItemSize.Width(); 600cdf0e10cSrcweir 601cdf0e10cSrcweir for ( sal_uInt16 n = mpEntryList->GetEntryCount(); n; ) 602cdf0e10cSrcweir { 603cdf0e10cSrcweir ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( --n ); 604cdf0e10cSrcweir ImplUpdateEntryMetrics( *pEntry ); 605cdf0e10cSrcweir } 606cdf0e10cSrcweir 607cdf0e10cSrcweir if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND ) 608cdf0e10cSrcweir { 609cdf0e10cSrcweir Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryPtr( mnCurrentPos )->mnHeight ); 610cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 611cdf0e10cSrcweir } 612cdf0e10cSrcweir } 613cdf0e10cSrcweir 614cdf0e10cSrcweir // ----------------------------------------------------------------------- 615cdf0e10cSrcweir 616cdf0e10cSrcweir void ImplListBoxWindow::Clear() 617cdf0e10cSrcweir { 618cdf0e10cSrcweir mpEntryList->Clear(); 619cdf0e10cSrcweir 620cdf0e10cSrcweir mnMaxHeight = mnMaxTxtHeight; 621cdf0e10cSrcweir mnMaxWidth = 0; 622cdf0e10cSrcweir mnMaxTxtWidth = 0; 623cdf0e10cSrcweir mnMaxImgTxtWidth= 0; 624cdf0e10cSrcweir mnMaxImgWidth = 0; 625cdf0e10cSrcweir mnMaxImgHeight = 0; 626cdf0e10cSrcweir mnTop = 0; 627cdf0e10cSrcweir mnLeft = 0; 628cdf0e10cSrcweir mbImgsDiffSz = sal_False; 629cdf0e10cSrcweir ImplClearLayoutData(); 630cdf0e10cSrcweir 631cdf0e10cSrcweir mnCurrentPos = LISTBOX_ENTRY_NOTFOUND; 632cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 633cdf0e10cSrcweir 634cdf0e10cSrcweir Invalidate(); 635cdf0e10cSrcweir } 636cdf0e10cSrcweir 637cdf0e10cSrcweir void ImplListBoxWindow::SetUserItemSize( const Size& rSz ) 638cdf0e10cSrcweir { 639cdf0e10cSrcweir ImplClearLayoutData(); 640cdf0e10cSrcweir maUserItemSize = rSz; 641cdf0e10cSrcweir ImplCalcMetrics(); 642cdf0e10cSrcweir } 643cdf0e10cSrcweir 644cdf0e10cSrcweir // ----------------------------------------------------------------------- 645cdf0e10cSrcweir 646cdf0e10cSrcweir struct ImplEntryMetrics 647cdf0e10cSrcweir { 648cdf0e10cSrcweir sal_Bool bText; 649cdf0e10cSrcweir sal_Bool bImage; 650cdf0e10cSrcweir long nEntryWidth; 651cdf0e10cSrcweir long nEntryHeight; 652cdf0e10cSrcweir long nTextWidth; 653cdf0e10cSrcweir long nImgWidth; 654cdf0e10cSrcweir long nImgHeight; 655cdf0e10cSrcweir }; 656cdf0e10cSrcweir 657cdf0e10cSrcweir // ----------------------------------------------------------------------- 658cdf0e10cSrcweir 659cdf0e10cSrcweir void ImplListBoxWindow::ImplUpdateEntryMetrics( ImplEntryType& rEntry ) 660cdf0e10cSrcweir { 661cdf0e10cSrcweir ImplEntryMetrics aMetrics; 662cdf0e10cSrcweir aMetrics.bText = rEntry.maStr.Len() ? sal_True : sal_False; 663cdf0e10cSrcweir aMetrics.bImage = !!rEntry.maImage; 664cdf0e10cSrcweir aMetrics.nEntryWidth = 0; 665cdf0e10cSrcweir aMetrics.nEntryHeight = 0; 666cdf0e10cSrcweir aMetrics.nTextWidth = 0; 667cdf0e10cSrcweir aMetrics.nImgWidth = 0; 668cdf0e10cSrcweir aMetrics.nImgHeight = 0; 669cdf0e10cSrcweir 670cdf0e10cSrcweir if ( aMetrics.bText ) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir if( (rEntry.mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) ) 673cdf0e10cSrcweir { 674cdf0e10cSrcweir // multiline case 675cdf0e10cSrcweir Size aCurSize( PixelToLogic( GetSizePixel() ) ); 676cdf0e10cSrcweir // set the current size to a large number 677cdf0e10cSrcweir // GetTextRect should shrink it to the actual size 678cdf0e10cSrcweir aCurSize.Height() = 0x7fffff; 679cdf0e10cSrcweir Rectangle aTextRect( Point( 0, 0 ), aCurSize ); 680cdf0e10cSrcweir aTextRect = GetTextRect( aTextRect, rEntry.maStr, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE ); 681cdf0e10cSrcweir aMetrics.nTextWidth = aTextRect.GetWidth(); 682cdf0e10cSrcweir if( aMetrics.nTextWidth > mnMaxTxtWidth ) 683cdf0e10cSrcweir mnMaxTxtWidth = aMetrics.nTextWidth; 684cdf0e10cSrcweir aMetrics.nEntryWidth = mnMaxTxtWidth; 685cdf0e10cSrcweir aMetrics.nEntryHeight = aTextRect.GetHeight() + mnBorder; 686cdf0e10cSrcweir } 687cdf0e10cSrcweir else 688cdf0e10cSrcweir { 689cdf0e10cSrcweir // normal single line case 690cdf0e10cSrcweir aMetrics.nTextWidth = (sal_uInt16)GetTextWidth( rEntry.maStr ); 691cdf0e10cSrcweir if( aMetrics.nTextWidth > mnMaxTxtWidth ) 692cdf0e10cSrcweir mnMaxTxtWidth = aMetrics.nTextWidth; 693cdf0e10cSrcweir aMetrics.nEntryWidth = mnMaxTxtWidth; 694cdf0e10cSrcweir aMetrics.nEntryHeight = mnTextHeight + mnBorder; 695cdf0e10cSrcweir } 696cdf0e10cSrcweir } 697cdf0e10cSrcweir if ( aMetrics.bImage ) 698cdf0e10cSrcweir { 699cdf0e10cSrcweir Size aImgSz = rEntry.maImage.GetSizePixel(); 700cdf0e10cSrcweir aMetrics.nImgWidth = (sal_uInt16) CalcZoom( aImgSz.Width() ); 701cdf0e10cSrcweir aMetrics.nImgHeight = (sal_uInt16) CalcZoom( aImgSz.Height() ); 702cdf0e10cSrcweir 703cdf0e10cSrcweir if( mnMaxImgWidth && ( aMetrics.nImgWidth != mnMaxImgWidth ) ) 704cdf0e10cSrcweir mbImgsDiffSz = sal_True; 705cdf0e10cSrcweir else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) ) 706cdf0e10cSrcweir mbImgsDiffSz = sal_True; 707cdf0e10cSrcweir 708cdf0e10cSrcweir if( aMetrics.nImgWidth > mnMaxImgWidth ) 709cdf0e10cSrcweir mnMaxImgWidth = aMetrics.nImgWidth; 710cdf0e10cSrcweir if( aMetrics.nImgHeight > mnMaxImgHeight ) 711cdf0e10cSrcweir mnMaxImgHeight = aMetrics.nImgHeight; 712cdf0e10cSrcweir 713cdf0e10cSrcweir mnMaxImgTxtWidth = Max( mnMaxImgTxtWidth, aMetrics.nTextWidth ); 714cdf0e10cSrcweir aMetrics.nEntryHeight = Max( aMetrics.nImgHeight, aMetrics.nEntryHeight ); 715cdf0e10cSrcweir 716cdf0e10cSrcweir } 717cdf0e10cSrcweir if ( IsUserDrawEnabled() || aMetrics.bImage ) 718cdf0e10cSrcweir { 719cdf0e10cSrcweir aMetrics.nEntryWidth = Max( aMetrics.nImgWidth, maUserItemSize.Width() ); 720cdf0e10cSrcweir if ( aMetrics.bText ) 721cdf0e10cSrcweir aMetrics.nEntryWidth += aMetrics.nTextWidth + IMG_TXT_DISTANCE; 722cdf0e10cSrcweir aMetrics.nEntryHeight = Max( Max( mnMaxImgHeight, maUserItemSize.Height() ) + 2, 723cdf0e10cSrcweir aMetrics.nEntryHeight ); 724cdf0e10cSrcweir } 725cdf0e10cSrcweir 726cdf0e10cSrcweir if ( !aMetrics.bText && !aMetrics.bImage && !IsUserDrawEnabled() ) 727cdf0e10cSrcweir { 728cdf0e10cSrcweir // entries which have no (aka an empty) text, and no image, and are not user-drawn, should be 729cdf0e10cSrcweir // shown nonetheless 730cdf0e10cSrcweir aMetrics.nEntryHeight = mnTextHeight + mnBorder; 731cdf0e10cSrcweir } 732cdf0e10cSrcweir 733cdf0e10cSrcweir if ( aMetrics.nEntryWidth > mnMaxWidth ) 734cdf0e10cSrcweir mnMaxWidth = aMetrics.nEntryWidth; 735cdf0e10cSrcweir if ( aMetrics.nEntryHeight > mnMaxHeight ) 736cdf0e10cSrcweir mnMaxHeight = aMetrics.nEntryHeight; 737cdf0e10cSrcweir 738cdf0e10cSrcweir rEntry.mnHeight = aMetrics.nEntryHeight; 739cdf0e10cSrcweir } 740cdf0e10cSrcweir 741cdf0e10cSrcweir // ----------------------------------------------------------------------- 742cdf0e10cSrcweir 743cdf0e10cSrcweir void ImplListBoxWindow::ImplCallSelect() 744cdf0e10cSrcweir { 745cdf0e10cSrcweir if ( !IsTravelSelect() && GetEntryList()->GetMaxMRUCount() ) 746cdf0e10cSrcweir { 747cdf0e10cSrcweir // Insert the selected entry as MRU, if not allready first MRU 748cdf0e10cSrcweir sal_uInt16 nSelected = GetEntryList()->GetSelectEntryPos( 0 ); 749cdf0e10cSrcweir sal_uInt16 nMRUCount = GetEntryList()->GetMRUCount(); 750cdf0e10cSrcweir String aSelected = GetEntryList()->GetEntryText( nSelected ); 751cdf0e10cSrcweir sal_uInt16 nFirstMatchingEntryPos = GetEntryList()->FindEntry( aSelected, sal_True ); 752cdf0e10cSrcweir if ( nFirstMatchingEntryPos || !nMRUCount ) 753cdf0e10cSrcweir { 754cdf0e10cSrcweir sal_Bool bSelectNewEntry = sal_False; 755cdf0e10cSrcweir if ( nFirstMatchingEntryPos < nMRUCount ) 756cdf0e10cSrcweir { 757cdf0e10cSrcweir RemoveEntry( nFirstMatchingEntryPos ); 758cdf0e10cSrcweir nMRUCount--; 759cdf0e10cSrcweir if ( nFirstMatchingEntryPos == nSelected ) 760cdf0e10cSrcweir bSelectNewEntry = sal_True; 761cdf0e10cSrcweir } 762cdf0e10cSrcweir else if ( nMRUCount == GetEntryList()->GetMaxMRUCount() ) 763cdf0e10cSrcweir { 764cdf0e10cSrcweir RemoveEntry( nMRUCount - 1 ); 765cdf0e10cSrcweir nMRUCount--; 766cdf0e10cSrcweir } 767cdf0e10cSrcweir 768cdf0e10cSrcweir ImplClearLayoutData(); 769cdf0e10cSrcweir 770cdf0e10cSrcweir ImplEntryType* pNewEntry = new ImplEntryType( aSelected ); 771cdf0e10cSrcweir pNewEntry->mbIsSelected = bSelectNewEntry; 772cdf0e10cSrcweir GetEntryList()->InsertEntry( 0, pNewEntry, sal_False ); 773cdf0e10cSrcweir ImplUpdateEntryMetrics( *pNewEntry ); 774cdf0e10cSrcweir GetEntryList()->SetMRUCount( ++nMRUCount ); 775cdf0e10cSrcweir SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 ); 776cdf0e10cSrcweir maMRUChangedHdl.Call( NULL ); 777cdf0e10cSrcweir } 778cdf0e10cSrcweir } 779cdf0e10cSrcweir 780cdf0e10cSrcweir maSelectHdl.Call( NULL ); 781cdf0e10cSrcweir mbSelectionChanged = sal_False; 782cdf0e10cSrcweir } 783cdf0e10cSrcweir 784cdf0e10cSrcweir // ----------------------------------------------------------------------- 785cdf0e10cSrcweir 786cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::InsertEntry( sal_uInt16 nPos, ImplEntryType* pNewEntry ) 787cdf0e10cSrcweir { 788cdf0e10cSrcweir ImplClearLayoutData(); 789cdf0e10cSrcweir sal_uInt16 nNewPos = mpEntryList->InsertEntry( nPos, pNewEntry, mbSort ); 790cdf0e10cSrcweir 791cdf0e10cSrcweir if( (GetStyle() & WB_WORDBREAK) ) 792cdf0e10cSrcweir pNewEntry->mnFlags |= LISTBOX_ENTRY_FLAG_MULTILINE; 793cdf0e10cSrcweir 794cdf0e10cSrcweir ImplUpdateEntryMetrics( *pNewEntry ); 795cdf0e10cSrcweir return nNewPos; 796cdf0e10cSrcweir } 797cdf0e10cSrcweir 798cdf0e10cSrcweir // ----------------------------------------------------------------------- 799cdf0e10cSrcweir 800cdf0e10cSrcweir void ImplListBoxWindow::RemoveEntry( sal_uInt16 nPos ) 801cdf0e10cSrcweir { 802cdf0e10cSrcweir ImplClearLayoutData(); 803cdf0e10cSrcweir mpEntryList->RemoveEntry( nPos ); 804cdf0e10cSrcweir if( mnCurrentPos >= mpEntryList->GetEntryCount() ) 805cdf0e10cSrcweir mnCurrentPos = LISTBOX_ENTRY_NOTFOUND; 806cdf0e10cSrcweir ImplCalcMetrics(); 807cdf0e10cSrcweir } 808cdf0e10cSrcweir 809cdf0e10cSrcweir // ----------------------------------------------------------------------- 810cdf0e10cSrcweir 811cdf0e10cSrcweir void ImplListBoxWindow::SetEntryFlags( sal_uInt16 nPos, long nFlags ) 812cdf0e10cSrcweir { 813cdf0e10cSrcweir mpEntryList->SetEntryFlags( nPos, nFlags ); 814cdf0e10cSrcweir ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( nPos ); 815cdf0e10cSrcweir if( pEntry ) 816cdf0e10cSrcweir ImplUpdateEntryMetrics( *pEntry ); 817cdf0e10cSrcweir } 818cdf0e10cSrcweir 819cdf0e10cSrcweir // ----------------------------------------------------------------------- 820cdf0e10cSrcweir 821cdf0e10cSrcweir void ImplListBoxWindow::ImplShowFocusRect() 822cdf0e10cSrcweir { 823cdf0e10cSrcweir if ( mbHasFocusRect ) 824cdf0e10cSrcweir HideFocus(); 825cdf0e10cSrcweir ShowFocus( maFocusRect ); 826cdf0e10cSrcweir mbHasFocusRect = sal_True; 827cdf0e10cSrcweir } 828cdf0e10cSrcweir 829cdf0e10cSrcweir // ----------------------------------------------------------------------- 830cdf0e10cSrcweir 831cdf0e10cSrcweir void ImplListBoxWindow::ImplHideFocusRect() 832cdf0e10cSrcweir { 833cdf0e10cSrcweir if ( mbHasFocusRect ) 834cdf0e10cSrcweir { 835cdf0e10cSrcweir HideFocus(); 836cdf0e10cSrcweir mbHasFocusRect = sal_False; 837cdf0e10cSrcweir } 838cdf0e10cSrcweir } 839cdf0e10cSrcweir 840cdf0e10cSrcweir 841cdf0e10cSrcweir // ----------------------------------------------------------------------- 842cdf0e10cSrcweir 843cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetEntryPosForPoint( const Point& rPoint ) const 844cdf0e10cSrcweir { 845cdf0e10cSrcweir long nY = mnBorder; 846cdf0e10cSrcweir 847cdf0e10cSrcweir sal_uInt16 nSelect = mnTop; 848cdf0e10cSrcweir const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nSelect ); 849cdf0e10cSrcweir while( pEntry && rPoint.Y() > pEntry->mnHeight + nY ) 850cdf0e10cSrcweir { 851cdf0e10cSrcweir nY += pEntry->mnHeight; 852cdf0e10cSrcweir pEntry = mpEntryList->GetEntryPtr( ++nSelect ); 853cdf0e10cSrcweir } 854cdf0e10cSrcweir if( pEntry == NULL ) 855cdf0e10cSrcweir nSelect = LISTBOX_ENTRY_NOTFOUND; 856cdf0e10cSrcweir 857cdf0e10cSrcweir return nSelect; 858cdf0e10cSrcweir } 859cdf0e10cSrcweir 860cdf0e10cSrcweir // ----------------------------------------------------------------------- 861cdf0e10cSrcweir 862cdf0e10cSrcweir sal_Bool ImplListBoxWindow::IsVisible( sal_uInt16 i_nEntry ) const 863cdf0e10cSrcweir { 864cdf0e10cSrcweir sal_Bool bRet = sal_False; 865cdf0e10cSrcweir 866cdf0e10cSrcweir if( i_nEntry >= mnTop ) 867cdf0e10cSrcweir { 868cdf0e10cSrcweir if( mpEntryList->GetAddedHeight( i_nEntry, mnTop ) < 869cdf0e10cSrcweir PixelToLogic( GetSizePixel() ).Height() ) 870cdf0e10cSrcweir { 871cdf0e10cSrcweir bRet = sal_True; 872cdf0e10cSrcweir } 873cdf0e10cSrcweir } 874cdf0e10cSrcweir 875cdf0e10cSrcweir return bRet; 876cdf0e10cSrcweir } 877cdf0e10cSrcweir 878cdf0e10cSrcweir // ----------------------------------------------------------------------- 879cdf0e10cSrcweir 880cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetLastVisibleEntry() const 881cdf0e10cSrcweir { 882cdf0e10cSrcweir sal_uInt16 nPos = mnTop; 883cdf0e10cSrcweir long nWindowHeight = GetSizePixel().Height(); 884cdf0e10cSrcweir sal_uInt16 nCount = mpEntryList->GetEntryCount(); 885cdf0e10cSrcweir long nDiff; 886cdf0e10cSrcweir for( nDiff = 0; nDiff < nWindowHeight && nPos < nCount; nDiff = mpEntryList->GetAddedHeight( nPos, mnTop ) ) 887cdf0e10cSrcweir nPos++; 888cdf0e10cSrcweir 889cdf0e10cSrcweir if( nDiff > nWindowHeight && nPos > mnTop ) 890cdf0e10cSrcweir nPos--; 891cdf0e10cSrcweir 892cdf0e10cSrcweir if( nPos >= nCount ) 893cdf0e10cSrcweir nPos = nCount-1; 894cdf0e10cSrcweir 895cdf0e10cSrcweir return nPos; 896cdf0e10cSrcweir } 897cdf0e10cSrcweir 898cdf0e10cSrcweir // ----------------------------------------------------------------------- 899cdf0e10cSrcweir 900cdf0e10cSrcweir void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt ) 901cdf0e10cSrcweir { 902cdf0e10cSrcweir mbMouseMoveSelect = sal_False; // Nur bis zum ersten MouseButtonDown 903cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 904cdf0e10cSrcweir 905cdf0e10cSrcweir if ( !IsReadOnly() ) 906cdf0e10cSrcweir { 907cdf0e10cSrcweir if( rMEvt.GetClicks() == 1 ) 908cdf0e10cSrcweir { 909cdf0e10cSrcweir sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() ); 910cdf0e10cSrcweir if( nSelect != LISTBOX_ENTRY_NOTFOUND ) 911cdf0e10cSrcweir { 912cdf0e10cSrcweir if ( !mbMulti && GetEntryList()->GetSelectEntryCount() ) 913cdf0e10cSrcweir mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 ); 914cdf0e10cSrcweir else 915cdf0e10cSrcweir mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND; 916cdf0e10cSrcweir 917cdf0e10cSrcweir mnCurrentPos = nSelect; 918cdf0e10cSrcweir mbTrackingSelect = sal_True; 919cdf0e10cSrcweir SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() ); 920cdf0e10cSrcweir mbTrackingSelect = sal_False; 921cdf0e10cSrcweir if ( mbGrabFocus ) 922cdf0e10cSrcweir GrabFocus(); 923cdf0e10cSrcweir 924cdf0e10cSrcweir StartTracking( STARTTRACK_SCROLLREPEAT ); 925cdf0e10cSrcweir } 926cdf0e10cSrcweir } 927cdf0e10cSrcweir if( rMEvt.GetClicks() == 2 ) 928cdf0e10cSrcweir { 929cdf0e10cSrcweir maDoubleClickHdl.Call( this ); 930cdf0e10cSrcweir } 931cdf0e10cSrcweir } 932cdf0e10cSrcweir else // if ( mbGrabFocus ) 933cdf0e10cSrcweir { 934cdf0e10cSrcweir GrabFocus(); 935cdf0e10cSrcweir } 936cdf0e10cSrcweir } 937cdf0e10cSrcweir 938cdf0e10cSrcweir // ----------------------------------------------------------------------- 939cdf0e10cSrcweir 940cdf0e10cSrcweir void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt ) 941cdf0e10cSrcweir { 942cdf0e10cSrcweir if ( rMEvt.IsLeaveWindow() ) 943cdf0e10cSrcweir { 944cdf0e10cSrcweir if ( mbStackMode && IsMouseMoveSelect() && IsReallyVisible() ) 945cdf0e10cSrcweir { 946cdf0e10cSrcweir if ( rMEvt.GetPosPixel().Y() < 0 ) 947cdf0e10cSrcweir { 948cdf0e10cSrcweir DeselectAll(); 949cdf0e10cSrcweir mnCurrentPos = LISTBOX_ENTRY_NOTFOUND; 950cdf0e10cSrcweir SetTopEntry( 0 ); 951cdf0e10cSrcweir if ( mbStackMode ) // #87072#, #92323# 952cdf0e10cSrcweir { 953cdf0e10cSrcweir mbTravelSelect = sal_True; 954cdf0e10cSrcweir mnSelectModifier = rMEvt.GetModifier(); 955cdf0e10cSrcweir ImplCallSelect(); 956cdf0e10cSrcweir mbTravelSelect = sal_False; 957cdf0e10cSrcweir } 958cdf0e10cSrcweir 959cdf0e10cSrcweir } 960cdf0e10cSrcweir } 961cdf0e10cSrcweir } 962cdf0e10cSrcweir else if ( ( ( !mbMulti && IsMouseMoveSelect() ) || mbStackMode ) && mpEntryList->GetEntryCount() ) 963cdf0e10cSrcweir { 964cdf0e10cSrcweir Point aPoint; 965cdf0e10cSrcweir Rectangle aRect( aPoint, GetOutputSizePixel() ); 966cdf0e10cSrcweir if( aRect.IsInside( rMEvt.GetPosPixel() ) ) 967cdf0e10cSrcweir { 968cdf0e10cSrcweir if ( IsMouseMoveSelect() ) 969cdf0e10cSrcweir { 970cdf0e10cSrcweir sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() ); 971cdf0e10cSrcweir if( nSelect == LISTBOX_ENTRY_NOTFOUND ) 972cdf0e10cSrcweir nSelect = mpEntryList->GetEntryCount() - 1; 973cdf0e10cSrcweir nSelect = Min( nSelect, GetLastVisibleEntry() ); 974cdf0e10cSrcweir nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) ); 975cdf0e10cSrcweir // Select only visible Entries with MouseMove, otherwise Tracking... 976cdf0e10cSrcweir if ( IsVisible( nSelect ) && 977cdf0e10cSrcweir mpEntryList->IsEntrySelectable( nSelect ) && 978cdf0e10cSrcweir ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() || ( nSelect != GetEntryList()->GetSelectEntryPos( 0 ) ) ) ) 979cdf0e10cSrcweir { 980cdf0e10cSrcweir mbTrackingSelect = sal_True; 981cdf0e10cSrcweir if ( SelectEntries( nSelect, LET_TRACKING, sal_False, sal_False ) ) 982cdf0e10cSrcweir { 983cdf0e10cSrcweir if ( mbStackMode ) // #87072# 984cdf0e10cSrcweir { 985cdf0e10cSrcweir mbTravelSelect = sal_True; 986cdf0e10cSrcweir mnSelectModifier = rMEvt.GetModifier(); 987cdf0e10cSrcweir ImplCallSelect(); 988cdf0e10cSrcweir mbTravelSelect = sal_False; 989cdf0e10cSrcweir } 990cdf0e10cSrcweir } 991cdf0e10cSrcweir mbTrackingSelect = sal_False; 992cdf0e10cSrcweir } 993cdf0e10cSrcweir } 994cdf0e10cSrcweir 995cdf0e10cSrcweir // Falls der DD-Button gedrueckt wurde und jemand mit gedrueckter 996cdf0e10cSrcweir // Maustaste in die ListBox faehrt... 997cdf0e10cSrcweir if ( rMEvt.IsLeft() && !rMEvt.IsSynthetic() ) 998cdf0e10cSrcweir { 999cdf0e10cSrcweir if ( !mbMulti && GetEntryList()->GetSelectEntryCount() ) 1000cdf0e10cSrcweir mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 ); 1001cdf0e10cSrcweir else 1002cdf0e10cSrcweir mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND; 1003cdf0e10cSrcweir 1004cdf0e10cSrcweir if ( mbStackMode && ( mpEntryList->GetSelectionAnchor() == LISTBOX_ENTRY_NOTFOUND ) ) 1005cdf0e10cSrcweir mpEntryList->SetSelectionAnchor( 0 ); 1006cdf0e10cSrcweir 1007cdf0e10cSrcweir StartTracking( STARTTRACK_SCROLLREPEAT ); 1008cdf0e10cSrcweir } 1009cdf0e10cSrcweir } 1010cdf0e10cSrcweir } 1011cdf0e10cSrcweir } 1012cdf0e10cSrcweir 1013cdf0e10cSrcweir // ----------------------------------------------------------------------- 1014cdf0e10cSrcweir 1015cdf0e10cSrcweir void ImplListBoxWindow::DeselectAll() 1016cdf0e10cSrcweir { 1017cdf0e10cSrcweir while ( GetEntryList()->GetSelectEntryCount() ) 1018cdf0e10cSrcweir { 1019cdf0e10cSrcweir sal_uInt16 nS = GetEntryList()->GetSelectEntryPos( 0 ); 1020cdf0e10cSrcweir SelectEntry( nS, sal_False ); 1021cdf0e10cSrcweir } 1022cdf0e10cSrcweir } 1023cdf0e10cSrcweir 1024cdf0e10cSrcweir // ----------------------------------------------------------------------- 1025cdf0e10cSrcweir 1026cdf0e10cSrcweir void ImplListBoxWindow::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect ) 1027cdf0e10cSrcweir { 1028cdf0e10cSrcweir if( (mpEntryList->IsEntryPosSelected( nPos ) != bSelect) && mpEntryList->IsEntrySelectable( nPos ) ) 1029cdf0e10cSrcweir { 1030cdf0e10cSrcweir ImplHideFocusRect(); 1031cdf0e10cSrcweir if( bSelect ) 1032cdf0e10cSrcweir { 1033cdf0e10cSrcweir if( !mbMulti ) 1034cdf0e10cSrcweir { 1035cdf0e10cSrcweir // Selektierten Eintrag deselektieren 1036cdf0e10cSrcweir sal_uInt16 nDeselect = GetEntryList()->GetSelectEntryPos( 0 ); 1037cdf0e10cSrcweir if( nDeselect != LISTBOX_ENTRY_NOTFOUND ) 1038cdf0e10cSrcweir { 1039cdf0e10cSrcweir //SelectEntryPos( nDeselect, sal_False ); 1040cdf0e10cSrcweir GetEntryList()->SelectEntry( nDeselect, sal_False ); 1041cdf0e10cSrcweir if ( IsUpdateMode() && IsReallyVisible() ) 1042cdf0e10cSrcweir ImplPaint( nDeselect, sal_True ); 1043cdf0e10cSrcweir } 1044cdf0e10cSrcweir } 1045cdf0e10cSrcweir mpEntryList->SelectEntry( nPos, sal_True ); 1046cdf0e10cSrcweir mnCurrentPos = nPos; 1047cdf0e10cSrcweir if ( ( nPos != LISTBOX_ENTRY_NOTFOUND ) && IsUpdateMode() ) 1048cdf0e10cSrcweir { 1049cdf0e10cSrcweir ImplPaint( nPos ); 1050cdf0e10cSrcweir if ( !IsVisible( nPos ) ) 1051cdf0e10cSrcweir { 1052cdf0e10cSrcweir ImplClearLayoutData(); 1053cdf0e10cSrcweir sal_uInt16 nVisibleEntries = GetLastVisibleEntry()-mnTop; 1054cdf0e10cSrcweir if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) ) 1055cdf0e10cSrcweir { 1056cdf0e10cSrcweir Resize(); 1057cdf0e10cSrcweir ShowProminentEntry( nPos ); 1058cdf0e10cSrcweir } 1059cdf0e10cSrcweir else 1060cdf0e10cSrcweir { 1061cdf0e10cSrcweir ShowProminentEntry( nPos ); 1062cdf0e10cSrcweir } 1063cdf0e10cSrcweir } 1064cdf0e10cSrcweir } 1065cdf0e10cSrcweir } 1066cdf0e10cSrcweir else 1067cdf0e10cSrcweir { 1068cdf0e10cSrcweir mpEntryList->SelectEntry( nPos, sal_False ); 1069cdf0e10cSrcweir ImplPaint( nPos, sal_True ); 1070cdf0e10cSrcweir } 1071cdf0e10cSrcweir mbSelectionChanged = sal_True; 1072cdf0e10cSrcweir } 1073cdf0e10cSrcweir } 1074cdf0e10cSrcweir 1075cdf0e10cSrcweir // ----------------------------------------------------------------------- 1076cdf0e10cSrcweir 1077cdf0e10cSrcweir sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift, sal_Bool bCtrl ) 1078cdf0e10cSrcweir { 1079cdf0e10cSrcweir sal_Bool bFocusChanged = sal_False; 1080cdf0e10cSrcweir sal_Bool bSelectionChanged = sal_False; 1081cdf0e10cSrcweir 1082cdf0e10cSrcweir if( IsEnabled() && mpEntryList->IsEntrySelectable( nSelect ) ) 1083cdf0e10cSrcweir { 1084cdf0e10cSrcweir // Hier (Single-ListBox) kann nur ein Eintrag deselektiert werden 1085cdf0e10cSrcweir if( !mbMulti ) 1086cdf0e10cSrcweir { 1087cdf0e10cSrcweir sal_uInt16 nDeselect = mpEntryList->GetSelectEntryPos( 0 ); 1088cdf0e10cSrcweir if( nSelect != nDeselect ) 1089cdf0e10cSrcweir { 1090cdf0e10cSrcweir SelectEntry( nSelect, sal_True ); 1091cdf0e10cSrcweir mpEntryList->SetLastSelected( nSelect ); 1092cdf0e10cSrcweir bFocusChanged = sal_True; 1093cdf0e10cSrcweir bSelectionChanged = sal_True; 1094cdf0e10cSrcweir } 1095cdf0e10cSrcweir } 1096cdf0e10cSrcweir // MultiListBox ohne Modifier 1097cdf0e10cSrcweir else if( mbSimpleMode && !bCtrl && !bShift ) 1098cdf0e10cSrcweir { 1099cdf0e10cSrcweir sal_uInt16 nEntryCount = mpEntryList->GetEntryCount(); 1100cdf0e10cSrcweir for ( sal_uInt16 nPos = 0; nPos < nEntryCount; nPos++ ) 1101cdf0e10cSrcweir { 1102cdf0e10cSrcweir sal_Bool bSelect = nPos == nSelect; 1103cdf0e10cSrcweir if ( mpEntryList->IsEntryPosSelected( nPos ) != bSelect ) 1104cdf0e10cSrcweir { 1105cdf0e10cSrcweir SelectEntry( nPos, bSelect ); 1106cdf0e10cSrcweir bFocusChanged = sal_True; 1107cdf0e10cSrcweir bSelectionChanged = sal_True; 1108cdf0e10cSrcweir } 1109cdf0e10cSrcweir } 1110cdf0e10cSrcweir mpEntryList->SetLastSelected( nSelect ); 1111cdf0e10cSrcweir mpEntryList->SetSelectionAnchor( nSelect ); 1112cdf0e10cSrcweir } 1113cdf0e10cSrcweir // MultiListBox nur mit CTRL/SHIFT oder nicht im SimpleMode 1114cdf0e10cSrcweir else if( ( !mbSimpleMode /* && !bShift */ ) || ( (mbSimpleMode && ( bCtrl || bShift )) || mbStackMode ) ) 1115cdf0e10cSrcweir { 1116cdf0e10cSrcweir // Space fuer Selektionswechsel 1117cdf0e10cSrcweir if( !bShift && ( ( eLET == LET_KEYSPACE ) || ( eLET == LET_MBDOWN ) ) ) 1118cdf0e10cSrcweir { 1119cdf0e10cSrcweir sal_Bool bSelect = ( mbStackMode && IsMouseMoveSelect() ) ? sal_True : !mpEntryList->IsEntryPosSelected( nSelect ); 1120cdf0e10cSrcweir if ( mbStackMode ) 1121cdf0e10cSrcweir { 1122cdf0e10cSrcweir sal_uInt16 n; 1123cdf0e10cSrcweir if ( bSelect ) 1124cdf0e10cSrcweir { 1125cdf0e10cSrcweir // All entries before nSelect must be selected... 1126cdf0e10cSrcweir for ( n = 0; n < nSelect; n++ ) 1127cdf0e10cSrcweir SelectEntry( n, sal_True ); 1128cdf0e10cSrcweir } 1129cdf0e10cSrcweir if ( !bSelect ) 1130cdf0e10cSrcweir { 1131cdf0e10cSrcweir for ( n = nSelect+1; n < mpEntryList->GetEntryCount(); n++ ) 1132cdf0e10cSrcweir SelectEntry( n, sal_False ); 1133cdf0e10cSrcweir } 1134cdf0e10cSrcweir } 1135cdf0e10cSrcweir SelectEntry( nSelect, bSelect ); 1136cdf0e10cSrcweir mpEntryList->SetLastSelected( nSelect ); 1137cdf0e10cSrcweir mpEntryList->SetSelectionAnchor( mbStackMode ? 0 : nSelect ); 1138cdf0e10cSrcweir if ( !mpEntryList->IsEntryPosSelected( nSelect ) ) 1139cdf0e10cSrcweir mpEntryList->SetSelectionAnchor( LISTBOX_ENTRY_NOTFOUND ); 1140cdf0e10cSrcweir bFocusChanged = sal_True; 1141cdf0e10cSrcweir bSelectionChanged = sal_True; 1142cdf0e10cSrcweir } 1143cdf0e10cSrcweir else if( ( ( eLET == LET_TRACKING ) && ( nSelect != mnCurrentPos ) ) || 1144cdf0e10cSrcweir ( (bShift||mbStackMode) && ( ( eLET == LET_KEYMOVE ) || ( eLET == LET_MBDOWN ) ) ) ) 1145cdf0e10cSrcweir { 1146cdf0e10cSrcweir mnCurrentPos = nSelect; 1147cdf0e10cSrcweir bFocusChanged = sal_True; 1148cdf0e10cSrcweir 1149cdf0e10cSrcweir sal_uInt16 nAnchor = mpEntryList->GetSelectionAnchor(); 1150cdf0e10cSrcweir if( ( nAnchor == LISTBOX_ENTRY_NOTFOUND ) && ( mpEntryList->GetSelectEntryCount() || mbStackMode ) ) 1151cdf0e10cSrcweir { 1152cdf0e10cSrcweir nAnchor = mbStackMode ? 0 : mpEntryList->GetSelectEntryPos( mpEntryList->GetSelectEntryCount() - 1 ); 1153cdf0e10cSrcweir } 1154cdf0e10cSrcweir if( nAnchor != LISTBOX_ENTRY_NOTFOUND ) 1155cdf0e10cSrcweir { 1156cdf0e10cSrcweir // Alle Eintraege vom Anchor bis nSelect muessen selektiert sein 1157cdf0e10cSrcweir sal_uInt16 nStart = Min( nSelect, nAnchor ); 1158cdf0e10cSrcweir sal_uInt16 nEnd = Max( nSelect, nAnchor ); 1159cdf0e10cSrcweir for ( sal_uInt16 n = nStart; n <= nEnd; n++ ) 1160cdf0e10cSrcweir { 1161cdf0e10cSrcweir if ( !mpEntryList->IsEntryPosSelected( n ) ) 1162cdf0e10cSrcweir { 1163cdf0e10cSrcweir SelectEntry( n, sal_True ); 1164cdf0e10cSrcweir bSelectionChanged = sal_True; 1165cdf0e10cSrcweir } 1166cdf0e10cSrcweir } 1167cdf0e10cSrcweir 1168cdf0e10cSrcweir // Ggf. muss noch was deselektiert werden... 1169cdf0e10cSrcweir sal_uInt16 nLast = mpEntryList->GetLastSelected(); 1170cdf0e10cSrcweir if ( nLast != LISTBOX_ENTRY_NOTFOUND ) 1171cdf0e10cSrcweir { 1172cdf0e10cSrcweir if ( ( nLast > nSelect ) && ( nLast > nAnchor ) ) 1173cdf0e10cSrcweir { 1174cdf0e10cSrcweir for ( sal_uInt16 n = nSelect+1; n <= nLast; n++ ) 1175cdf0e10cSrcweir { 1176cdf0e10cSrcweir if ( mpEntryList->IsEntryPosSelected( n ) ) 1177cdf0e10cSrcweir { 1178cdf0e10cSrcweir SelectEntry( n, sal_False ); 1179cdf0e10cSrcweir bSelectionChanged = sal_True; 1180cdf0e10cSrcweir } 1181cdf0e10cSrcweir } 1182cdf0e10cSrcweir } 1183cdf0e10cSrcweir else if ( ( nLast < nSelect ) && ( nLast < nAnchor ) ) 1184cdf0e10cSrcweir { 1185cdf0e10cSrcweir for ( sal_uInt16 n = nLast; n < nSelect; n++ ) 1186cdf0e10cSrcweir { 1187cdf0e10cSrcweir if ( mpEntryList->IsEntryPosSelected( n ) ) 1188cdf0e10cSrcweir { 1189cdf0e10cSrcweir SelectEntry( n, sal_False ); 1190cdf0e10cSrcweir bSelectionChanged = sal_True; 1191cdf0e10cSrcweir } 1192cdf0e10cSrcweir } 1193cdf0e10cSrcweir } 1194cdf0e10cSrcweir } 1195cdf0e10cSrcweir mpEntryList->SetLastSelected( nSelect ); 1196cdf0e10cSrcweir } 1197cdf0e10cSrcweir } 1198cdf0e10cSrcweir else if( eLET != LET_TRACKING ) 1199cdf0e10cSrcweir { 1200cdf0e10cSrcweir ImplHideFocusRect(); 1201cdf0e10cSrcweir ImplPaint( nSelect, sal_True ); 1202cdf0e10cSrcweir bFocusChanged = sal_True; 1203cdf0e10cSrcweir } 1204cdf0e10cSrcweir } 1205cdf0e10cSrcweir else if( bShift ) 1206cdf0e10cSrcweir { 1207cdf0e10cSrcweir bFocusChanged = sal_True; 1208cdf0e10cSrcweir } 1209cdf0e10cSrcweir 1210cdf0e10cSrcweir if( bSelectionChanged ) 1211cdf0e10cSrcweir mbSelectionChanged = sal_True; 1212cdf0e10cSrcweir 1213cdf0e10cSrcweir if( bFocusChanged ) 1214cdf0e10cSrcweir { 1215cdf0e10cSrcweir long nHeightDiff = mpEntryList->GetAddedHeight( nSelect, mnTop, 0 ); 1216cdf0e10cSrcweir maFocusRect.SetPos( Point( 0, nHeightDiff ) ); 1217cdf0e10cSrcweir Size aSz( maFocusRect.GetWidth(), 1218cdf0e10cSrcweir mpEntryList->GetEntryHeight( nSelect ) ); 1219cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 1220cdf0e10cSrcweir if( HasFocus() ) 1221cdf0e10cSrcweir ImplShowFocusRect(); 1222cdf0e10cSrcweir } 1223cdf0e10cSrcweir ImplClearLayoutData(); 1224cdf0e10cSrcweir } 1225cdf0e10cSrcweir return bSelectionChanged; 1226cdf0e10cSrcweir } 1227cdf0e10cSrcweir 1228cdf0e10cSrcweir // ----------------------------------------------------------------------- 1229cdf0e10cSrcweir 1230cdf0e10cSrcweir void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt ) 1231cdf0e10cSrcweir { 1232cdf0e10cSrcweir Point aPoint; 1233cdf0e10cSrcweir Rectangle aRect( aPoint, GetOutputSizePixel() ); 1234cdf0e10cSrcweir sal_Bool bInside = aRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ); 1235cdf0e10cSrcweir 1236cdf0e10cSrcweir if( rTEvt.IsTrackingCanceled() || rTEvt.IsTrackingEnded() ) // MouseButtonUp 1237cdf0e10cSrcweir { 1238cdf0e10cSrcweir if ( bInside && !rTEvt.IsTrackingCanceled() ) 1239cdf0e10cSrcweir { 1240cdf0e10cSrcweir mnSelectModifier = rTEvt.GetMouseEvent().GetModifier(); 1241cdf0e10cSrcweir ImplCallSelect(); 1242cdf0e10cSrcweir } 1243cdf0e10cSrcweir else 1244cdf0e10cSrcweir { 1245cdf0e10cSrcweir maCancelHdl.Call( NULL ); 1246cdf0e10cSrcweir if ( !mbMulti ) 1247cdf0e10cSrcweir { 1248cdf0e10cSrcweir mbTrackingSelect = sal_True; 1249cdf0e10cSrcweir SelectEntry( mnTrackingSaveSelection, sal_True ); 1250cdf0e10cSrcweir mbTrackingSelect = sal_False; 1251cdf0e10cSrcweir if ( mnTrackingSaveSelection != LISTBOX_ENTRY_NOTFOUND ) 1252cdf0e10cSrcweir { 1253cdf0e10cSrcweir long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 ); 1254cdf0e10cSrcweir maFocusRect.SetPos( Point( 0, nHeightDiff ) ); 1255cdf0e10cSrcweir Size aSz( maFocusRect.GetWidth(), 1256cdf0e10cSrcweir mpEntryList->GetEntryHeight( mnCurrentPos ) ); 1257cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 1258cdf0e10cSrcweir ImplShowFocusRect(); 1259cdf0e10cSrcweir } 1260cdf0e10cSrcweir } 1261cdf0e10cSrcweir } 1262cdf0e10cSrcweir 1263cdf0e10cSrcweir mbTrack = sal_False; 1264cdf0e10cSrcweir } 1265cdf0e10cSrcweir else 1266cdf0e10cSrcweir { 1267cdf0e10cSrcweir sal_Bool bTrackOrQuickClick = mbTrack; 1268cdf0e10cSrcweir if( !mbTrack ) 1269cdf0e10cSrcweir { 1270cdf0e10cSrcweir if ( bInside ) 1271cdf0e10cSrcweir { 1272cdf0e10cSrcweir mbTrack = sal_True; 1273cdf0e10cSrcweir } 1274cdf0e10cSrcweir 1275cdf0e10cSrcweir // Folgender Fall tritt nur auf, wenn man ganz kurz die Maustaste drueckt 1276cdf0e10cSrcweir if( rTEvt.IsTrackingEnded() && mbTrack ) 1277cdf0e10cSrcweir { 1278cdf0e10cSrcweir bTrackOrQuickClick = sal_True; 1279cdf0e10cSrcweir mbTrack = sal_False; 1280cdf0e10cSrcweir } 1281cdf0e10cSrcweir } 1282cdf0e10cSrcweir 1283cdf0e10cSrcweir if( bTrackOrQuickClick ) 1284cdf0e10cSrcweir { 1285cdf0e10cSrcweir MouseEvent aMEvt = rTEvt.GetMouseEvent(); 1286cdf0e10cSrcweir Point aPt( aMEvt.GetPosPixel() ); 1287cdf0e10cSrcweir sal_Bool bShift = aMEvt.IsShift(); 1288cdf0e10cSrcweir sal_Bool bCtrl = aMEvt.IsMod1(); 1289cdf0e10cSrcweir 1290cdf0e10cSrcweir sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND; 1291cdf0e10cSrcweir if( aPt.Y() < 0 ) 1292cdf0e10cSrcweir { 1293cdf0e10cSrcweir if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND ) 1294cdf0e10cSrcweir { 1295cdf0e10cSrcweir nSelect = mnCurrentPos ? ( mnCurrentPos - 1 ) : 0; 1296cdf0e10cSrcweir if( nSelect < mnTop ) 1297cdf0e10cSrcweir SetTopEntry( mnTop-1 ); 1298cdf0e10cSrcweir } 1299cdf0e10cSrcweir } 1300cdf0e10cSrcweir else if( aPt.Y() > GetOutputSizePixel().Height() ) 1301cdf0e10cSrcweir { 1302cdf0e10cSrcweir if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND ) 1303cdf0e10cSrcweir { 1304cdf0e10cSrcweir nSelect = Min( (sal_uInt16)(mnCurrentPos+1), (sal_uInt16)(mpEntryList->GetEntryCount()-1) ); 1305cdf0e10cSrcweir if( nSelect >= GetLastVisibleEntry() ) 1306cdf0e10cSrcweir SetTopEntry( mnTop+1 ); 1307cdf0e10cSrcweir } 1308cdf0e10cSrcweir } 1309cdf0e10cSrcweir else 1310cdf0e10cSrcweir { 1311cdf0e10cSrcweir nSelect = (sal_uInt16) ( ( aPt.Y() + mnBorder ) / mnMaxHeight ) + (sal_uInt16) mnTop; 1312cdf0e10cSrcweir nSelect = Min( nSelect, GetLastVisibleEntry() ); 1313cdf0e10cSrcweir nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) ); 1314cdf0e10cSrcweir } 1315cdf0e10cSrcweir 1316cdf0e10cSrcweir if ( bInside ) 1317cdf0e10cSrcweir { 1318cdf0e10cSrcweir if ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() ) 1319cdf0e10cSrcweir { 1320cdf0e10cSrcweir mbTrackingSelect = sal_True; 1321cdf0e10cSrcweir if ( SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl ) ) 1322cdf0e10cSrcweir { 1323cdf0e10cSrcweir if ( mbStackMode ) // #87734# (#87072#) 1324cdf0e10cSrcweir { 1325cdf0e10cSrcweir mbTravelSelect = sal_True; 1326cdf0e10cSrcweir mnSelectModifier = rTEvt.GetMouseEvent().GetModifier(); 1327cdf0e10cSrcweir ImplCallSelect(); 1328cdf0e10cSrcweir mbTravelSelect = sal_False; 1329cdf0e10cSrcweir } 1330cdf0e10cSrcweir } 1331cdf0e10cSrcweir mbTrackingSelect = sal_False; 1332cdf0e10cSrcweir } 1333cdf0e10cSrcweir } 1334cdf0e10cSrcweir else 1335cdf0e10cSrcweir { 1336cdf0e10cSrcweir if ( !mbMulti && GetEntryList()->GetSelectEntryCount() ) 1337cdf0e10cSrcweir { 1338cdf0e10cSrcweir mbTrackingSelect = sal_True; 1339cdf0e10cSrcweir SelectEntry( GetEntryList()->GetSelectEntryPos( 0 ), sal_False ); 1340cdf0e10cSrcweir mbTrackingSelect = sal_False; 1341cdf0e10cSrcweir } 1342cdf0e10cSrcweir else if ( mbStackMode ) 1343cdf0e10cSrcweir { 1344cdf0e10cSrcweir if ( ( rTEvt.GetMouseEvent().GetPosPixel().X() > 0 ) && ( rTEvt.GetMouseEvent().GetPosPixel().X() < aRect.Right() ) ) 1345cdf0e10cSrcweir { 1346cdf0e10cSrcweir if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 ) || ( rTEvt.GetMouseEvent().GetPosPixel().Y() > GetOutputSizePixel().Height() ) ) 1347cdf0e10cSrcweir { 1348cdf0e10cSrcweir sal_Bool bSelectionChanged = sal_False; 1349cdf0e10cSrcweir if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 ) 1350cdf0e10cSrcweir && !mnCurrentPos ) 1351cdf0e10cSrcweir { 1352cdf0e10cSrcweir if ( mpEntryList->IsEntryPosSelected( 0 ) ) 1353cdf0e10cSrcweir { 1354cdf0e10cSrcweir SelectEntry( 0, sal_False ); 1355cdf0e10cSrcweir bSelectionChanged = sal_True; 1356cdf0e10cSrcweir nSelect = LISTBOX_ENTRY_NOTFOUND; 1357cdf0e10cSrcweir 1358cdf0e10cSrcweir } 1359cdf0e10cSrcweir } 1360cdf0e10cSrcweir else 1361cdf0e10cSrcweir { 1362cdf0e10cSrcweir mbTrackingSelect = sal_True; 1363cdf0e10cSrcweir bSelectionChanged = SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl ); 1364cdf0e10cSrcweir mbTrackingSelect = sal_False; 1365cdf0e10cSrcweir } 1366cdf0e10cSrcweir 1367cdf0e10cSrcweir if ( bSelectionChanged ) 1368cdf0e10cSrcweir { 1369cdf0e10cSrcweir mbSelectionChanged = sal_True; 1370cdf0e10cSrcweir mbTravelSelect = sal_True; 1371cdf0e10cSrcweir mnSelectModifier = rTEvt.GetMouseEvent().GetModifier(); 1372cdf0e10cSrcweir ImplCallSelect(); 1373cdf0e10cSrcweir mbTravelSelect = sal_False; 1374cdf0e10cSrcweir } 1375cdf0e10cSrcweir } 1376cdf0e10cSrcweir } 1377cdf0e10cSrcweir } 1378cdf0e10cSrcweir } 1379cdf0e10cSrcweir mnCurrentPos = nSelect; 1380cdf0e10cSrcweir if ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) 1381cdf0e10cSrcweir { 1382cdf0e10cSrcweir ImplHideFocusRect(); 1383cdf0e10cSrcweir } 1384cdf0e10cSrcweir else 1385cdf0e10cSrcweir { 1386cdf0e10cSrcweir long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 ); 1387cdf0e10cSrcweir maFocusRect.SetPos( Point( 0, nHeightDiff ) ); 1388cdf0e10cSrcweir Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) ); 1389cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 1390cdf0e10cSrcweir ImplShowFocusRect(); 1391cdf0e10cSrcweir } 1392cdf0e10cSrcweir } 1393cdf0e10cSrcweir } 1394cdf0e10cSrcweir } 1395cdf0e10cSrcweir 1396cdf0e10cSrcweir 1397cdf0e10cSrcweir // ----------------------------------------------------------------------- 1398cdf0e10cSrcweir 1399cdf0e10cSrcweir void ImplListBoxWindow::KeyInput( const KeyEvent& rKEvt ) 1400cdf0e10cSrcweir { 1401cdf0e10cSrcweir if( !ProcessKeyInput( rKEvt ) ) 1402cdf0e10cSrcweir Control::KeyInput( rKEvt ); 1403cdf0e10cSrcweir } 1404cdf0e10cSrcweir 1405cdf0e10cSrcweir // ----------------------------------------------------------------------- 1406cdf0e10cSrcweir 1407cdf0e10cSrcweir #define IMPL_SELECT_NODIRECTION 0 1408cdf0e10cSrcweir #define IMPL_SELECT_UP 1 1409cdf0e10cSrcweir #define IMPL_SELECT_DOWN 2 1410cdf0e10cSrcweir 1411cdf0e10cSrcweir sal_Bool ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) 1412cdf0e10cSrcweir { 1413cdf0e10cSrcweir // zu selektierender Eintrag 1414cdf0e10cSrcweir sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND; 1415cdf0e10cSrcweir LB_EVENT_TYPE eLET = LET_KEYMOVE; 1416cdf0e10cSrcweir 1417cdf0e10cSrcweir KeyCode aKeyCode = rKEvt.GetKeyCode(); 1418cdf0e10cSrcweir 1419cdf0e10cSrcweir sal_Bool bShift = aKeyCode.IsShift(); 1420cdf0e10cSrcweir sal_Bool bCtrl = aKeyCode.IsMod1() || aKeyCode.IsMod3(); 1421cdf0e10cSrcweir sal_Bool bMod2 = aKeyCode.IsMod2(); 1422cdf0e10cSrcweir sal_Bool bDone = sal_False; 1423cdf0e10cSrcweir 1424cdf0e10cSrcweir switch( aKeyCode.GetCode() ) 1425cdf0e10cSrcweir { 1426cdf0e10cSrcweir case KEY_UP: 1427cdf0e10cSrcweir { 1428cdf0e10cSrcweir if ( IsReadOnly() ) 1429cdf0e10cSrcweir { 1430cdf0e10cSrcweir if ( GetTopEntry() ) 1431cdf0e10cSrcweir SetTopEntry( GetTopEntry()-1 ); 1432cdf0e10cSrcweir } 1433cdf0e10cSrcweir else if ( !bMod2 ) 1434cdf0e10cSrcweir { 1435cdf0e10cSrcweir if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) 1436cdf0e10cSrcweir { 1437cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( 0, true ); 1438cdf0e10cSrcweir } 1439cdf0e10cSrcweir else if ( mnCurrentPos ) 1440cdf0e10cSrcweir { 1441cdf0e10cSrcweir // search first selectable above the current position 1442cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos - 1, false ); 1443cdf0e10cSrcweir } 1444cdf0e10cSrcweir 1445cdf0e10cSrcweir if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect < mnTop ) ) 1446cdf0e10cSrcweir SetTopEntry( mnTop-1 ); 1447cdf0e10cSrcweir 1448cdf0e10cSrcweir bDone = sal_True; 1449cdf0e10cSrcweir } 1450cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1451cdf0e10cSrcweir } 1452cdf0e10cSrcweir break; 1453cdf0e10cSrcweir 1454cdf0e10cSrcweir case KEY_DOWN: 1455cdf0e10cSrcweir { 1456cdf0e10cSrcweir if ( IsReadOnly() ) 1457cdf0e10cSrcweir { 1458cdf0e10cSrcweir SetTopEntry( GetTopEntry()+1 ); 1459cdf0e10cSrcweir } 1460cdf0e10cSrcweir else if ( !bMod2 ) 1461cdf0e10cSrcweir { 1462cdf0e10cSrcweir if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) 1463cdf0e10cSrcweir { 1464cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( 0, true ); 1465cdf0e10cSrcweir } 1466cdf0e10cSrcweir else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() ) 1467cdf0e10cSrcweir { 1468cdf0e10cSrcweir // search first selectable below the current position 1469cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos + 1, true ); 1470cdf0e10cSrcweir } 1471cdf0e10cSrcweir 1472cdf0e10cSrcweir if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= GetLastVisibleEntry() ) ) 1473cdf0e10cSrcweir SetTopEntry( mnTop+1 ); 1474cdf0e10cSrcweir 1475cdf0e10cSrcweir bDone = sal_True; 1476cdf0e10cSrcweir } 1477cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1478cdf0e10cSrcweir } 1479cdf0e10cSrcweir break; 1480cdf0e10cSrcweir 1481cdf0e10cSrcweir case KEY_PAGEUP: 1482cdf0e10cSrcweir { 1483cdf0e10cSrcweir if ( IsReadOnly() ) 1484cdf0e10cSrcweir { 1485cdf0e10cSrcweir sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1; 1486cdf0e10cSrcweir SetTopEntry( ( mnTop > nCurVis ) ? 1487cdf0e10cSrcweir (mnTop-nCurVis) : 0 ); 1488cdf0e10cSrcweir } 1489cdf0e10cSrcweir else if ( !bCtrl && !bMod2 ) 1490cdf0e10cSrcweir { 1491cdf0e10cSrcweir if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) 1492cdf0e10cSrcweir { 1493cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( 0, true ); 1494cdf0e10cSrcweir } 1495cdf0e10cSrcweir else if ( mnCurrentPos ) 1496cdf0e10cSrcweir { 1497cdf0e10cSrcweir if( mnCurrentPos == mnTop ) 1498cdf0e10cSrcweir { 1499cdf0e10cSrcweir sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1; 1500cdf0e10cSrcweir SetTopEntry( ( mnTop > nCurVis ) ? ( mnTop-nCurVis+1 ) : 0 ); 1501cdf0e10cSrcweir } 1502cdf0e10cSrcweir 1503cdf0e10cSrcweir // find first selectable starting from mnTop looking foreward 1504cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( mnTop, true ); 1505cdf0e10cSrcweir } 1506cdf0e10cSrcweir bDone = sal_True; 1507cdf0e10cSrcweir } 1508cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1509cdf0e10cSrcweir } 1510cdf0e10cSrcweir break; 1511cdf0e10cSrcweir 1512cdf0e10cSrcweir case KEY_PAGEDOWN: 1513cdf0e10cSrcweir { 1514cdf0e10cSrcweir if ( IsReadOnly() ) 1515cdf0e10cSrcweir { 1516cdf0e10cSrcweir SetTopEntry( GetLastVisibleEntry() ); 1517cdf0e10cSrcweir } 1518cdf0e10cSrcweir else if ( !bCtrl && !bMod2 ) 1519cdf0e10cSrcweir { 1520cdf0e10cSrcweir if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) 1521cdf0e10cSrcweir { 1522cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( 0, true ); 1523cdf0e10cSrcweir } 1524cdf0e10cSrcweir else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() ) 1525cdf0e10cSrcweir { 1526cdf0e10cSrcweir sal_uInt16 nCount = mpEntryList->GetEntryCount(); 1527cdf0e10cSrcweir sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop; 1528cdf0e10cSrcweir sal_uInt16 nTmp = Min( nCurVis, nCount ); 1529cdf0e10cSrcweir nTmp += mnTop - 1; 1530cdf0e10cSrcweir if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 ) 1531cdf0e10cSrcweir { 1532cdf0e10cSrcweir long nTmp2 = Min( (long)(nCount-nCurVis), (long)((long)mnTop+(long)nCurVis-1) ); 1533cdf0e10cSrcweir nTmp2 = Max( (long)0 , nTmp2 ); 1534cdf0e10cSrcweir nTmp = (sal_uInt16)(nTmp2+(nCurVis-1) ); 1535cdf0e10cSrcweir SetTopEntry( (sal_uInt16)nTmp2 ); 1536cdf0e10cSrcweir } 1537cdf0e10cSrcweir // find first selectable starting from nTmp looking backwards 1538cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( nTmp, false ); 1539cdf0e10cSrcweir } 1540cdf0e10cSrcweir bDone = sal_True; 1541cdf0e10cSrcweir } 1542cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1543cdf0e10cSrcweir } 1544cdf0e10cSrcweir break; 1545cdf0e10cSrcweir 1546cdf0e10cSrcweir case KEY_HOME: 1547cdf0e10cSrcweir { 1548cdf0e10cSrcweir if ( IsReadOnly() ) 1549cdf0e10cSrcweir { 1550cdf0e10cSrcweir SetTopEntry( 0 ); 1551cdf0e10cSrcweir } 1552cdf0e10cSrcweir else if ( !bCtrl && !bMod2 ) 1553cdf0e10cSrcweir { 1554cdf0e10cSrcweir if ( mnCurrentPos ) 1555cdf0e10cSrcweir { 1556cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND, true ); 1557cdf0e10cSrcweir if( mnTop != 0 ) 1558cdf0e10cSrcweir SetTopEntry( 0 ); 1559cdf0e10cSrcweir 1560cdf0e10cSrcweir bDone = sal_True; 1561cdf0e10cSrcweir } 1562cdf0e10cSrcweir } 1563cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1564cdf0e10cSrcweir } 1565cdf0e10cSrcweir break; 1566cdf0e10cSrcweir 1567cdf0e10cSrcweir case KEY_END: 1568cdf0e10cSrcweir { 1569cdf0e10cSrcweir if ( IsReadOnly() ) 1570cdf0e10cSrcweir { 1571cdf0e10cSrcweir SetTopEntry( 0xFFFF ); 1572cdf0e10cSrcweir } 1573cdf0e10cSrcweir else if ( !bCtrl && !bMod2 ) 1574cdf0e10cSrcweir { 1575cdf0e10cSrcweir if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) 1576cdf0e10cSrcweir { 1577cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( 0, true ); 1578cdf0e10cSrcweir } 1579cdf0e10cSrcweir else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() ) 1580cdf0e10cSrcweir { 1581cdf0e10cSrcweir sal_uInt16 nCount = mpEntryList->GetEntryCount(); 1582cdf0e10cSrcweir nSelect = mpEntryList->FindFirstSelectable( nCount - 1, false ); 1583cdf0e10cSrcweir sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop + 1; 1584cdf0e10cSrcweir if( nCount > nCurVis ) 1585cdf0e10cSrcweir SetTopEntry( nCount - nCurVis ); 1586cdf0e10cSrcweir } 1587cdf0e10cSrcweir bDone = sal_True; 1588cdf0e10cSrcweir } 1589cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1590cdf0e10cSrcweir } 1591cdf0e10cSrcweir break; 1592cdf0e10cSrcweir 1593cdf0e10cSrcweir case KEY_LEFT: 1594cdf0e10cSrcweir { 1595cdf0e10cSrcweir if ( !bCtrl && !bMod2 ) 1596cdf0e10cSrcweir { 1597cdf0e10cSrcweir ScrollHorz( -HORZ_SCROLL ); 1598cdf0e10cSrcweir bDone = sal_True; 1599cdf0e10cSrcweir } 1600cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1601cdf0e10cSrcweir } 1602cdf0e10cSrcweir break; 1603cdf0e10cSrcweir 1604cdf0e10cSrcweir case KEY_RIGHT: 1605cdf0e10cSrcweir { 1606cdf0e10cSrcweir if ( !bCtrl && !bMod2 ) 1607cdf0e10cSrcweir { 1608cdf0e10cSrcweir ScrollHorz( HORZ_SCROLL ); 1609cdf0e10cSrcweir bDone = sal_True; 1610cdf0e10cSrcweir } 1611cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1612cdf0e10cSrcweir } 1613cdf0e10cSrcweir break; 1614cdf0e10cSrcweir 1615cdf0e10cSrcweir case KEY_RETURN: 1616cdf0e10cSrcweir { 1617cdf0e10cSrcweir if ( !bMod2 && !IsReadOnly() ) 1618cdf0e10cSrcweir { 1619cdf0e10cSrcweir mnSelectModifier = rKEvt.GetKeyCode().GetModifier(); 1620cdf0e10cSrcweir ImplCallSelect(); 1621cdf0e10cSrcweir bDone = sal_False; // RETURN nicht abfangen. 1622cdf0e10cSrcweir } 1623cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1624cdf0e10cSrcweir } 1625cdf0e10cSrcweir break; 1626cdf0e10cSrcweir 1627cdf0e10cSrcweir case KEY_SPACE: 1628cdf0e10cSrcweir { 1629cdf0e10cSrcweir if ( !bMod2 && !IsReadOnly() ) 1630cdf0e10cSrcweir { 1631cdf0e10cSrcweir if( mbMulti && ( !mbSimpleMode || ( mbSimpleMode && bCtrl && !bShift ) || mbStackMode ) ) 1632cdf0e10cSrcweir { 1633cdf0e10cSrcweir nSelect = mnCurrentPos; 1634cdf0e10cSrcweir eLET = LET_KEYSPACE; 1635cdf0e10cSrcweir } 1636cdf0e10cSrcweir bDone = sal_True; 1637cdf0e10cSrcweir } 1638cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1639cdf0e10cSrcweir } 1640cdf0e10cSrcweir break; 1641cdf0e10cSrcweir 1642cdf0e10cSrcweir case KEY_A: 1643cdf0e10cSrcweir { 1644cdf0e10cSrcweir if( bCtrl && mbMulti ) 1645cdf0e10cSrcweir { 1646cdf0e10cSrcweir // paint only once 1647cdf0e10cSrcweir sal_Bool bUpdates = IsUpdateMode(); 1648cdf0e10cSrcweir SetUpdateMode( sal_False ); 1649cdf0e10cSrcweir 1650cdf0e10cSrcweir sal_uInt16 nEntryCount = mpEntryList->GetEntryCount(); 1651cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nEntryCount; i++ ) 1652cdf0e10cSrcweir SelectEntry( i, sal_True ); 1653cdf0e10cSrcweir 1654cdf0e10cSrcweir // restore update mode 1655cdf0e10cSrcweir SetUpdateMode( bUpdates ); 1656cdf0e10cSrcweir Invalidate(); 1657cdf0e10cSrcweir 1658cdf0e10cSrcweir maQuickSelectionEngine.Reset(); 1659cdf0e10cSrcweir 1660cdf0e10cSrcweir bDone = sal_True; 1661cdf0e10cSrcweir break; 1662cdf0e10cSrcweir } 1663cdf0e10cSrcweir } 1664cdf0e10cSrcweir // fall through intentional 1665cdf0e10cSrcweir default: 1666cdf0e10cSrcweir { 1667cdf0e10cSrcweir if ( !IsReadOnly() ) 1668cdf0e10cSrcweir { 1669cdf0e10cSrcweir bDone = maQuickSelectionEngine.HandleKeyEvent( rKEvt ); 1670cdf0e10cSrcweir } 1671cdf0e10cSrcweir } 1672cdf0e10cSrcweir break; 1673cdf0e10cSrcweir } 1674cdf0e10cSrcweir 1675cdf0e10cSrcweir if ( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) 1676cdf0e10cSrcweir && ( ( !mpEntryList->IsEntryPosSelected( nSelect ) ) 1677cdf0e10cSrcweir || ( eLET == LET_KEYSPACE ) 1678cdf0e10cSrcweir ) 1679cdf0e10cSrcweir ) 1680cdf0e10cSrcweir { 1681cdf0e10cSrcweir DBG_ASSERT( !mpEntryList->IsEntryPosSelected( nSelect ) || mbMulti, "ImplListBox: Selecting same Entry" ); 1682cdf0e10cSrcweir if( nSelect >= mpEntryList->GetEntryCount() ) 1683cdf0e10cSrcweir nSelect = mpEntryList->GetEntryCount()-1; 1684cdf0e10cSrcweir mnCurrentPos = nSelect; 1685cdf0e10cSrcweir if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) ) 1686cdf0e10cSrcweir { 1687cdf0e10cSrcweir mbTravelSelect = sal_True; 1688cdf0e10cSrcweir mnSelectModifier = rKEvt.GetKeyCode().GetModifier(); 1689cdf0e10cSrcweir ImplCallSelect(); 1690cdf0e10cSrcweir mbTravelSelect = sal_False; 1691cdf0e10cSrcweir } 1692cdf0e10cSrcweir } 1693cdf0e10cSrcweir 1694cdf0e10cSrcweir return bDone; 1695cdf0e10cSrcweir } 1696cdf0e10cSrcweir 1697cdf0e10cSrcweir // ----------------------------------------------------------------------- 1698cdf0e10cSrcweir namespace 1699cdf0e10cSrcweir { 1700cdf0e10cSrcweir static ::vcl::StringEntryIdentifier lcl_getEntry( const ImplEntryList& _rList, sal_uInt16 _nPos, String& _out_entryText ) 1701cdf0e10cSrcweir { 1702cdf0e10cSrcweir OSL_PRECOND( ( _nPos != LISTBOX_ENTRY_NOTFOUND ), "lcl_getEntry: invalid position!" ); 1703cdf0e10cSrcweir sal_uInt16 nEntryCount( _rList.GetEntryCount() ); 1704cdf0e10cSrcweir if ( _nPos >= nEntryCount ) 1705cdf0e10cSrcweir _nPos = 0; 1706cdf0e10cSrcweir _out_entryText = _rList.GetEntryText( _nPos ); 1707cdf0e10cSrcweir 1708cdf0e10cSrcweir // ::vcl::StringEntryIdentifier does not allow for 0 values, but our position is 0-based 1709cdf0e10cSrcweir // => normalize 1710cdf0e10cSrcweir return reinterpret_cast< ::vcl::StringEntryIdentifier >( _nPos + 1 ); 1711cdf0e10cSrcweir } 1712cdf0e10cSrcweir 1713cdf0e10cSrcweir static sal_uInt16 lcl_getEntryPos( ::vcl::StringEntryIdentifier _entry ) 1714cdf0e10cSrcweir { 1715cdf0e10cSrcweir // our pos is 0-based, but StringEntryIdentifier does not allow for a NULL 1716cdf0e10cSrcweir return static_cast< sal_uInt16 >( reinterpret_cast< sal_Int64 >( _entry ) ) - 1; 1717cdf0e10cSrcweir } 1718cdf0e10cSrcweir } 1719cdf0e10cSrcweir 1720cdf0e10cSrcweir // ----------------------------------------------------------------------- 1721cdf0e10cSrcweir ::vcl::StringEntryIdentifier ImplListBoxWindow::CurrentEntry( String& _out_entryText ) const 1722cdf0e10cSrcweir { 1723cdf0e10cSrcweir return lcl_getEntry( *GetEntryList(), ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) ? 0 : mnCurrentPos + 1, _out_entryText ); 1724cdf0e10cSrcweir } 1725cdf0e10cSrcweir 1726cdf0e10cSrcweir // ----------------------------------------------------------------------- 1727cdf0e10cSrcweir ::vcl::StringEntryIdentifier ImplListBoxWindow::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const 1728cdf0e10cSrcweir { 1729cdf0e10cSrcweir sal_uInt16 nNextPos = lcl_getEntryPos( _currentEntry ) + 1; 1730cdf0e10cSrcweir return lcl_getEntry( *GetEntryList(), nNextPos, _out_entryText ); 1731cdf0e10cSrcweir } 1732cdf0e10cSrcweir 1733cdf0e10cSrcweir // ----------------------------------------------------------------------- 1734cdf0e10cSrcweir void ImplListBoxWindow::SelectEntry( ::vcl::StringEntryIdentifier _entry ) 1735cdf0e10cSrcweir { 1736cdf0e10cSrcweir sal_uInt16 nSelect = lcl_getEntryPos( _entry ); 1737cdf0e10cSrcweir if ( mpEntryList->IsEntryPosSelected( nSelect ) ) 1738cdf0e10cSrcweir { 1739cdf0e10cSrcweir // ignore that. This method is a callback from the QuickSelectionEngine, which means the user attempted 1740cdf0e10cSrcweir // to select the given entry by typing its starting letters. No need to act. 1741cdf0e10cSrcweir return; 1742cdf0e10cSrcweir } 1743cdf0e10cSrcweir 1744cdf0e10cSrcweir // normalize 1745cdf0e10cSrcweir OSL_ENSURE( nSelect < mpEntryList->GetEntryCount(), "ImplListBoxWindow::SelectEntry: how that?" ); 1746cdf0e10cSrcweir if( nSelect >= mpEntryList->GetEntryCount() ) 1747cdf0e10cSrcweir nSelect = mpEntryList->GetEntryCount()-1; 1748cdf0e10cSrcweir 1749cdf0e10cSrcweir // make visible 1750cdf0e10cSrcweir ShowProminentEntry( nSelect ); 1751cdf0e10cSrcweir 1752cdf0e10cSrcweir // actually select 1753cdf0e10cSrcweir mnCurrentPos = nSelect; 1754cdf0e10cSrcweir if ( SelectEntries( nSelect, LET_KEYMOVE, sal_False, sal_False ) ) 1755cdf0e10cSrcweir { 1756cdf0e10cSrcweir mbTravelSelect = sal_True; 1757cdf0e10cSrcweir mnSelectModifier = 0; 1758cdf0e10cSrcweir ImplCallSelect(); 1759cdf0e10cSrcweir mbTravelSelect = sal_False; 1760cdf0e10cSrcweir } 1761cdf0e10cSrcweir } 1762cdf0e10cSrcweir 1763cdf0e10cSrcweir // ----------------------------------------------------------------------- 1764cdf0e10cSrcweir 1765cdf0e10cSrcweir void ImplListBoxWindow::ImplPaint( sal_uInt16 nPos, sal_Bool bErase, bool bLayout ) 1766cdf0e10cSrcweir { 1767cdf0e10cSrcweir const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 1768cdf0e10cSrcweir 1769cdf0e10cSrcweir const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos ); 1770cdf0e10cSrcweir if( ! pEntry ) 1771cdf0e10cSrcweir return; 1772cdf0e10cSrcweir 1773cdf0e10cSrcweir long nWidth = GetOutputSizePixel().Width(); 1774cdf0e10cSrcweir long nY = mpEntryList->GetAddedHeight( nPos, mnTop ); 1775cdf0e10cSrcweir Rectangle aRect( Point( 0, nY ), Size( nWidth, pEntry->mnHeight ) ); 1776cdf0e10cSrcweir 1777cdf0e10cSrcweir if( ! bLayout ) 1778cdf0e10cSrcweir { 1779cdf0e10cSrcweir if( mpEntryList->IsEntryPosSelected( nPos ) ) 1780cdf0e10cSrcweir { 1781cdf0e10cSrcweir SetTextColor( !IsEnabled() ? rStyleSettings.GetDisableColor() : rStyleSettings.GetHighlightTextColor() ); 1782cdf0e10cSrcweir SetFillColor( rStyleSettings.GetHighlightColor() ); 1783cdf0e10cSrcweir SetTextFillColor( rStyleSettings.GetHighlightColor() ); 1784cdf0e10cSrcweir DrawRect( aRect ); 1785cdf0e10cSrcweir } 1786cdf0e10cSrcweir else 1787cdf0e10cSrcweir { 1788cdf0e10cSrcweir ImplInitSettings( sal_False, sal_True, sal_False ); 1789cdf0e10cSrcweir if( !IsEnabled() ) 1790cdf0e10cSrcweir SetTextColor( rStyleSettings.GetDisableColor() ); 1791cdf0e10cSrcweir SetTextFillColor(); 1792cdf0e10cSrcweir if( bErase ) 1793cdf0e10cSrcweir Erase( aRect ); 1794cdf0e10cSrcweir } 1795cdf0e10cSrcweir } 1796cdf0e10cSrcweir 1797cdf0e10cSrcweir if ( IsUserDrawEnabled() ) 1798cdf0e10cSrcweir { 1799cdf0e10cSrcweir mbInUserDraw = sal_True; 1800cdf0e10cSrcweir mnUserDrawEntry = nPos; 1801cdf0e10cSrcweir aRect.Left() -= mnLeft; 1802cdf0e10cSrcweir if ( nPos < GetEntryList()->GetMRUCount() ) 1803cdf0e10cSrcweir nPos = GetEntryList()->FindEntry( GetEntryList()->GetEntryText( nPos ) ); 1804cdf0e10cSrcweir nPos = sal::static_int_cast<sal_uInt16>(nPos - GetEntryList()->GetMRUCount()); 1805cdf0e10cSrcweir UserDrawEvent aUDEvt( this, aRect, nPos, 0 ); 1806cdf0e10cSrcweir maUserDrawHdl.Call( &aUDEvt ); 1807cdf0e10cSrcweir mbInUserDraw = sal_False; 1808cdf0e10cSrcweir } 1809cdf0e10cSrcweir else 1810cdf0e10cSrcweir { 1811cdf0e10cSrcweir DrawEntry( nPos, sal_True, sal_True, sal_False, bLayout ); 1812cdf0e10cSrcweir } 1813cdf0e10cSrcweir } 1814cdf0e10cSrcweir 1815cdf0e10cSrcweir // ----------------------------------------------------------------------- 1816cdf0e10cSrcweir 1817cdf0e10cSrcweir void ImplListBoxWindow::DrawEntry( sal_uInt16 nPos, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout ) 1818cdf0e10cSrcweir { 1819cdf0e10cSrcweir const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos ); 1820cdf0e10cSrcweir if( ! pEntry ) 1821cdf0e10cSrcweir return; 1822cdf0e10cSrcweir 1823cdf0e10cSrcweir // Bei Aenderungen in dieser Methode ggf. auch ImplWin::DrawEntry() anpassen. 1824cdf0e10cSrcweir 1825cdf0e10cSrcweir if ( mbInUserDraw ) 1826cdf0e10cSrcweir nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU 1827cdf0e10cSrcweir 1828cdf0e10cSrcweir long nY = mpEntryList->GetAddedHeight( nPos, mnTop ); 1829cdf0e10cSrcweir Size aImgSz; 1830cdf0e10cSrcweir 1831cdf0e10cSrcweir if( bDrawImage && mpEntryList->HasImages() && !bLayout ) 1832cdf0e10cSrcweir { 1833cdf0e10cSrcweir Image aImage = mpEntryList->GetEntryImage( nPos ); 1834cdf0e10cSrcweir if( !!aImage ) 1835cdf0e10cSrcweir { 1836cdf0e10cSrcweir aImgSz = aImage.GetSizePixel(); 1837cdf0e10cSrcweir Point aPtImg( mnBorder - mnLeft, nY + ( ( pEntry->mnHeight - aImgSz.Height() ) / 2 ) ); 1838cdf0e10cSrcweir 1839cdf0e10cSrcweir // pb: #106948# explicit mirroring for calc 1840cdf0e10cSrcweir if ( mbMirroring ) 1841cdf0e10cSrcweir // right aligned 1842cdf0e10cSrcweir aPtImg.X() = mnMaxWidth + mnBorder - aImgSz.Width() - mnLeft; 1843cdf0e10cSrcweir 1844cdf0e10cSrcweir if ( !IsZoom() ) 1845cdf0e10cSrcweir { 1846cdf0e10cSrcweir DrawImage( aPtImg, aImage ); 1847cdf0e10cSrcweir } 1848cdf0e10cSrcweir else 1849cdf0e10cSrcweir { 1850cdf0e10cSrcweir aImgSz.Width() = CalcZoom( aImgSz.Width() ); 1851cdf0e10cSrcweir aImgSz.Height() = CalcZoom( aImgSz.Height() ); 1852cdf0e10cSrcweir DrawImage( aPtImg, aImgSz, aImage ); 1853cdf0e10cSrcweir } 1854cdf0e10cSrcweir } 1855cdf0e10cSrcweir } 1856cdf0e10cSrcweir 1857cdf0e10cSrcweir if( bDrawText ) 1858cdf0e10cSrcweir { 1859cdf0e10cSrcweir MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL; 1860cdf0e10cSrcweir String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; 1861cdf0e10cSrcweir XubString aStr( mpEntryList->GetEntryText( nPos ) ); 1862cdf0e10cSrcweir if ( aStr.Len() ) 1863cdf0e10cSrcweir { 1864cdf0e10cSrcweir long nMaxWidth = Max( static_cast< long >( mnMaxWidth ), 1865cdf0e10cSrcweir GetOutputSizePixel().Width() - 2*mnBorder ); 1866cdf0e10cSrcweir // a multiline entry should only be as wide a the window 1867cdf0e10cSrcweir if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) ) 1868cdf0e10cSrcweir nMaxWidth = GetOutputSizePixel().Width() - 2*mnBorder; 1869cdf0e10cSrcweir 1870cdf0e10cSrcweir Rectangle aTextRect( Point( mnBorder - mnLeft, nY ), 1871cdf0e10cSrcweir Size( nMaxWidth, pEntry->mnHeight ) ); 1872cdf0e10cSrcweir 1873cdf0e10cSrcweir if( !bDrawTextAtImagePos && ( mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled() ) ) 1874cdf0e10cSrcweir { 1875cdf0e10cSrcweir long nImageWidth = Max( mnMaxImgWidth, maUserItemSize.Width() ); 1876cdf0e10cSrcweir aTextRect.Left() += nImageWidth + IMG_TXT_DISTANCE; 1877cdf0e10cSrcweir } 1878cdf0e10cSrcweir 1879cdf0e10cSrcweir if( bLayout ) 1880cdf0e10cSrcweir mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() ); 1881cdf0e10cSrcweir 1882cdf0e10cSrcweir // pb: #106948# explicit mirroring for calc 1883cdf0e10cSrcweir if ( mbMirroring ) 1884cdf0e10cSrcweir { 1885cdf0e10cSrcweir // right aligned 1886cdf0e10cSrcweir aTextRect.Left() = nMaxWidth + mnBorder - GetTextWidth( aStr ) - mnLeft; 1887cdf0e10cSrcweir if ( aImgSz.Width() > 0 ) 1888cdf0e10cSrcweir aTextRect.Left() -= ( aImgSz.Width() + IMG_TXT_DISTANCE ); 1889cdf0e10cSrcweir } 1890cdf0e10cSrcweir 1891cdf0e10cSrcweir sal_uInt16 nDrawStyle = ImplGetTextStyle(); 1892cdf0e10cSrcweir if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) ) 1893cdf0e10cSrcweir nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS; 1894cdf0e10cSrcweir if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_DRAW_DISABLED) ) 1895cdf0e10cSrcweir nDrawStyle |= TEXT_DRAW_DISABLE; 1896cdf0e10cSrcweir 1897cdf0e10cSrcweir DrawText( aTextRect, aStr, nDrawStyle, pVector, pDisplayText ); 1898cdf0e10cSrcweir } 1899cdf0e10cSrcweir } 1900cdf0e10cSrcweir 1901cdf0e10cSrcweir if( !bLayout ) 1902cdf0e10cSrcweir { 1903cdf0e10cSrcweir if ( ( mnSeparatorPos != LISTBOX_ENTRY_NOTFOUND ) && 1904cdf0e10cSrcweir ( ( nPos == mnSeparatorPos ) || ( nPos == mnSeparatorPos+1 ) ) ) 1905cdf0e10cSrcweir { 1906cdf0e10cSrcweir Color aOldLineColor( GetLineColor() ); 1907cdf0e10cSrcweir SetLineColor( ( GetBackground().GetColor() != COL_LIGHTGRAY ) ? COL_LIGHTGRAY : COL_GRAY ); 1908cdf0e10cSrcweir Point aStartPos( 0, nY ); 1909cdf0e10cSrcweir if ( nPos == mnSeparatorPos ) 1910cdf0e10cSrcweir aStartPos.Y() += pEntry->mnHeight-1; 1911cdf0e10cSrcweir Point aEndPos( aStartPos ); 1912cdf0e10cSrcweir aEndPos.X() = GetOutputSizePixel().Width(); 1913cdf0e10cSrcweir DrawLine( aStartPos, aEndPos ); 1914cdf0e10cSrcweir SetLineColor( aOldLineColor ); 1915cdf0e10cSrcweir } 1916cdf0e10cSrcweir } 1917cdf0e10cSrcweir } 1918cdf0e10cSrcweir 1919cdf0e10cSrcweir // ----------------------------------------------------------------------- 1920cdf0e10cSrcweir 1921cdf0e10cSrcweir void ImplListBoxWindow::FillLayoutData() const 1922cdf0e10cSrcweir { 1923cdf0e10cSrcweir mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 1924cdf0e10cSrcweir const_cast<ImplListBoxWindow*>(this)-> 1925cdf0e10cSrcweir ImplDoPaint( Rectangle( Point( 0, 0 ), GetOutputSize() ), true ); 1926cdf0e10cSrcweir } 1927cdf0e10cSrcweir 1928cdf0e10cSrcweir // ----------------------------------------------------------------------- 1929cdf0e10cSrcweir 1930cdf0e10cSrcweir void ImplListBoxWindow::ImplDoPaint( const Rectangle& rRect, bool bLayout ) 1931cdf0e10cSrcweir { 1932cdf0e10cSrcweir sal_uInt16 nCount = mpEntryList->GetEntryCount(); 1933cdf0e10cSrcweir 1934cdf0e10cSrcweir sal_Bool bShowFocusRect = mbHasFocusRect; 1935cdf0e10cSrcweir if ( mbHasFocusRect && ! bLayout ) 1936cdf0e10cSrcweir ImplHideFocusRect(); 1937cdf0e10cSrcweir 1938cdf0e10cSrcweir long nY = 0; // + mnBorder; 1939cdf0e10cSrcweir long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder; 1940cdf0e10cSrcweir 1941cdf0e10cSrcweir for( sal_uInt16 i = (sal_uInt16)mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++ ) 1942cdf0e10cSrcweir { 1943cdf0e10cSrcweir const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( i ); 1944cdf0e10cSrcweir if( nY + pEntry->mnHeight >= rRect.Top() && 1945cdf0e10cSrcweir nY <= rRect.Bottom() + mnMaxHeight ) 1946cdf0e10cSrcweir { 1947cdf0e10cSrcweir ImplPaint( i, sal_False, bLayout ); 1948cdf0e10cSrcweir } 1949cdf0e10cSrcweir nY += pEntry->mnHeight; 1950cdf0e10cSrcweir } 1951cdf0e10cSrcweir 1952cdf0e10cSrcweir long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 ); 1953cdf0e10cSrcweir maFocusRect.SetPos( Point( 0, nHeightDiff ) ); 1954cdf0e10cSrcweir Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) ); 1955cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 1956cdf0e10cSrcweir if( HasFocus() && bShowFocusRect && !bLayout ) 1957cdf0e10cSrcweir ImplShowFocusRect(); 1958cdf0e10cSrcweir } 1959cdf0e10cSrcweir 1960cdf0e10cSrcweir // ----------------------------------------------------------------------- 1961cdf0e10cSrcweir 1962cdf0e10cSrcweir void ImplListBoxWindow::Paint( const Rectangle& rRect ) 1963cdf0e10cSrcweir { 1964cdf0e10cSrcweir ImplDoPaint( rRect ); 1965cdf0e10cSrcweir } 1966cdf0e10cSrcweir 1967cdf0e10cSrcweir // ----------------------------------------------------------------------- 1968cdf0e10cSrcweir 1969cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetDisplayLineCount() const 1970cdf0e10cSrcweir { 1971cdf0e10cSrcweir // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE 1972cdf0e10cSrcweir 1973cdf0e10cSrcweir sal_uInt16 nCount = mpEntryList->GetEntryCount(); 1974cdf0e10cSrcweir long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder; 1975cdf0e10cSrcweir sal_uInt16 nEntries = static_cast< sal_uInt16 >( ( nHeight + mnMaxHeight - 1 ) / mnMaxHeight ); 1976cdf0e10cSrcweir if( nEntries > nCount-mnTop ) 1977cdf0e10cSrcweir nEntries = nCount-mnTop; 1978cdf0e10cSrcweir 1979cdf0e10cSrcweir return nEntries; 1980cdf0e10cSrcweir } 1981cdf0e10cSrcweir 1982cdf0e10cSrcweir // ----------------------------------------------------------------------- 1983cdf0e10cSrcweir 1984cdf0e10cSrcweir void ImplListBoxWindow::Resize() 1985cdf0e10cSrcweir { 1986cdf0e10cSrcweir Control::Resize(); 1987cdf0e10cSrcweir 1988cdf0e10cSrcweir sal_Bool bShowFocusRect = mbHasFocusRect; 1989cdf0e10cSrcweir if ( bShowFocusRect ) 1990cdf0e10cSrcweir ImplHideFocusRect(); 1991cdf0e10cSrcweir 1992cdf0e10cSrcweir if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND ) 1993cdf0e10cSrcweir { 1994cdf0e10cSrcweir Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryHeight( mnCurrentPos ) ); 1995cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 1996cdf0e10cSrcweir } 1997cdf0e10cSrcweir 1998cdf0e10cSrcweir if ( bShowFocusRect ) 1999cdf0e10cSrcweir ImplShowFocusRect(); 2000cdf0e10cSrcweir 2001cdf0e10cSrcweir ImplClearLayoutData(); 2002cdf0e10cSrcweir } 2003cdf0e10cSrcweir 2004cdf0e10cSrcweir // ----------------------------------------------------------------------- 2005cdf0e10cSrcweir 2006cdf0e10cSrcweir void ImplListBoxWindow::GetFocus() 2007cdf0e10cSrcweir { 2008cdf0e10cSrcweir sal_uInt16 nPos = mnCurrentPos; 2009cdf0e10cSrcweir if ( nPos == LISTBOX_ENTRY_NOTFOUND ) 2010cdf0e10cSrcweir nPos = 0; 2011cdf0e10cSrcweir long nHeightDiff = mpEntryList->GetAddedHeight( nPos, mnTop, 0 ); 2012cdf0e10cSrcweir maFocusRect.SetPos( Point( 0, nHeightDiff ) ); 2013cdf0e10cSrcweir Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( nPos ) ); 2014cdf0e10cSrcweir maFocusRect.SetSize( aSz ); 2015cdf0e10cSrcweir ImplShowFocusRect(); 2016cdf0e10cSrcweir Control::GetFocus(); 2017cdf0e10cSrcweir } 2018cdf0e10cSrcweir 2019cdf0e10cSrcweir // ----------------------------------------------------------------------- 2020cdf0e10cSrcweir 2021cdf0e10cSrcweir void ImplListBoxWindow::LoseFocus() 2022cdf0e10cSrcweir { 2023cdf0e10cSrcweir ImplHideFocusRect(); 2024cdf0e10cSrcweir Control::LoseFocus(); 2025cdf0e10cSrcweir } 2026cdf0e10cSrcweir 2027cdf0e10cSrcweir // ----------------------------------------------------------------------- 2028cdf0e10cSrcweir 2029cdf0e10cSrcweir /* 2030cdf0e10cSrcweir void ImplListBoxWindow::RequestHelp( const HelpEvent& rHEvt ) 2031cdf0e10cSrcweir { 2032cdf0e10cSrcweir if ( rHEvt.GetMode() & HELPMODE_BALLOON ) 2033cdf0e10cSrcweir Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), String() ); 2034cdf0e10cSrcweir 2035cdf0e10cSrcweir Window::RequestHelp( rHEvt ); 2036cdf0e10cSrcweir } 2037cdf0e10cSrcweir */ 2038cdf0e10cSrcweir 2039cdf0e10cSrcweir // ----------------------------------------------------------------------- 2040cdf0e10cSrcweir 2041cdf0e10cSrcweir void ImplListBoxWindow::SetTopEntry( sal_uInt16 nTop ) 2042cdf0e10cSrcweir { 2043cdf0e10cSrcweir if( mpEntryList->GetEntryCount() == 0 ) 2044cdf0e10cSrcweir return; 2045cdf0e10cSrcweir 2046cdf0e10cSrcweir long nWHeight = PixelToLogic( GetSizePixel() ).Height(); 2047cdf0e10cSrcweir 2048cdf0e10cSrcweir sal_uInt16 nLastEntry = mpEntryList->GetEntryCount()-1; 2049cdf0e10cSrcweir if( nTop > nLastEntry ) 2050cdf0e10cSrcweir nTop = nLastEntry; 2051cdf0e10cSrcweir const ImplEntryType* pLast = mpEntryList->GetEntryPtr( nLastEntry ); 2052cdf0e10cSrcweir while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->mnHeight <= nWHeight ) 2053cdf0e10cSrcweir nTop--; 2054cdf0e10cSrcweir 2055cdf0e10cSrcweir if ( nTop != mnTop ) 2056cdf0e10cSrcweir { 2057cdf0e10cSrcweir ImplClearLayoutData(); 2058cdf0e10cSrcweir long nDiff = mpEntryList->GetAddedHeight( mnTop, nTop, 0 ); 2059cdf0e10cSrcweir Update(); 2060cdf0e10cSrcweir ImplHideFocusRect(); 2061cdf0e10cSrcweir mnTop = nTop; 2062cdf0e10cSrcweir Scroll( 0, nDiff ); 2063cdf0e10cSrcweir Update(); 2064cdf0e10cSrcweir if( HasFocus() ) 2065cdf0e10cSrcweir ImplShowFocusRect(); 2066cdf0e10cSrcweir maScrollHdl.Call( this ); 2067cdf0e10cSrcweir } 2068cdf0e10cSrcweir } 2069cdf0e10cSrcweir 2070cdf0e10cSrcweir // ----------------------------------------------------------------------- 2071cdf0e10cSrcweir 2072cdf0e10cSrcweir void ImplListBoxWindow::ShowProminentEntry( sal_uInt16 nEntryPos ) 2073cdf0e10cSrcweir { 2074cdf0e10cSrcweir if( meProminentType == PROMINENT_MIDDLE ) 2075cdf0e10cSrcweir { 2076cdf0e10cSrcweir sal_uInt16 nPos = nEntryPos; 2077cdf0e10cSrcweir long nWHeight = PixelToLogic( GetSizePixel() ).Height(); 2078cdf0e10cSrcweir while( nEntryPos > 0 && mpEntryList->GetAddedHeight( nPos+1, nEntryPos ) < nWHeight/2 ) 2079cdf0e10cSrcweir nEntryPos--; 2080cdf0e10cSrcweir } 2081cdf0e10cSrcweir SetTopEntry( nEntryPos ); 2082cdf0e10cSrcweir } 2083cdf0e10cSrcweir 2084cdf0e10cSrcweir // ----------------------------------------------------------------------- 2085cdf0e10cSrcweir 2086cdf0e10cSrcweir void ImplListBoxWindow::SetLeftIndent( long n ) 2087cdf0e10cSrcweir { 2088cdf0e10cSrcweir ScrollHorz( n - mnLeft ); 2089cdf0e10cSrcweir } 2090cdf0e10cSrcweir 2091cdf0e10cSrcweir // ----------------------------------------------------------------------- 2092cdf0e10cSrcweir 2093cdf0e10cSrcweir void ImplListBoxWindow::ScrollHorz( long n ) 2094cdf0e10cSrcweir { 2095cdf0e10cSrcweir long nDiff = 0; 2096cdf0e10cSrcweir if ( n > 0 ) 2097cdf0e10cSrcweir { 2098cdf0e10cSrcweir long nWidth = GetOutputSizePixel().Width(); 2099cdf0e10cSrcweir if( ( mnMaxWidth - mnLeft + n ) > nWidth ) 2100cdf0e10cSrcweir nDiff = n; 2101cdf0e10cSrcweir } 2102cdf0e10cSrcweir else if ( n < 0 ) 2103cdf0e10cSrcweir { 2104cdf0e10cSrcweir if( mnLeft ) 2105cdf0e10cSrcweir { 2106cdf0e10cSrcweir long nAbs = -n; 2107cdf0e10cSrcweir nDiff = - ( ( mnLeft > nAbs ) ? nAbs : mnLeft ); 2108cdf0e10cSrcweir } 2109cdf0e10cSrcweir } 2110cdf0e10cSrcweir 2111cdf0e10cSrcweir if ( nDiff ) 2112cdf0e10cSrcweir { 2113cdf0e10cSrcweir ImplClearLayoutData(); 2114cdf0e10cSrcweir mnLeft = sal::static_int_cast<sal_uInt16>(mnLeft + nDiff); 2115cdf0e10cSrcweir Update(); 2116cdf0e10cSrcweir ImplHideFocusRect(); 2117cdf0e10cSrcweir Scroll( -nDiff, 0 ); 2118cdf0e10cSrcweir Update(); 2119cdf0e10cSrcweir if( HasFocus() ) 2120cdf0e10cSrcweir ImplShowFocusRect(); 2121cdf0e10cSrcweir maScrollHdl.Call( this ); 2122cdf0e10cSrcweir } 2123cdf0e10cSrcweir } 2124cdf0e10cSrcweir 2125cdf0e10cSrcweir // ----------------------------------------------------------------------- 2126cdf0e10cSrcweir 2127cdf0e10cSrcweir Size ImplListBoxWindow::CalcSize( sal_uInt16 nMaxLines ) const 2128cdf0e10cSrcweir { 2129cdf0e10cSrcweir // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE 2130cdf0e10cSrcweir 2131cdf0e10cSrcweir Size aSz; 2132cdf0e10cSrcweir // sal_uInt16 nL = Min( nMaxLines, mpEntryList->GetEntryCount() ); 2133cdf0e10cSrcweir aSz.Height() = nMaxLines * mnMaxHeight; 2134cdf0e10cSrcweir aSz.Width() = mnMaxWidth + 2*mnBorder; 2135cdf0e10cSrcweir return aSz; 2136cdf0e10cSrcweir } 2137cdf0e10cSrcweir 2138cdf0e10cSrcweir // ----------------------------------------------------------------------- 2139cdf0e10cSrcweir 2140cdf0e10cSrcweir Rectangle ImplListBoxWindow::GetBoundingRectangle( sal_uInt16 nItem ) const 2141cdf0e10cSrcweir { 2142cdf0e10cSrcweir const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem ); 2143cdf0e10cSrcweir Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() ); 2144cdf0e10cSrcweir long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) - mpEntryList->GetAddedHeight( GetTopEntry() ); 2145cdf0e10cSrcweir Rectangle aRect( Point( 0, nY ), aSz ); 2146cdf0e10cSrcweir return aRect; 2147cdf0e10cSrcweir } 2148cdf0e10cSrcweir 2149cdf0e10cSrcweir 2150cdf0e10cSrcweir // ----------------------------------------------------------------------- 2151cdf0e10cSrcweir 2152cdf0e10cSrcweir void ImplListBoxWindow::StateChanged( StateChangedType nType ) 2153cdf0e10cSrcweir { 2154cdf0e10cSrcweir Control::StateChanged( nType ); 2155cdf0e10cSrcweir 2156cdf0e10cSrcweir if ( nType == STATE_CHANGE_ZOOM ) 2157cdf0e10cSrcweir { 2158cdf0e10cSrcweir ImplInitSettings( sal_True, sal_False, sal_False ); 2159cdf0e10cSrcweir ImplCalcMetrics(); 2160cdf0e10cSrcweir Invalidate(); 2161cdf0e10cSrcweir } 2162cdf0e10cSrcweir else if ( nType == STATE_CHANGE_UPDATEMODE ) 2163cdf0e10cSrcweir { 2164cdf0e10cSrcweir if ( IsUpdateMode() && IsReallyVisible() ) 2165cdf0e10cSrcweir Invalidate(); 2166cdf0e10cSrcweir } 2167cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLFONT ) 2168cdf0e10cSrcweir { 2169cdf0e10cSrcweir ImplInitSettings( sal_True, sal_False, sal_False ); 2170cdf0e10cSrcweir ImplCalcMetrics(); 2171cdf0e10cSrcweir Invalidate(); 2172cdf0e10cSrcweir } 2173cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 2174cdf0e10cSrcweir { 2175cdf0e10cSrcweir ImplInitSettings( sal_False, sal_True, sal_False ); 2176cdf0e10cSrcweir Invalidate(); 2177cdf0e10cSrcweir } 2178cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 2179cdf0e10cSrcweir { 2180cdf0e10cSrcweir ImplInitSettings( sal_False, sal_False, sal_True ); 2181cdf0e10cSrcweir Invalidate(); 2182cdf0e10cSrcweir } 2183cdf0e10cSrcweir ImplClearLayoutData(); 2184cdf0e10cSrcweir } 2185cdf0e10cSrcweir 2186cdf0e10cSrcweir // ----------------------------------------------------------------------- 2187cdf0e10cSrcweir 2188cdf0e10cSrcweir void ImplListBoxWindow::DataChanged( const DataChangedEvent& rDCEvt ) 2189cdf0e10cSrcweir { 2190cdf0e10cSrcweir Control::DataChanged( rDCEvt ); 2191cdf0e10cSrcweir 2192cdf0e10cSrcweir if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 2193cdf0e10cSrcweir (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 2194cdf0e10cSrcweir ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 2195cdf0e10cSrcweir (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 2196cdf0e10cSrcweir { 2197cdf0e10cSrcweir ImplClearLayoutData(); 2198cdf0e10cSrcweir ImplInitSettings( sal_True, sal_True, sal_True ); 2199cdf0e10cSrcweir ImplCalcMetrics(); 2200cdf0e10cSrcweir Invalidate(); 2201cdf0e10cSrcweir } 2202cdf0e10cSrcweir } 2203cdf0e10cSrcweir 2204cdf0e10cSrcweir // ----------------------------------------------------------------------- 2205cdf0e10cSrcweir 2206cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::ImplGetTextStyle() const 2207cdf0e10cSrcweir { 2208cdf0e10cSrcweir sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER; 2209cdf0e10cSrcweir 2210cdf0e10cSrcweir if ( mpEntryList->HasImages() ) 2211cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_LEFT; 2212cdf0e10cSrcweir else if ( mbCenter ) 2213cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_CENTER; 2214cdf0e10cSrcweir else if ( mbRight ) 2215cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_RIGHT; 2216cdf0e10cSrcweir else 2217cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_LEFT; 2218cdf0e10cSrcweir 2219cdf0e10cSrcweir return nTextStyle; 2220cdf0e10cSrcweir } 2221cdf0e10cSrcweir 2222cdf0e10cSrcweir // ======================================================================= 2223cdf0e10cSrcweir 2224cdf0e10cSrcweir ImplListBox::ImplListBox( Window* pParent, WinBits nWinStyle ) : 2225cdf0e10cSrcweir Control( pParent, nWinStyle ), 2226cdf0e10cSrcweir maLBWindow( this, nWinStyle&(~WB_BORDER) ) 2227cdf0e10cSrcweir { 2228cdf0e10cSrcweir // for native widget rendering we must be able to detect this window type 2229cdf0e10cSrcweir SetType( WINDOW_LISTBOXWINDOW ); 2230cdf0e10cSrcweir 2231cdf0e10cSrcweir mpVScrollBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG ); 2232cdf0e10cSrcweir mpHScrollBar = new ScrollBar( this, WB_HSCROLL | WB_DRAG ); 2233cdf0e10cSrcweir mpScrollBarBox = new ScrollBarBox( this ); 2234cdf0e10cSrcweir 2235cdf0e10cSrcweir Link aLink( LINK( this, ImplListBox, ScrollBarHdl ) ); 2236cdf0e10cSrcweir mpVScrollBar->SetScrollHdl( aLink ); 2237cdf0e10cSrcweir mpHScrollBar->SetScrollHdl( aLink ); 2238cdf0e10cSrcweir 2239cdf0e10cSrcweir mbVScroll = sal_False; 2240cdf0e10cSrcweir mbHScroll = sal_False; 2241cdf0e10cSrcweir mbAutoHScroll = ( nWinStyle & WB_AUTOHSCROLL ) ? sal_True : sal_False; 2242cdf0e10cSrcweir 2243cdf0e10cSrcweir maLBWindow.SetScrollHdl( LINK( this, ImplListBox, LBWindowScrolled ) ); 2244cdf0e10cSrcweir maLBWindow.SetMRUChangedHdl( LINK( this, ImplListBox, MRUChanged ) ); 2245cdf0e10cSrcweir maLBWindow.Show(); 2246cdf0e10cSrcweir } 2247cdf0e10cSrcweir 2248cdf0e10cSrcweir // ----------------------------------------------------------------------- 2249cdf0e10cSrcweir 2250cdf0e10cSrcweir ImplListBox::~ImplListBox() 2251cdf0e10cSrcweir { 2252cdf0e10cSrcweir delete mpHScrollBar; 2253cdf0e10cSrcweir delete mpVScrollBar; 2254cdf0e10cSrcweir delete mpScrollBarBox; 2255cdf0e10cSrcweir } 2256cdf0e10cSrcweir 2257cdf0e10cSrcweir // ----------------------------------------------------------------------- 2258cdf0e10cSrcweir 2259cdf0e10cSrcweir void ImplListBox::Clear() 2260cdf0e10cSrcweir { 2261cdf0e10cSrcweir maLBWindow.Clear(); 2262cdf0e10cSrcweir if ( GetEntryList()->GetMRUCount() ) 2263cdf0e10cSrcweir { 2264cdf0e10cSrcweir maLBWindow.GetEntryList()->SetMRUCount( 0 ); 2265cdf0e10cSrcweir maLBWindow.SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND ); 2266cdf0e10cSrcweir } 2267cdf0e10cSrcweir mpVScrollBar->SetThumbPos( 0 ); 2268cdf0e10cSrcweir mpHScrollBar->SetThumbPos( 0 ); 2269cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2270cdf0e10cSrcweir } 2271cdf0e10cSrcweir 2272cdf0e10cSrcweir // ----------------------------------------------------------------------- 2273cdf0e10cSrcweir 2274cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr ) 2275cdf0e10cSrcweir { 2276cdf0e10cSrcweir ImplEntryType* pNewEntry = new ImplEntryType( rStr ); 2277cdf0e10cSrcweir sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry ); 2278cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2279cdf0e10cSrcweir return nNewPos; 2280cdf0e10cSrcweir } 2281cdf0e10cSrcweir 2282cdf0e10cSrcweir // ----------------------------------------------------------------------- 2283cdf0e10cSrcweir 2284cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const Image& rImage ) 2285cdf0e10cSrcweir { 2286cdf0e10cSrcweir ImplEntryType* pNewEntry = new ImplEntryType( rImage ); 2287cdf0e10cSrcweir sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry ); 2288cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2289cdf0e10cSrcweir return nNewPos; 2290cdf0e10cSrcweir } 2291cdf0e10cSrcweir 2292cdf0e10cSrcweir // ----------------------------------------------------------------------- 2293cdf0e10cSrcweir 2294cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr, const Image& rImage ) 2295cdf0e10cSrcweir { 2296cdf0e10cSrcweir ImplEntryType* pNewEntry = new ImplEntryType( rStr, rImage ); 2297cdf0e10cSrcweir sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry ); 2298cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2299cdf0e10cSrcweir return nNewPos; 2300cdf0e10cSrcweir } 2301cdf0e10cSrcweir 2302cdf0e10cSrcweir // ----------------------------------------------------------------------- 2303cdf0e10cSrcweir 2304cdf0e10cSrcweir void ImplListBox::RemoveEntry( sal_uInt16 nPos ) 2305cdf0e10cSrcweir { 2306cdf0e10cSrcweir maLBWindow.RemoveEntry( nPos ); 2307cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2308cdf0e10cSrcweir } 2309cdf0e10cSrcweir 2310cdf0e10cSrcweir // ----------------------------------------------------------------------- 2311cdf0e10cSrcweir 2312cdf0e10cSrcweir void ImplListBox::SetEntryFlags( sal_uInt16 nPos, long nFlags ) 2313cdf0e10cSrcweir { 2314cdf0e10cSrcweir maLBWindow.SetEntryFlags( nPos, nFlags ); 2315cdf0e10cSrcweir } 2316cdf0e10cSrcweir 2317cdf0e10cSrcweir // ----------------------------------------------------------------------- 2318cdf0e10cSrcweir 2319cdf0e10cSrcweir long ImplListBox::GetEntryFlags( sal_uInt16 nPos ) const 2320cdf0e10cSrcweir { 2321cdf0e10cSrcweir return maLBWindow.GetEntryList()->GetEntryFlags( nPos ); 2322cdf0e10cSrcweir } 2323cdf0e10cSrcweir 2324cdf0e10cSrcweir // ----------------------------------------------------------------------- 2325cdf0e10cSrcweir 2326cdf0e10cSrcweir void ImplListBox::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect ) 2327cdf0e10cSrcweir { 2328cdf0e10cSrcweir maLBWindow.SelectEntry( nPos, bSelect ); 2329cdf0e10cSrcweir } 2330cdf0e10cSrcweir 2331cdf0e10cSrcweir // ----------------------------------------------------------------------- 2332cdf0e10cSrcweir 2333cdf0e10cSrcweir void ImplListBox::SetNoSelection() 2334cdf0e10cSrcweir { 2335cdf0e10cSrcweir maLBWindow.DeselectAll(); 2336cdf0e10cSrcweir } 2337cdf0e10cSrcweir 2338cdf0e10cSrcweir // ----------------------------------------------------------------------- 2339cdf0e10cSrcweir 2340cdf0e10cSrcweir void ImplListBox::GetFocus() 2341cdf0e10cSrcweir { 2342cdf0e10cSrcweir maLBWindow.GrabFocus(); 2343cdf0e10cSrcweir } 2344cdf0e10cSrcweir 2345cdf0e10cSrcweir // ----------------------------------------------------------------------- 2346cdf0e10cSrcweir 2347cdf0e10cSrcweir Window* ImplListBox::GetPreferredKeyInputWindow() 2348cdf0e10cSrcweir { 2349cdf0e10cSrcweir return &maLBWindow; 2350cdf0e10cSrcweir } 2351cdf0e10cSrcweir 2352cdf0e10cSrcweir // ----------------------------------------------------------------------- 2353cdf0e10cSrcweir 2354cdf0e10cSrcweir void ImplListBox::Resize() 2355cdf0e10cSrcweir { 2356cdf0e10cSrcweir Control::Resize(); 2357cdf0e10cSrcweir ImplResizeControls(); 2358cdf0e10cSrcweir ImplCheckScrollBars(); 2359cdf0e10cSrcweir } 2360cdf0e10cSrcweir 2361cdf0e10cSrcweir 2362cdf0e10cSrcweir // ----------------------------------------------------------------------- 2363cdf0e10cSrcweir 2364cdf0e10cSrcweir IMPL_LINK( ImplListBox, MRUChanged, void*, EMPTYARG ) 2365cdf0e10cSrcweir { 2366cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2367cdf0e10cSrcweir return 1; 2368cdf0e10cSrcweir } 2369cdf0e10cSrcweir 2370cdf0e10cSrcweir // ----------------------------------------------------------------------- 2371cdf0e10cSrcweir 2372cdf0e10cSrcweir IMPL_LINK( ImplListBox, LBWindowScrolled, void*, EMPTYARG ) 2373cdf0e10cSrcweir { 2374cdf0e10cSrcweir long nSet = GetTopEntry(); 2375cdf0e10cSrcweir if( nSet > mpVScrollBar->GetRangeMax() ) 2376cdf0e10cSrcweir mpVScrollBar->SetRangeMax( GetEntryList()->GetEntryCount() ); 2377cdf0e10cSrcweir mpVScrollBar->SetThumbPos( GetTopEntry() ); 2378cdf0e10cSrcweir 2379cdf0e10cSrcweir mpHScrollBar->SetThumbPos( GetLeftIndent() ); 2380cdf0e10cSrcweir 2381cdf0e10cSrcweir maScrollHdl.Call( this ); 2382cdf0e10cSrcweir 2383cdf0e10cSrcweir return 1; 2384cdf0e10cSrcweir } 2385cdf0e10cSrcweir 2386cdf0e10cSrcweir // ----------------------------------------------------------------------- 2387cdf0e10cSrcweir 2388cdf0e10cSrcweir IMPL_LINK( ImplListBox, ScrollBarHdl, ScrollBar*, pSB ) 2389cdf0e10cSrcweir { 2390cdf0e10cSrcweir sal_uInt16 nPos = (sal_uInt16) pSB->GetThumbPos(); 2391cdf0e10cSrcweir if( pSB == mpVScrollBar ) 2392cdf0e10cSrcweir SetTopEntry( nPos ); 2393cdf0e10cSrcweir else if( pSB == mpHScrollBar ) 2394cdf0e10cSrcweir SetLeftIndent( nPos ); 2395cdf0e10cSrcweir 2396cdf0e10cSrcweir return 1; 2397cdf0e10cSrcweir } 2398cdf0e10cSrcweir 2399cdf0e10cSrcweir // ----------------------------------------------------------------------- 2400cdf0e10cSrcweir 2401cdf0e10cSrcweir void ImplListBox::ImplCheckScrollBars() 2402cdf0e10cSrcweir { 2403cdf0e10cSrcweir sal_Bool bArrange = sal_False; 2404cdf0e10cSrcweir 2405cdf0e10cSrcweir Size aOutSz = GetOutputSizePixel(); 2406cdf0e10cSrcweir sal_uInt16 nEntries = GetEntryList()->GetEntryCount(); 2407cdf0e10cSrcweir sal_uInt16 nMaxVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight()); 2408cdf0e10cSrcweir 2409cdf0e10cSrcweir // vert. ScrollBar 2410cdf0e10cSrcweir if( nEntries > nMaxVisEntries ) 2411cdf0e10cSrcweir { 2412cdf0e10cSrcweir if( !mbVScroll ) 2413cdf0e10cSrcweir bArrange = sal_True; 2414cdf0e10cSrcweir mbVScroll = sal_True; 2415cdf0e10cSrcweir 2416cdf0e10cSrcweir // Ueberpruefung des rausgescrollten Bereichs 2417cdf0e10cSrcweir if( GetEntryList()->GetSelectEntryCount() == 1 && 2418cdf0e10cSrcweir GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND ) 2419cdf0e10cSrcweir ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) ); 2420cdf0e10cSrcweir else 2421cdf0e10cSrcweir SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft... 2422cdf0e10cSrcweir } 2423cdf0e10cSrcweir else 2424cdf0e10cSrcweir { 2425cdf0e10cSrcweir if( mbVScroll ) 2426cdf0e10cSrcweir bArrange = sal_True; 2427cdf0e10cSrcweir mbVScroll = sal_False; 2428cdf0e10cSrcweir SetTopEntry( 0 ); 2429cdf0e10cSrcweir } 2430cdf0e10cSrcweir 2431cdf0e10cSrcweir // horz. ScrollBar 2432cdf0e10cSrcweir if( mbAutoHScroll ) 2433cdf0e10cSrcweir { 2434cdf0e10cSrcweir long nWidth = (sal_uInt16) aOutSz.Width(); 2435cdf0e10cSrcweir if ( mbVScroll ) 2436cdf0e10cSrcweir nWidth -= mpVScrollBar->GetSizePixel().Width(); 2437cdf0e10cSrcweir 2438cdf0e10cSrcweir long nMaxWidth = GetMaxEntryWidth(); 2439cdf0e10cSrcweir if( nWidth < nMaxWidth ) 2440cdf0e10cSrcweir { 2441cdf0e10cSrcweir if( !mbHScroll ) 2442cdf0e10cSrcweir bArrange = sal_True; 2443cdf0e10cSrcweir mbHScroll = sal_True; 2444cdf0e10cSrcweir 2445cdf0e10cSrcweir if ( !mbVScroll ) // ggf. brauchen wir jetzt doch einen 2446cdf0e10cSrcweir { 2447cdf0e10cSrcweir nMaxVisEntries = (sal_uInt16) ( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeight() ); 2448cdf0e10cSrcweir if( nEntries > nMaxVisEntries ) 2449cdf0e10cSrcweir { 2450cdf0e10cSrcweir bArrange = sal_True; 2451cdf0e10cSrcweir mbVScroll = sal_True; 2452cdf0e10cSrcweir 2453cdf0e10cSrcweir // Ueberpruefung des rausgescrollten Bereichs 2454cdf0e10cSrcweir if( GetEntryList()->GetSelectEntryCount() == 1 && 2455cdf0e10cSrcweir GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND ) 2456cdf0e10cSrcweir ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) ); 2457cdf0e10cSrcweir else 2458cdf0e10cSrcweir SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft... 2459cdf0e10cSrcweir } 2460cdf0e10cSrcweir } 2461cdf0e10cSrcweir 2462cdf0e10cSrcweir // Ueberpruefung des rausgescrollten Bereichs 2463cdf0e10cSrcweir sal_uInt16 nMaxLI = (sal_uInt16) (nMaxWidth - nWidth); 2464cdf0e10cSrcweir if ( nMaxLI < GetLeftIndent() ) 2465cdf0e10cSrcweir SetLeftIndent( nMaxLI ); 2466cdf0e10cSrcweir } 2467cdf0e10cSrcweir else 2468cdf0e10cSrcweir { 2469cdf0e10cSrcweir if( mbHScroll ) 2470cdf0e10cSrcweir bArrange = sal_True; 2471cdf0e10cSrcweir mbHScroll = sal_False; 2472cdf0e10cSrcweir SetLeftIndent( 0 ); 2473cdf0e10cSrcweir } 2474cdf0e10cSrcweir } 2475cdf0e10cSrcweir 2476cdf0e10cSrcweir if( bArrange ) 2477cdf0e10cSrcweir ImplResizeControls(); 2478cdf0e10cSrcweir 2479cdf0e10cSrcweir ImplInitScrollBars(); 2480cdf0e10cSrcweir } 2481cdf0e10cSrcweir 2482cdf0e10cSrcweir // ----------------------------------------------------------------------- 2483cdf0e10cSrcweir 2484cdf0e10cSrcweir void ImplListBox::ImplInitScrollBars() 2485cdf0e10cSrcweir { 2486cdf0e10cSrcweir Size aOutSz = maLBWindow.GetOutputSizePixel(); 2487cdf0e10cSrcweir 2488cdf0e10cSrcweir if ( mbVScroll ) 2489cdf0e10cSrcweir { 2490cdf0e10cSrcweir sal_uInt16 nEntries = GetEntryList()->GetEntryCount(); 2491cdf0e10cSrcweir sal_uInt16 nVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight()); 2492cdf0e10cSrcweir mpVScrollBar->SetRangeMax( nEntries ); 2493cdf0e10cSrcweir mpVScrollBar->SetVisibleSize( nVisEntries ); 2494cdf0e10cSrcweir mpVScrollBar->SetPageSize( nVisEntries - 1 ); 2495cdf0e10cSrcweir } 2496cdf0e10cSrcweir 2497cdf0e10cSrcweir if ( mbHScroll ) 2498cdf0e10cSrcweir { 2499cdf0e10cSrcweir mpHScrollBar->SetRangeMax( GetMaxEntryWidth() + HORZ_SCROLL ); 2500cdf0e10cSrcweir mpHScrollBar->SetVisibleSize( (sal_uInt16)aOutSz.Width() ); 2501cdf0e10cSrcweir mpHScrollBar->SetLineSize( HORZ_SCROLL ); 2502cdf0e10cSrcweir mpHScrollBar->SetPageSize( aOutSz.Width() - HORZ_SCROLL ); 2503cdf0e10cSrcweir } 2504cdf0e10cSrcweir } 2505cdf0e10cSrcweir 2506cdf0e10cSrcweir // ----------------------------------------------------------------------- 2507cdf0e10cSrcweir 2508cdf0e10cSrcweir void ImplListBox::ImplResizeControls() 2509cdf0e10cSrcweir { 2510cdf0e10cSrcweir // Hier werden die Controls nur angeordnet, ob die Scrollbars 2511cdf0e10cSrcweir // sichtbar sein sollen wird bereits in ImplCheckScrollBars ermittelt. 2512cdf0e10cSrcweir 2513cdf0e10cSrcweir Size aOutSz = GetOutputSizePixel(); 2514cdf0e10cSrcweir long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize(); 2515cdf0e10cSrcweir nSBWidth = CalcZoom( nSBWidth ); 2516cdf0e10cSrcweir 2517cdf0e10cSrcweir Size aInnerSz( aOutSz ); 2518cdf0e10cSrcweir if ( mbVScroll ) 2519cdf0e10cSrcweir aInnerSz.Width() -= nSBWidth; 2520cdf0e10cSrcweir if ( mbHScroll ) 2521cdf0e10cSrcweir aInnerSz.Height() -= nSBWidth; 2522cdf0e10cSrcweir 2523cdf0e10cSrcweir // pb: #106948# explicit mirroring for calc 2524cdf0e10cSrcweir // Scrollbar on left or right side? 2525cdf0e10cSrcweir sal_Bool bMirroring = maLBWindow.IsMirroring(); 2526cdf0e10cSrcweir Point aWinPos( bMirroring && mbVScroll ? nSBWidth : 0, 0 ); 2527cdf0e10cSrcweir maLBWindow.SetPosSizePixel( aWinPos, aInnerSz ); 2528cdf0e10cSrcweir 2529cdf0e10cSrcweir // ScrollBarBox 2530cdf0e10cSrcweir if( mbVScroll && mbHScroll ) 2531cdf0e10cSrcweir { 2532cdf0e10cSrcweir Point aBoxPos( bMirroring ? 0 : aInnerSz.Width(), aInnerSz.Height() ); 2533cdf0e10cSrcweir mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) ); 2534cdf0e10cSrcweir mpScrollBarBox->Show(); 2535cdf0e10cSrcweir } 2536cdf0e10cSrcweir else 2537cdf0e10cSrcweir { 2538cdf0e10cSrcweir mpScrollBarBox->Hide(); 2539cdf0e10cSrcweir } 2540cdf0e10cSrcweir 2541cdf0e10cSrcweir // vert. ScrollBar 2542cdf0e10cSrcweir if( mbVScroll ) 2543cdf0e10cSrcweir { 2544cdf0e10cSrcweir // Scrollbar on left or right side? 2545cdf0e10cSrcweir Point aVPos( bMirroring ? 0 : aOutSz.Width() - nSBWidth, 0 ); 2546cdf0e10cSrcweir mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, aInnerSz.Height() ) ); 2547cdf0e10cSrcweir mpVScrollBar->Show(); 2548cdf0e10cSrcweir } 2549cdf0e10cSrcweir else 2550cdf0e10cSrcweir { 2551cdf0e10cSrcweir mpVScrollBar->Hide(); 2552cdf0e10cSrcweir // #107254# Don't reset top entry after resize, but check for max top entry 2553cdf0e10cSrcweir SetTopEntry( GetTopEntry() ); 2554cdf0e10cSrcweir } 2555cdf0e10cSrcweir 2556cdf0e10cSrcweir // horz. ScrollBar 2557cdf0e10cSrcweir if( mbHScroll ) 2558cdf0e10cSrcweir { 2559cdf0e10cSrcweir Point aHPos( ( bMirroring && mbVScroll ) ? nSBWidth : 0, aOutSz.Height() - nSBWidth ); 2560cdf0e10cSrcweir mpHScrollBar->SetPosSizePixel( aHPos, Size( aInnerSz.Width(), nSBWidth ) ); 2561cdf0e10cSrcweir mpHScrollBar->Show(); 2562cdf0e10cSrcweir } 2563cdf0e10cSrcweir else 2564cdf0e10cSrcweir { 2565cdf0e10cSrcweir mpHScrollBar->Hide(); 2566cdf0e10cSrcweir SetLeftIndent( 0 ); 2567cdf0e10cSrcweir } 2568cdf0e10cSrcweir } 2569cdf0e10cSrcweir 2570cdf0e10cSrcweir // ----------------------------------------------------------------------- 2571cdf0e10cSrcweir 2572cdf0e10cSrcweir void ImplListBox::StateChanged( StateChangedType nType ) 2573cdf0e10cSrcweir { 2574cdf0e10cSrcweir if ( nType == STATE_CHANGE_INITSHOW ) 2575cdf0e10cSrcweir { 2576cdf0e10cSrcweir ImplCheckScrollBars(); 2577cdf0e10cSrcweir } 2578cdf0e10cSrcweir else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) ) 2579cdf0e10cSrcweir { 2580cdf0e10cSrcweir sal_Bool bUpdate = IsUpdateMode(); 2581cdf0e10cSrcweir maLBWindow.SetUpdateMode( bUpdate ); 2582cdf0e10cSrcweir // mpHScrollBar->SetUpdateMode( bUpdate ); 2583cdf0e10cSrcweir // mpVScrollBar->SetUpdateMode( bUpdate ); 2584cdf0e10cSrcweir if ( bUpdate && IsReallyVisible() ) 2585cdf0e10cSrcweir ImplCheckScrollBars(); 2586cdf0e10cSrcweir } 2587cdf0e10cSrcweir else if( nType == STATE_CHANGE_ENABLE ) 2588cdf0e10cSrcweir { 2589cdf0e10cSrcweir mpHScrollBar->Enable( IsEnabled() ); 2590cdf0e10cSrcweir mpVScrollBar->Enable( IsEnabled() ); 2591cdf0e10cSrcweir mpScrollBarBox->Enable( IsEnabled() ); 2592cdf0e10cSrcweir Invalidate(); 2593cdf0e10cSrcweir } 2594cdf0e10cSrcweir else if ( nType == STATE_CHANGE_ZOOM ) 2595cdf0e10cSrcweir { 2596cdf0e10cSrcweir maLBWindow.SetZoom( GetZoom() ); 2597cdf0e10cSrcweir Resize(); 2598cdf0e10cSrcweir } 2599cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLFONT ) 2600cdf0e10cSrcweir { 2601cdf0e10cSrcweir maLBWindow.SetControlFont( GetControlFont() ); 2602cdf0e10cSrcweir } 2603cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 2604cdf0e10cSrcweir { 2605cdf0e10cSrcweir maLBWindow.SetControlForeground( GetControlForeground() ); 2606cdf0e10cSrcweir } 2607cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 2608cdf0e10cSrcweir { 2609cdf0e10cSrcweir maLBWindow.SetControlBackground( GetControlBackground() ); 2610cdf0e10cSrcweir } 2611cdf0e10cSrcweir else if( nType == STATE_CHANGE_MIRRORING ) 2612cdf0e10cSrcweir { 2613cdf0e10cSrcweir maLBWindow.EnableRTL( IsRTLEnabled() ); 2614cdf0e10cSrcweir mpHScrollBar->EnableRTL( IsRTLEnabled() ); 2615cdf0e10cSrcweir mpVScrollBar->EnableRTL( IsRTLEnabled() ); 2616cdf0e10cSrcweir ImplResizeControls(); 2617cdf0e10cSrcweir } 2618cdf0e10cSrcweir 2619cdf0e10cSrcweir Control::StateChanged( nType ); 2620cdf0e10cSrcweir } 2621cdf0e10cSrcweir 2622cdf0e10cSrcweir // ----------------------------------------------------------------------- 2623cdf0e10cSrcweir 2624cdf0e10cSrcweir void ImplListBox::DataChanged( const DataChangedEvent& rDCEvt ) 2625cdf0e10cSrcweir { 2626cdf0e10cSrcweir // if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 2627cdf0e10cSrcweir // (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 2628cdf0e10cSrcweir // { 2629cdf0e10cSrcweir // maLBWindow.SetSettings( GetSettings() ); 2630cdf0e10cSrcweir // Resize(); 2631cdf0e10cSrcweir // } 2632cdf0e10cSrcweir // else 2633cdf0e10cSrcweir Control::DataChanged( rDCEvt ); 2634cdf0e10cSrcweir } 2635cdf0e10cSrcweir 2636cdf0e10cSrcweir // ----------------------------------------------------------------------- 2637cdf0e10cSrcweir 2638cdf0e10cSrcweir long ImplListBox::Notify( NotifyEvent& rNEvt ) 2639cdf0e10cSrcweir { 2640cdf0e10cSrcweir long nDone = 0; 2641cdf0e10cSrcweir if ( rNEvt.GetType() == EVENT_COMMAND ) 2642cdf0e10cSrcweir { 2643cdf0e10cSrcweir const CommandEvent& rCEvt = *rNEvt.GetCommandEvent(); 2644cdf0e10cSrcweir if ( rCEvt.GetCommand() == COMMAND_WHEEL ) 2645cdf0e10cSrcweir { 2646cdf0e10cSrcweir const CommandWheelData* pData = rCEvt.GetWheelData(); 2647cdf0e10cSrcweir if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) ) 2648cdf0e10cSrcweir { 2649cdf0e10cSrcweir nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar ); 2650cdf0e10cSrcweir } 2651cdf0e10cSrcweir } 2652cdf0e10cSrcweir } 2653cdf0e10cSrcweir 2654cdf0e10cSrcweir return nDone ? nDone : Window::Notify( rNEvt ); 2655cdf0e10cSrcweir } 2656cdf0e10cSrcweir 2657cdf0e10cSrcweir // ----------------------------------------------------------------------- 2658cdf0e10cSrcweir 2659cdf0e10cSrcweir const Wallpaper& ImplListBox::GetDisplayBackground() const 2660cdf0e10cSrcweir { 2661cdf0e10cSrcweir return maLBWindow.GetDisplayBackground(); 2662cdf0e10cSrcweir } 2663cdf0e10cSrcweir 2664cdf0e10cSrcweir // ----------------------------------------------------------------------- 2665cdf0e10cSrcweir 2666cdf0e10cSrcweir sal_Bool ImplListBox::HandleWheelAsCursorTravel( const CommandEvent& rCEvt ) 2667cdf0e10cSrcweir { 2668cdf0e10cSrcweir sal_Bool bDone = sal_False; 2669cdf0e10cSrcweir if ( rCEvt.GetCommand() == COMMAND_WHEEL ) 2670cdf0e10cSrcweir { 2671cdf0e10cSrcweir const CommandWheelData* pData = rCEvt.GetWheelData(); 2672cdf0e10cSrcweir if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) ) 2673cdf0e10cSrcweir { 2674cdf0e10cSrcweir sal_uInt16 nKey = ( pData->GetDelta() < 0 ) ? KEY_DOWN : KEY_UP; 2675cdf0e10cSrcweir KeyEvent aKeyEvent( 0, KeyCode( nKey ) ); 2676cdf0e10cSrcweir bDone = ProcessKeyInput( aKeyEvent ); 2677cdf0e10cSrcweir } 2678cdf0e10cSrcweir } 2679cdf0e10cSrcweir return bDone; 2680cdf0e10cSrcweir } 2681cdf0e10cSrcweir 2682cdf0e10cSrcweir // ----------------------------------------------------------------------- 2683cdf0e10cSrcweir 2684cdf0e10cSrcweir void ImplListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep ) 2685cdf0e10cSrcweir { 2686cdf0e10cSrcweir sal_Bool bChanges = GetEntryList()->GetMRUCount() ? sal_True : sal_False; 2687cdf0e10cSrcweir 2688cdf0e10cSrcweir // Remove old MRU entries 2689cdf0e10cSrcweir for ( sal_uInt16 n = GetEntryList()->GetMRUCount();n; ) 2690cdf0e10cSrcweir maLBWindow.RemoveEntry( --n ); 2691cdf0e10cSrcweir 2692cdf0e10cSrcweir sal_uInt16 nMRUCount = 0; 2693cdf0e10cSrcweir sal_uInt16 nEntries = rEntries.GetTokenCount( cSep ); 2694cdf0e10cSrcweir for ( sal_uInt16 nEntry = 0; nEntry < nEntries; nEntry++ ) 2695cdf0e10cSrcweir { 2696cdf0e10cSrcweir XubString aEntry = rEntries.GetToken( nEntry, cSep ); 2697cdf0e10cSrcweir // Accept only existing entries 2698cdf0e10cSrcweir if ( GetEntryList()->FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND ) 2699cdf0e10cSrcweir { 2700cdf0e10cSrcweir ImplEntryType* pNewEntry = new ImplEntryType( aEntry ); 2701cdf0e10cSrcweir maLBWindow.GetEntryList()->InsertEntry( nMRUCount++, pNewEntry, sal_False ); 2702cdf0e10cSrcweir bChanges = sal_True; 2703cdf0e10cSrcweir } 2704cdf0e10cSrcweir } 2705cdf0e10cSrcweir 2706cdf0e10cSrcweir if ( bChanges ) 2707cdf0e10cSrcweir { 2708cdf0e10cSrcweir maLBWindow.GetEntryList()->SetMRUCount( nMRUCount ); 2709cdf0e10cSrcweir SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 ); 2710cdf0e10cSrcweir StateChanged( STATE_CHANGE_DATA ); 2711cdf0e10cSrcweir } 2712cdf0e10cSrcweir } 2713cdf0e10cSrcweir 2714cdf0e10cSrcweir // ----------------------------------------------------------------------- 2715cdf0e10cSrcweir 2716cdf0e10cSrcweir XubString ImplListBox::GetMRUEntries( xub_Unicode cSep ) const 2717cdf0e10cSrcweir { 2718cdf0e10cSrcweir String aEntries; 2719cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < GetEntryList()->GetMRUCount(); n++ ) 2720cdf0e10cSrcweir { 2721cdf0e10cSrcweir aEntries += GetEntryList()->GetEntryText( n ); 2722cdf0e10cSrcweir if( n < ( GetEntryList()->GetMRUCount() - 1 ) ) 2723cdf0e10cSrcweir aEntries += cSep; 2724cdf0e10cSrcweir } 2725cdf0e10cSrcweir return aEntries; 2726cdf0e10cSrcweir } 2727cdf0e10cSrcweir 2728cdf0e10cSrcweir // ======================================================================= 2729cdf0e10cSrcweir 2730cdf0e10cSrcweir ImplWin::ImplWin( Window* pParent, WinBits nWinStyle ) : 2731cdf0e10cSrcweir Control ( pParent, nWinStyle ) 2732cdf0e10cSrcweir { 2733cdf0e10cSrcweir if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) 2734cdf0e10cSrcweir && ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) ) 2735cdf0e10cSrcweir SetBackground(); 2736cdf0e10cSrcweir else 2737cdf0e10cSrcweir SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) ); 2738cdf0e10cSrcweir 2739cdf0e10cSrcweir mbInUserDraw = sal_False; 2740cdf0e10cSrcweir mbUserDrawEnabled = sal_False; 2741cdf0e10cSrcweir mnItemPos = LISTBOX_ENTRY_NOTFOUND; 2742cdf0e10cSrcweir } 2743cdf0e10cSrcweir 2744cdf0e10cSrcweir // ----------------------------------------------------------------------- 2745cdf0e10cSrcweir 2746cdf0e10cSrcweir sal_Bool ImplWin::SetModeImage( const Image& rImage, BmpColorMode eMode ) 2747cdf0e10cSrcweir { 2748cdf0e10cSrcweir if( eMode == BMP_COLOR_NORMAL ) 2749cdf0e10cSrcweir SetImage( rImage ); 2750cdf0e10cSrcweir else if( eMode == BMP_COLOR_HIGHCONTRAST ) 2751cdf0e10cSrcweir maImageHC = rImage; 2752cdf0e10cSrcweir else 2753cdf0e10cSrcweir return sal_False; 2754cdf0e10cSrcweir return sal_True; 2755cdf0e10cSrcweir } 2756cdf0e10cSrcweir 2757cdf0e10cSrcweir // ----------------------------------------------------------------------- 2758cdf0e10cSrcweir 2759cdf0e10cSrcweir const Image& ImplWin::GetModeImage( BmpColorMode eMode ) const 2760cdf0e10cSrcweir { 2761cdf0e10cSrcweir if( eMode == BMP_COLOR_HIGHCONTRAST ) 2762cdf0e10cSrcweir return maImageHC; 2763cdf0e10cSrcweir else 2764cdf0e10cSrcweir return maImage; 2765cdf0e10cSrcweir } 2766cdf0e10cSrcweir 2767cdf0e10cSrcweir // ----------------------------------------------------------------------- 2768cdf0e10cSrcweir 2769cdf0e10cSrcweir void ImplWin::MBDown() 2770cdf0e10cSrcweir { 2771cdf0e10cSrcweir if( IsEnabled() ) 2772cdf0e10cSrcweir maMBDownHdl.Call( this ); 2773cdf0e10cSrcweir } 2774cdf0e10cSrcweir 2775cdf0e10cSrcweir // ----------------------------------------------------------------------- 2776cdf0e10cSrcweir 2777cdf0e10cSrcweir void ImplWin::MouseButtonDown( const MouseEvent& ) 2778cdf0e10cSrcweir { 2779cdf0e10cSrcweir if( IsEnabled() ) 2780cdf0e10cSrcweir { 2781cdf0e10cSrcweir // Control::MouseButtonDown( rMEvt ); 2782cdf0e10cSrcweir MBDown(); 2783cdf0e10cSrcweir } 2784cdf0e10cSrcweir } 2785cdf0e10cSrcweir 2786cdf0e10cSrcweir // ----------------------------------------------------------------------- 2787cdf0e10cSrcweir 2788cdf0e10cSrcweir void ImplWin::FillLayoutData() const 2789cdf0e10cSrcweir { 2790cdf0e10cSrcweir mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 2791cdf0e10cSrcweir const_cast<ImplWin*>(this)->ImplDraw( true ); 2792cdf0e10cSrcweir } 2793cdf0e10cSrcweir 2794cdf0e10cSrcweir // ----------------------------------------------------------------------- 2795cdf0e10cSrcweir 2796cdf0e10cSrcweir long ImplWin::PreNotify( NotifyEvent& rNEvt ) 2797cdf0e10cSrcweir { 2798cdf0e10cSrcweir long nDone = 0; 2799cdf0e10cSrcweir const MouseEvent* pMouseEvt = NULL; 2800cdf0e10cSrcweir 2801cdf0e10cSrcweir if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 2802cdf0e10cSrcweir { 2803cdf0e10cSrcweir if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) 2804cdf0e10cSrcweir { 2805cdf0e10cSrcweir // trigger redraw as mouse over state has changed 2806cdf0e10cSrcweir if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) 2807cdf0e10cSrcweir && ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) ) 2808cdf0e10cSrcweir { 2809cdf0e10cSrcweir GetParent()->GetWindow( WINDOW_BORDER )->Invalidate( INVALIDATE_NOERASE ); 2810cdf0e10cSrcweir GetParent()->GetWindow( WINDOW_BORDER )->Update(); 2811cdf0e10cSrcweir } 2812cdf0e10cSrcweir } 2813cdf0e10cSrcweir } 2814cdf0e10cSrcweir 2815cdf0e10cSrcweir return nDone ? nDone : Control::PreNotify(rNEvt); 2816cdf0e10cSrcweir } 2817cdf0e10cSrcweir 2818cdf0e10cSrcweir // ----------------------------------------------------------------------- 2819cdf0e10cSrcweir 2820cdf0e10cSrcweir void ImplWin::ImplDraw( bool bLayout ) 2821cdf0e10cSrcweir { 2822cdf0e10cSrcweir const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 2823cdf0e10cSrcweir 2824cdf0e10cSrcweir sal_Bool bNativeOK = sal_False; 2825cdf0e10cSrcweir 2826cdf0e10cSrcweir if( ! bLayout ) 2827cdf0e10cSrcweir { 2828cdf0e10cSrcweir ControlState nState = CTRL_STATE_ENABLED; 2829cdf0e10cSrcweir if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) 2830cdf0e10cSrcweir && IsNativeControlSupported(CTRL_LISTBOX, HAS_BACKGROUND_TEXTURE) ) 2831cdf0e10cSrcweir { 2832cdf0e10cSrcweir // Repaint the (focused) area similarly to 2833cdf0e10cSrcweir // ImplSmallBorderWindowView::DrawWindow() in 2834cdf0e10cSrcweir // vcl/source/window/brdwin.cxx 2835cdf0e10cSrcweir Window *pWin = GetParent(); 2836cdf0e10cSrcweir 2837cdf0e10cSrcweir ImplControlValue aControlValue; 2838cdf0e10cSrcweir if ( !pWin->IsEnabled() ) 2839cdf0e10cSrcweir nState &= ~CTRL_STATE_ENABLED; 2840cdf0e10cSrcweir if ( pWin->HasFocus() ) 2841cdf0e10cSrcweir nState |= CTRL_STATE_FOCUSED; 2842cdf0e10cSrcweir 2843cdf0e10cSrcweir // The listbox is painted over the entire control including the 2844cdf0e10cSrcweir // border, but ImplWin does not contain the border => correction 2845cdf0e10cSrcweir // needed. 2846cdf0e10cSrcweir sal_Int32 nLeft, nTop, nRight, nBottom; 2847cdf0e10cSrcweir pWin->GetBorder( nLeft, nTop, nRight, nBottom ); 2848cdf0e10cSrcweir Point aPoint( -nLeft, -nTop ); 2849cdf0e10cSrcweir Rectangle aCtrlRegion( aPoint - GetPosPixel(), pWin->GetSizePixel() ); 2850cdf0e10cSrcweir 2851cdf0e10cSrcweir sal_Bool bMouseOver = sal_False; 2852cdf0e10cSrcweir if( GetParent() ) 2853cdf0e10cSrcweir { 2854cdf0e10cSrcweir Window *pChild = GetParent()->GetWindow( WINDOW_FIRSTCHILD ); 2855cdf0e10cSrcweir while( pChild && (bMouseOver = pChild->IsMouseOver()) == sal_False ) 2856cdf0e10cSrcweir pChild = pChild->GetWindow( WINDOW_NEXT ); 2857cdf0e10cSrcweir } 2858cdf0e10cSrcweir 2859cdf0e10cSrcweir if( bMouseOver ) 2860cdf0e10cSrcweir nState |= CTRL_STATE_ROLLOVER; 2861cdf0e10cSrcweir 2862cdf0e10cSrcweir // if parent has no border, then nobody has drawn the background 2863cdf0e10cSrcweir // since no border window exists. so draw it here. 2864cdf0e10cSrcweir WinBits nParentStyle = pWin->GetStyle(); 2865cdf0e10cSrcweir if( ! (nParentStyle & WB_BORDER) || (nParentStyle & WB_NOBORDER) ) 2866cdf0e10cSrcweir { 2867cdf0e10cSrcweir Rectangle aParentRect( Point( 0, 0 ), pWin->GetSizePixel() ); 2868cdf0e10cSrcweir pWin->DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aParentRect, 2869cdf0e10cSrcweir nState, aControlValue, rtl::OUString() ); 2870cdf0e10cSrcweir } 2871cdf0e10cSrcweir 2872cdf0e10cSrcweir bNativeOK = DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 2873cdf0e10cSrcweir aControlValue, rtl::OUString() ); 2874cdf0e10cSrcweir } 2875cdf0e10cSrcweir 2876cdf0e10cSrcweir if( IsEnabled() ) 2877cdf0e10cSrcweir { 2878cdf0e10cSrcweir if( HasFocus() ) 2879cdf0e10cSrcweir { 2880cdf0e10cSrcweir SetTextColor( rStyleSettings.GetHighlightTextColor() ); 2881cdf0e10cSrcweir SetFillColor( rStyleSettings.GetHighlightColor() ); 2882cdf0e10cSrcweir DrawRect( maFocusRect ); 2883cdf0e10cSrcweir } 2884cdf0e10cSrcweir else 2885cdf0e10cSrcweir { 2886cdf0e10cSrcweir Color aColor; 2887cdf0e10cSrcweir if( bNativeOK && (nState & CTRL_STATE_ROLLOVER) ) 2888cdf0e10cSrcweir aColor = rStyleSettings.GetFieldRolloverTextColor(); 2889cdf0e10cSrcweir else 2890cdf0e10cSrcweir aColor = rStyleSettings.GetFieldTextColor(); 2891cdf0e10cSrcweir if( IsControlForeground() ) 2892cdf0e10cSrcweir aColor = GetControlForeground(); 2893cdf0e10cSrcweir SetTextColor( aColor ); 2894cdf0e10cSrcweir if ( !bNativeOK ) 2895cdf0e10cSrcweir Erase( maFocusRect ); 2896cdf0e10cSrcweir } 2897cdf0e10cSrcweir } 2898cdf0e10cSrcweir else // Disabled 2899cdf0e10cSrcweir { 2900cdf0e10cSrcweir SetTextColor( rStyleSettings.GetDisableColor() ); 2901cdf0e10cSrcweir if ( !bNativeOK ) 2902cdf0e10cSrcweir Erase( maFocusRect ); 2903cdf0e10cSrcweir } 2904cdf0e10cSrcweir } 2905cdf0e10cSrcweir 2906cdf0e10cSrcweir if ( IsUserDrawEnabled() ) 2907cdf0e10cSrcweir { 2908cdf0e10cSrcweir mbInUserDraw = sal_True; 2909cdf0e10cSrcweir UserDrawEvent aUDEvt( this, maFocusRect, mnItemPos, 0 ); 2910cdf0e10cSrcweir maUserDrawHdl.Call( &aUDEvt ); 2911cdf0e10cSrcweir mbInUserDraw = sal_False; 2912cdf0e10cSrcweir } 2913cdf0e10cSrcweir else 2914cdf0e10cSrcweir { 2915cdf0e10cSrcweir DrawEntry( sal_True, sal_True, sal_False, bLayout ); 2916cdf0e10cSrcweir } 2917cdf0e10cSrcweir } 2918cdf0e10cSrcweir 2919cdf0e10cSrcweir // ----------------------------------------------------------------------- 2920cdf0e10cSrcweir 2921cdf0e10cSrcweir void ImplWin::Paint( const Rectangle& ) 2922cdf0e10cSrcweir { 2923cdf0e10cSrcweir ImplDraw(); 2924cdf0e10cSrcweir } 2925cdf0e10cSrcweir 2926cdf0e10cSrcweir // ----------------------------------------------------------------------- 2927cdf0e10cSrcweir 2928cdf0e10cSrcweir void ImplWin::DrawEntry( sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout ) 2929cdf0e10cSrcweir { 2930cdf0e10cSrcweir long nBorder = 1; 2931cdf0e10cSrcweir Size aOutSz = GetOutputSizePixel(); 2932cdf0e10cSrcweir 2933cdf0e10cSrcweir sal_Bool bImage = !!maImage; 2934cdf0e10cSrcweir if( bDrawImage && bImage && !bLayout ) 2935cdf0e10cSrcweir { 2936cdf0e10cSrcweir sal_uInt16 nStyle = 0; 2937cdf0e10cSrcweir Size aImgSz = maImage.GetSizePixel(); 2938cdf0e10cSrcweir Point aPtImg( nBorder, ( ( aOutSz.Height() - aImgSz.Height() ) / 2 ) ); 2939cdf0e10cSrcweir 2940cdf0e10cSrcweir // check for HC mode 2941cdf0e10cSrcweir Image *pImage = &maImage; 2942cdf0e10cSrcweir 2943cdf0e10cSrcweir if( !!maImageHC ) 2944cdf0e10cSrcweir { 2945cdf0e10cSrcweir if( GetSettings().GetStyleSettings().GetHighContrastMode() ) 2946cdf0e10cSrcweir pImage = &maImageHC; 2947cdf0e10cSrcweir } 2948cdf0e10cSrcweir 2949cdf0e10cSrcweir if ( !IsZoom() ) 2950cdf0e10cSrcweir { 2951cdf0e10cSrcweir DrawImage( aPtImg, *pImage, nStyle ); 2952cdf0e10cSrcweir } 2953cdf0e10cSrcweir else 2954cdf0e10cSrcweir { 2955cdf0e10cSrcweir aImgSz.Width() = CalcZoom( aImgSz.Width() ); 2956cdf0e10cSrcweir aImgSz.Height() = CalcZoom( aImgSz.Height() ); 2957cdf0e10cSrcweir DrawImage( aPtImg, aImgSz, *pImage, nStyle ); 2958cdf0e10cSrcweir } 2959cdf0e10cSrcweir } 2960cdf0e10cSrcweir 2961cdf0e10cSrcweir if( bDrawText && maString.Len() ) 2962cdf0e10cSrcweir { 2963cdf0e10cSrcweir sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER; 2964cdf0e10cSrcweir 2965cdf0e10cSrcweir if ( bDrawImage && bImage && !bLayout ) 2966cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_LEFT; 2967cdf0e10cSrcweir else if ( GetStyle() & WB_CENTER ) 2968cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_CENTER; 2969cdf0e10cSrcweir else if ( GetStyle() & WB_RIGHT ) 2970cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_RIGHT; 2971cdf0e10cSrcweir else 2972cdf0e10cSrcweir nTextStyle |= TEXT_DRAW_LEFT; 2973cdf0e10cSrcweir 2974cdf0e10cSrcweir Rectangle aTextRect( Point( nBorder, 0 ), Size( aOutSz.Width()-2*nBorder, aOutSz.Height() ) ); 2975cdf0e10cSrcweir 2976cdf0e10cSrcweir if ( !bDrawTextAtImagePos && ( bImage || IsUserDrawEnabled() ) ) 2977cdf0e10cSrcweir { 2978cdf0e10cSrcweir long nMaxWidth = Max( maImage.GetSizePixel().Width(), maUserItemSize.Width() ); 2979cdf0e10cSrcweir aTextRect.Left() += nMaxWidth + IMG_TXT_DISTANCE; 2980cdf0e10cSrcweir } 2981cdf0e10cSrcweir 2982cdf0e10cSrcweir MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL; 2983cdf0e10cSrcweir String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; 2984cdf0e10cSrcweir DrawText( aTextRect, maString, nTextStyle, pVector, pDisplayText ); 2985cdf0e10cSrcweir } 2986cdf0e10cSrcweir 2987cdf0e10cSrcweir if( HasFocus() && !bLayout ) 2988cdf0e10cSrcweir ShowFocus( maFocusRect ); 2989cdf0e10cSrcweir } 2990cdf0e10cSrcweir 2991cdf0e10cSrcweir // ----------------------------------------------------------------------- 2992cdf0e10cSrcweir 2993cdf0e10cSrcweir void ImplWin::Resize() 2994cdf0e10cSrcweir { 2995cdf0e10cSrcweir Control::Resize(); 2996cdf0e10cSrcweir maFocusRect.SetSize( GetOutputSizePixel() ); 2997cdf0e10cSrcweir Invalidate(); 2998cdf0e10cSrcweir } 2999cdf0e10cSrcweir 3000cdf0e10cSrcweir // ----------------------------------------------------------------------- 3001cdf0e10cSrcweir 3002cdf0e10cSrcweir void ImplWin::GetFocus() 3003cdf0e10cSrcweir { 3004cdf0e10cSrcweir ShowFocus( maFocusRect ); 3005cdf0e10cSrcweir if( ImplGetSVData()->maNWFData.mbNoFocusRects && 3006cdf0e10cSrcweir IsNativeWidgetEnabled() && 3007cdf0e10cSrcweir IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) ) 3008cdf0e10cSrcweir { 3009cdf0e10cSrcweir Window* pWin = GetParent()->GetWindow( WINDOW_BORDER ); 3010cdf0e10cSrcweir if( ! pWin ) 3011cdf0e10cSrcweir pWin = GetParent(); 3012cdf0e10cSrcweir pWin->Invalidate(); 3013cdf0e10cSrcweir } 3014cdf0e10cSrcweir else 3015cdf0e10cSrcweir Invalidate(); 3016cdf0e10cSrcweir Control::GetFocus(); 3017cdf0e10cSrcweir } 3018cdf0e10cSrcweir 3019cdf0e10cSrcweir // ----------------------------------------------------------------------- 3020cdf0e10cSrcweir 3021cdf0e10cSrcweir void ImplWin::LoseFocus() 3022cdf0e10cSrcweir { 3023cdf0e10cSrcweir HideFocus(); 3024cdf0e10cSrcweir if( ImplGetSVData()->maNWFData.mbNoFocusRects && 3025cdf0e10cSrcweir IsNativeWidgetEnabled() && 3026cdf0e10cSrcweir IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) ) 3027cdf0e10cSrcweir { 3028cdf0e10cSrcweir Window* pWin = GetParent()->GetWindow( WINDOW_BORDER ); 3029cdf0e10cSrcweir if( ! pWin ) 3030cdf0e10cSrcweir pWin = GetParent(); 3031cdf0e10cSrcweir pWin->Invalidate(); 3032cdf0e10cSrcweir } 3033cdf0e10cSrcweir else 3034cdf0e10cSrcweir Invalidate(); 3035cdf0e10cSrcweir Control::LoseFocus(); 3036cdf0e10cSrcweir } 3037cdf0e10cSrcweir 3038cdf0e10cSrcweir // ======================================================================= 3039cdf0e10cSrcweir 3040cdf0e10cSrcweir ImplBtn::ImplBtn( Window* pParent, WinBits nWinStyle ) : 3041cdf0e10cSrcweir PushButton( pParent, nWinStyle ), 3042cdf0e10cSrcweir mbDown ( sal_False ) 3043cdf0e10cSrcweir { 3044cdf0e10cSrcweir } 3045cdf0e10cSrcweir 3046cdf0e10cSrcweir // ----------------------------------------------------------------------- 3047cdf0e10cSrcweir 3048cdf0e10cSrcweir void ImplBtn::MBDown() 3049cdf0e10cSrcweir { 3050cdf0e10cSrcweir if( IsEnabled() ) 3051cdf0e10cSrcweir maMBDownHdl.Call( this ); 3052cdf0e10cSrcweir } 3053cdf0e10cSrcweir 3054cdf0e10cSrcweir // ----------------------------------------------------------------------- 3055cdf0e10cSrcweir 3056cdf0e10cSrcweir void ImplBtn::MouseButtonDown( const MouseEvent& ) 3057cdf0e10cSrcweir { 3058cdf0e10cSrcweir //PushButton::MouseButtonDown( rMEvt ); 3059cdf0e10cSrcweir if( IsEnabled() ) 3060cdf0e10cSrcweir { 3061cdf0e10cSrcweir MBDown(); 3062cdf0e10cSrcweir mbDown = sal_True; 3063cdf0e10cSrcweir } 3064cdf0e10cSrcweir } 3065cdf0e10cSrcweir 3066cdf0e10cSrcweir // ======================================================================= 3067cdf0e10cSrcweir 3068cdf0e10cSrcweir ImplListBoxFloatingWindow::ImplListBoxFloatingWindow( Window* pParent ) : 3069cdf0e10cSrcweir FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW ) // no drop shadow for list boxes 3070cdf0e10cSrcweir { 3071cdf0e10cSrcweir mpImplLB = NULL; 3072cdf0e10cSrcweir mnDDLineCount = 0; 3073cdf0e10cSrcweir mbAutoWidth = sal_False; 3074cdf0e10cSrcweir 3075cdf0e10cSrcweir mnPopupModeStartSaveSelection = LISTBOX_ENTRY_NOTFOUND; 3076cdf0e10cSrcweir 3077cdf0e10cSrcweir EnableSaveBackground(); 3078cdf0e10cSrcweir 3079cdf0e10cSrcweir Window * pBorderWindow = ImplGetBorderWindow(); 3080cdf0e10cSrcweir if( pBorderWindow ) 3081cdf0e10cSrcweir { 3082cdf0e10cSrcweir SetAccessibleRole(accessibility::AccessibleRole::PANEL); 3083cdf0e10cSrcweir pBorderWindow->SetAccessibleRole(accessibility::AccessibleRole::WINDOW); 3084cdf0e10cSrcweir } 3085cdf0e10cSrcweir else 3086cdf0e10cSrcweir { 3087cdf0e10cSrcweir SetAccessibleRole(accessibility::AccessibleRole::WINDOW); 3088cdf0e10cSrcweir } 3089cdf0e10cSrcweir 3090cdf0e10cSrcweir } 3091cdf0e10cSrcweir 3092cdf0e10cSrcweir // ----------------------------------------------------------------------- 3093cdf0e10cSrcweir 3094cdf0e10cSrcweir long ImplListBoxFloatingWindow::PreNotify( NotifyEvent& rNEvt ) 3095cdf0e10cSrcweir { 3096cdf0e10cSrcweir if( rNEvt.GetType() == EVENT_LOSEFOCUS ) 3097cdf0e10cSrcweir { 3098cdf0e10cSrcweir if( !GetParent()->HasChildPathFocus( sal_True ) ) 3099cdf0e10cSrcweir EndPopupMode(); 3100cdf0e10cSrcweir } 3101cdf0e10cSrcweir 3102cdf0e10cSrcweir return FloatingWindow::PreNotify( rNEvt ); 3103cdf0e10cSrcweir } 3104cdf0e10cSrcweir 3105cdf0e10cSrcweir // ----------------------------------------------------------------------- 3106cdf0e10cSrcweir 3107cdf0e10cSrcweir void ImplListBoxFloatingWindow::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) 3108cdf0e10cSrcweir { 3109cdf0e10cSrcweir FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 3110cdf0e10cSrcweir 3111cdf0e10cSrcweir // Fix #60890# ( MBA ): um auch im aufgeklappten Zustand der Listbox die Gr"o\se einfach zu einen 3112cdf0e10cSrcweir // Aufruf von Resize() "andern zu k"onnen, wird die Position hier ggf. angepa\t 3113cdf0e10cSrcweir if ( IsReallyVisible() && ( nFlags & WINDOW_POSSIZE_HEIGHT ) ) 3114cdf0e10cSrcweir { 3115cdf0e10cSrcweir Point aPos = GetParent()->GetPosPixel(); 3116cdf0e10cSrcweir aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos ); 3117cdf0e10cSrcweir 3118cdf0e10cSrcweir if ( nFlags & WINDOW_POSSIZE_X ) 3119cdf0e10cSrcweir aPos.X() = nX; 3120cdf0e10cSrcweir 3121cdf0e10cSrcweir if ( nFlags & WINDOW_POSSIZE_Y ) 3122cdf0e10cSrcweir aPos.Y() = nY; 3123cdf0e10cSrcweir 3124cdf0e10cSrcweir sal_uInt16 nIndex; 3125cdf0e10cSrcweir SetPosPixel( ImplCalcPos( this, Rectangle( aPos, GetParent()->GetSizePixel() ), FLOATWIN_POPUPMODE_DOWN, nIndex ) ); 3126cdf0e10cSrcweir } 3127cdf0e10cSrcweir 3128cdf0e10cSrcweir // if( !IsReallyVisible() ) 3129cdf0e10cSrcweir { 3130cdf0e10cSrcweir // Die ImplListBox erhaelt kein Resize, weil nicht sichtbar. 3131cdf0e10cSrcweir // Die Fenster muessen aber ein Resize() erhalten, damit die 3132cdf0e10cSrcweir // Anzahl der sichtbaren Eintraege fuer PgUp/PgDown stimmt. 3133cdf0e10cSrcweir // Die Anzahl kann auch nicht von List/Combobox berechnet werden, 3134cdf0e10cSrcweir // weil hierfuer auch die ggf. vorhandene vertikale Scrollbar 3135cdf0e10cSrcweir // beruecksichtigt werden muss. 3136cdf0e10cSrcweir mpImplLB->SetSizePixel( GetOutputSizePixel() ); 3137cdf0e10cSrcweir ((Window*)mpImplLB)->Resize(); 3138cdf0e10cSrcweir ((Window*)mpImplLB->GetMainWindow())->Resize(); 3139cdf0e10cSrcweir } 3140cdf0e10cSrcweir } 3141cdf0e10cSrcweir 3142cdf0e10cSrcweir // ----------------------------------------------------------------------- 3143cdf0e10cSrcweir 3144cdf0e10cSrcweir void ImplListBoxFloatingWindow::Resize() 3145cdf0e10cSrcweir { 3146cdf0e10cSrcweir mpImplLB->GetMainWindow()->ImplClearLayoutData(); 3147cdf0e10cSrcweir FloatingWindow::Resize(); 3148cdf0e10cSrcweir } 3149cdf0e10cSrcweir 3150cdf0e10cSrcweir // ----------------------------------------------------------------------- 3151cdf0e10cSrcweir 3152cdf0e10cSrcweir Size ImplListBoxFloatingWindow::CalcFloatSize() 3153cdf0e10cSrcweir { 3154cdf0e10cSrcweir Size aFloatSz( maPrefSz ); 3155cdf0e10cSrcweir 3156cdf0e10cSrcweir sal_Int32 nLeft, nTop, nRight, nBottom; 3157cdf0e10cSrcweir GetBorder( nLeft, nTop, nRight, nBottom ); 3158cdf0e10cSrcweir 3159cdf0e10cSrcweir sal_uInt16 nLines = mpImplLB->GetEntryList()->GetEntryCount(); 3160cdf0e10cSrcweir if ( mnDDLineCount && ( nLines > mnDDLineCount ) ) 3161cdf0e10cSrcweir nLines = mnDDLineCount; 3162cdf0e10cSrcweir 3163cdf0e10cSrcweir Size aSz = mpImplLB->CalcSize( nLines ); 3164cdf0e10cSrcweir long nMaxHeight = aSz.Height() + nTop + nBottom; 3165cdf0e10cSrcweir 3166cdf0e10cSrcweir if ( mnDDLineCount ) 3167cdf0e10cSrcweir aFloatSz.Height() = nMaxHeight; 3168cdf0e10cSrcweir 3169cdf0e10cSrcweir if( mbAutoWidth ) 3170cdf0e10cSrcweir { 3171cdf0e10cSrcweir // AutoSize erstmal nur fuer die Breite... 3172cdf0e10cSrcweir 3173cdf0e10cSrcweir aFloatSz.Width() = aSz.Width() + nLeft + nRight; 3174cdf0e10cSrcweir aFloatSz.Width() += nRight; // etwas mehr Platz sieht besser aus... 3175cdf0e10cSrcweir 3176cdf0e10cSrcweir if ( ( aFloatSz.Height() < nMaxHeight ) || ( mnDDLineCount && ( mnDDLineCount < mpImplLB->GetEntryList()->GetEntryCount() ) ) ) 3177cdf0e10cSrcweir { 3178cdf0e10cSrcweir // dann wird noch der vertikale Scrollbar benoetigt 3179cdf0e10cSrcweir long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize(); 3180cdf0e10cSrcweir aFloatSz.Width() += nSBWidth; 3181cdf0e10cSrcweir } 3182cdf0e10cSrcweir } 3183cdf0e10cSrcweir 3184cdf0e10cSrcweir if ( aFloatSz.Height() > nMaxHeight ) 3185cdf0e10cSrcweir aFloatSz.Height() = nMaxHeight; 3186cdf0e10cSrcweir 3187cdf0e10cSrcweir // Minimale Hoehe, falls Hoehe nicht auf Float-Hoehe eingestellt wurde. 3188cdf0e10cSrcweir // Der Parent vom FloatWin muss die DropDown-Combo/Listbox sein. 3189cdf0e10cSrcweir Size aParentSz = GetParent()->GetSizePixel(); 3190cdf0e10cSrcweir if( !mnDDLineCount && ( aFloatSz.Height() < aParentSz.Height() ) ) 3191cdf0e10cSrcweir aFloatSz.Height() = aParentSz.Height(); 3192cdf0e10cSrcweir 3193cdf0e10cSrcweir // Nicht schmaler als der Parent werden... 3194cdf0e10cSrcweir if( aFloatSz.Width() < aParentSz.Width() ) 3195cdf0e10cSrcweir aFloatSz.Width() = aParentSz.Width(); 3196cdf0e10cSrcweir 3197cdf0e10cSrcweir // Hoehe auf Entries alignen... 3198cdf0e10cSrcweir long nInnerHeight = aFloatSz.Height() - nTop - nBottom; 3199cdf0e10cSrcweir long nEntryHeight = mpImplLB->GetEntryHeight(); 3200cdf0e10cSrcweir if ( nInnerHeight % nEntryHeight ) 3201cdf0e10cSrcweir { 3202cdf0e10cSrcweir nInnerHeight /= nEntryHeight; 3203cdf0e10cSrcweir nInnerHeight++; 3204cdf0e10cSrcweir nInnerHeight *= nEntryHeight; 3205cdf0e10cSrcweir aFloatSz.Height() = nInnerHeight + nTop + nBottom; 3206cdf0e10cSrcweir } 3207cdf0e10cSrcweir 3208cdf0e10cSrcweir return aFloatSz; 3209cdf0e10cSrcweir } 3210cdf0e10cSrcweir 3211cdf0e10cSrcweir // ----------------------------------------------------------------------- 3212cdf0e10cSrcweir 3213cdf0e10cSrcweir void ImplListBoxFloatingWindow::StartFloat( sal_Bool bStartTracking ) 3214cdf0e10cSrcweir { 3215cdf0e10cSrcweir if( !IsInPopupMode() ) 3216cdf0e10cSrcweir { 3217cdf0e10cSrcweir Size aFloatSz = CalcFloatSize(); 3218cdf0e10cSrcweir 3219cdf0e10cSrcweir SetSizePixel( aFloatSz ); 3220cdf0e10cSrcweir mpImplLB->SetSizePixel( GetOutputSizePixel() ); 3221cdf0e10cSrcweir 3222cdf0e10cSrcweir sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 ); 3223cdf0e10cSrcweir mnPopupModeStartSaveSelection = nPos; 3224cdf0e10cSrcweir 3225cdf0e10cSrcweir Size aSz = GetParent()->GetSizePixel(); 3226cdf0e10cSrcweir Point aPos = GetParent()->GetPosPixel(); 3227cdf0e10cSrcweir aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos ); 3228cdf0e10cSrcweir // FIXME: this ugly hack is for Mac/Aqua 3229cdf0e10cSrcweir // should be replaced by a real mechanism to place the float rectangle 3230cdf0e10cSrcweir if( ImplGetSVData()->maNWFData.mbNoFocusRects && 3231cdf0e10cSrcweir GetParent()->IsNativeWidgetEnabled() ) 3232cdf0e10cSrcweir { 3233cdf0e10cSrcweir sal_Int32 nLeft = 4, nTop = 4, nRight = 4, nBottom = 4; 3234cdf0e10cSrcweir aPos.X() += nLeft; 3235cdf0e10cSrcweir aPos.Y() += nTop; 3236cdf0e10cSrcweir aSz.Width() -= nLeft + nRight; 3237cdf0e10cSrcweir aSz.Height() -= nTop + nBottom; 3238cdf0e10cSrcweir } 3239cdf0e10cSrcweir Rectangle aRect( aPos, aSz ); 3240cdf0e10cSrcweir 3241cdf0e10cSrcweir // check if the control's parent is un-mirrored which is the case for form controls in a mirrored UI 3242cdf0e10cSrcweir // where the document is unmirrored 3243cdf0e10cSrcweir // because StartPopupMode() expects a rectangle in mirrored coordinates we have to re-mirror 3244cdf0e10cSrcweir if( GetParent()->GetParent()->ImplIsAntiparallel() ) 3245cdf0e10cSrcweir GetParent()->GetParent()->ImplReMirror( aRect ); 3246cdf0e10cSrcweir 3247cdf0e10cSrcweir StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN ); 3248cdf0e10cSrcweir 3249cdf0e10cSrcweir if( nPos != LISTBOX_ENTRY_NOTFOUND ) 3250cdf0e10cSrcweir mpImplLB->ShowProminentEntry( nPos ); 3251cdf0e10cSrcweir 3252cdf0e10cSrcweir if( bStartTracking ) 3253cdf0e10cSrcweir mpImplLB->GetMainWindow()->EnableMouseMoveSelect( sal_True ); 3254cdf0e10cSrcweir 3255cdf0e10cSrcweir if ( mpImplLB->GetMainWindow()->IsGrabFocusAllowed() ) 3256cdf0e10cSrcweir mpImplLB->GetMainWindow()->GrabFocus(); 3257cdf0e10cSrcweir 3258cdf0e10cSrcweir mpImplLB->GetMainWindow()->ImplClearLayoutData(); 3259cdf0e10cSrcweir } 3260cdf0e10cSrcweir } 3261