LibreOffice Module vcl (master)  1
imp_listbox.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 
22 #include <vcl/svapp.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/scrbar.hxx>
26 #include <vcl/toolkit/lstbox.hxx>
27 #include <vcl/i18nhelp.hxx>
28 #include <vcl/naturalsort.hxx>
29 
30 #include <listbox.hxx>
31 #include <svdata.hxx>
32 #include <window.h>
33 
34 #include <com/sun/star/accessibility/AccessibleRole.hpp>
35 
36 #include <sal/log.hxx>
37 #include <o3tl/safeint.hxx>
38 #include <osl/diagnose.h>
39 #include <comphelper/string.hxx>
41 
42 #include <limits>
43 
44 #define MULTILINE_ENTRY_DRAW_FLAGS ( DrawTextFlags::WordBreak | DrawTextFlags::MultiLine | DrawTextFlags::VCenter )
45 
46 using namespace ::com::sun::star;
47 
48 constexpr tools::Long gnBorder = 1;
49 
51 {
52  pButton->SetSymbol( SymbolType::SPIN_DOWN );
53 
56  pButton->SetBackground();
57 }
58 
60 {
61  mpWindow = pWindow;
64  mnImages = 0;
66 
67  mnMRUCount = 0;
68  mnMaxMRUCount = 0;
69 }
70 
72 {
73  Clear();
74 }
75 
77 {
78  mnImages = 0;
79  maEntries.clear();
80 }
81 
83 {
84  Clear();
85  mpWindow.clear();
86 }
87 
88 void ImplEntryList::SelectEntry( sal_Int32 nPos, bool bSelect )
89 {
90  if (0 <= nPos && o3tl::make_unsigned(nPos) < maEntries.size())
91  {
92  std::vector<std::unique_ptr<ImplEntryType> >::iterator iter = maEntries.begin()+nPos;
93 
94  if ( ( (*iter)->mbIsSelected != bSelect ) &&
96  {
97  (*iter)->mbIsSelected = bSelect;
99  maSelectionChangedHdl.Call( nPos );
100  }
101  }
102 }
103 
104 namespace
105 {
107  {
110  Application::GetSettings().GetLanguageTag().getLocale());
111  return gSorter;
112  };
113 }
114 
115 namespace vcl
116 {
117  sal_Int32 NaturalSortCompare(const OUString &rA, const OUString &rB)
118  {
119  const comphelper::string::NaturalStringSorter &rSorter = GetSorter();
120  return rSorter.compare(rA, rB);
121  }
122 }
123 
124 sal_Int32 ImplEntryList::InsertEntry( sal_Int32 nPos, ImplEntryType* pNewEntry, bool bSort )
125 {
126  assert(nPos >= 0);
127  assert(maEntries.size() < LISTBOX_MAX_ENTRIES);
128 
129  if ( !!pNewEntry->maImage )
130  mnImages++;
131 
132  sal_Int32 insPos = 0;
133  const sal_Int32 nEntriesSize = static_cast<sal_Int32>(maEntries.size());
134 
135  if ( !bSort || maEntries.empty())
136  {
137  if (0 <= nPos && nPos < nEntriesSize)
138  {
139  insPos = nPos;
140  maEntries.insert( maEntries.begin() + nPos, std::unique_ptr<ImplEntryType>(pNewEntry) );
141  }
142  else
143  {
144  insPos = nEntriesSize;
145  maEntries.push_back(std::unique_ptr<ImplEntryType>(pNewEntry));
146  }
147  }
148  else
149  {
150  const comphelper::string::NaturalStringSorter &rSorter = GetSorter();
151 
152  const OUString& rStr = pNewEntry->maStr;
153 
154  ImplEntryType* pTemp = GetEntry( nEntriesSize-1 );
155 
156  try
157  {
158  sal_Int32 nComp = rSorter.compare(rStr, pTemp->maStr);
159 
160  // fast insert for sorted data
161  if ( nComp >= 0 )
162  {
163  insPos = nEntriesSize;
164  maEntries.push_back(std::unique_ptr<ImplEntryType>(pNewEntry));
165  }
166  else
167  {
168  pTemp = GetEntry( mnMRUCount );
169 
170  nComp = rSorter.compare(rStr, pTemp->maStr);
171  if ( nComp <= 0 )
172  {
173  insPos = 0;
174  maEntries.insert(maEntries.begin(), std::unique_ptr<ImplEntryType>(pNewEntry));
175  }
176  else
177  {
178  sal_uLong nLow = mnMRUCount;
179  sal_uLong nHigh = maEntries.size()-1;
180  sal_Int32 nMid;
181 
182  // binary search
183  do
184  {
185  nMid = static_cast<sal_Int32>((nLow + nHigh) / 2);
186  pTemp = GetEntry( nMid );
187 
188  nComp = rSorter.compare(rStr, pTemp->maStr);
189 
190  if ( nComp < 0 )
191  nHigh = nMid-1;
192  else
193  {
194  if ( nComp > 0 )
195  nLow = nMid + 1;
196  else
197  break;
198  }
199  }
200  while ( nLow <= nHigh );
201 
202  if ( nComp >= 0 )
203  nMid++;
204 
205  insPos = nMid;
206  maEntries.insert(maEntries.begin()+nMid, std::unique_ptr<ImplEntryType>(pNewEntry));
207  }
208  }
209  }
210  catch (uno::RuntimeException& )
211  {
212  // XXX this is arguable, if the exception occurred because pNewEntry is
213  // garbage you wouldn't insert it. If the exception occurred because the
214  // Collator implementation is garbage then give the user a chance to see
215  // his stuff
216  insPos = 0;
217  maEntries.insert(maEntries.begin(), std::unique_ptr<ImplEntryType>(pNewEntry));
218  }
219 
220  }
221 
222  return insPos;
223 }
224 
225 void ImplEntryList::RemoveEntry( sal_Int32 nPos )
226 {
227  if (0 <= nPos && o3tl::make_unsigned(nPos) < maEntries.size())
228  {
229  std::vector<std::unique_ptr<ImplEntryType> >::iterator iter = maEntries.begin()+ nPos;
230 
231  if ( !!(*iter)->maImage )
232  mnImages--;
233 
234  maEntries.erase(iter);
235  }
236 }
237 
238 sal_Int32 ImplEntryList::FindEntry( std::u16string_view rString, bool bSearchMRUArea ) const
239 {
240  const sal_Int32 nEntries = static_cast<sal_Int32>(maEntries.size());
241  for ( sal_Int32 n = bSearchMRUArea ? 0 : GetMRUCount(); n < nEntries; n++ )
242  {
243  OUString aComp( vcl::I18nHelper::filterFormattingChars( maEntries[n]->maStr ) );
244  if ( aComp == rString )
245  return n;
246  }
247  return LISTBOX_ENTRY_NOTFOUND;
248 }
249 
250 sal_Int32 ImplEntryList::FindMatchingEntry( const OUString& rStr, sal_Int32 nStart, bool bLazy ) const
251 {
252  sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND;
253  sal_Int32 nEntryCount = GetEntryCount();
254 
255  const vcl::I18nHelper& rI18nHelper = mpWindow->GetSettings().GetLocaleI18nHelper();
256  for ( sal_Int32 n = nStart; n < nEntryCount; )
257  {
258  ImplEntryType* pImplEntry = GetEntry( n );
259  bool bMatch;
260  if ( bLazy )
261  {
262  bMatch = rI18nHelper.MatchString( rStr, pImplEntry->maStr );
263  }
264  else
265  {
266  bMatch = pImplEntry->maStr.startsWith(rStr);
267  }
268  if ( bMatch )
269  {
270  nPos = n;
271  break;
272  }
273 
274  n++;
275  }
276 
277  return nPos;
278 }
279 
280 tools::Long ImplEntryList::GetAddedHeight( sal_Int32 i_nEndIndex, sal_Int32 i_nBeginIndex ) const
281 {
282  tools::Long nHeight = 0;
283  sal_Int32 nStart = std::min(i_nEndIndex, i_nBeginIndex);
284  sal_Int32 nStop = std::max(i_nEndIndex, i_nBeginIndex);
285  sal_Int32 nEntryCount = GetEntryCount();
286  if( 0 <= nStop && nStop != LISTBOX_ENTRY_NOTFOUND && nEntryCount != 0 )
287  {
288  // sanity check
289  if( nStop > nEntryCount-1 )
290  nStop = nEntryCount-1;
291  if (nStart < 0)
292  nStart = 0;
293  else if( nStart > nEntryCount-1 )
294  nStart = nEntryCount-1;
295 
296  sal_Int32 nIndex = nStart;
297  while( nIndex != LISTBOX_ENTRY_NOTFOUND && nIndex < nStop )
298  {
299  tools::Long nPosHeight = GetEntryPtr( nIndex )->getHeightWithMargin();
300  if (nHeight > ::std::numeric_limits<tools::Long>::max() - nPosHeight)
301  {
302  SAL_WARN( "vcl", "ImplEntryList::GetAddedHeight: truncated");
303  break;
304  }
305  nHeight += nPosHeight;
306  nIndex++;
307  }
308  }
309  else
310  nHeight = 0;
311  return i_nEndIndex > i_nBeginIndex ? nHeight : -nHeight;
312 }
313 
315 {
316  ImplEntryType* pImplEntry = GetEntry( nPos );
317  return pImplEntry ? pImplEntry->getHeightWithMargin() : 0;
318 }
319 
320 OUString ImplEntryList::GetEntryText( sal_Int32 nPos ) const
321 {
322  OUString aEntryText;
323  ImplEntryType* pImplEntry = GetEntry( nPos );
324  if ( pImplEntry )
325  aEntryText = pImplEntry->maStr;
326  return aEntryText;
327 }
328 
329 bool ImplEntryList::HasEntryImage( sal_Int32 nPos ) const
330 {
331  bool bImage = false;
332  ImplEntryType* pImplEntry = GetEntry( nPos );
333  if ( pImplEntry )
334  bImage = !!pImplEntry->maImage;
335  return bImage;
336 }
337 
338 Image ImplEntryList::GetEntryImage( sal_Int32 nPos ) const
339 {
340  Image aImage;
341  ImplEntryType* pImplEntry = GetEntry( nPos );
342  if ( pImplEntry )
343  aImage = pImplEntry->maImage;
344  return aImage;
345 }
346 
347 void ImplEntryList::SetEntryData( sal_Int32 nPos, void* pNewData )
348 {
349  ImplEntryType* pImplEntry = GetEntry( nPos );
350  if ( pImplEntry )
351  pImplEntry->mpUserData = pNewData;
352 }
353 
354 void* ImplEntryList::GetEntryData( sal_Int32 nPos ) const
355 {
356  ImplEntryType* pImplEntry = GetEntry( nPos );
357  return pImplEntry ? pImplEntry->mpUserData : nullptr;
358 }
359 
360 void ImplEntryList::SetEntryFlags( sal_Int32 nPos, ListBoxEntryFlags nFlags )
361 {
362  ImplEntryType* pImplEntry = GetEntry( nPos );
363  if ( pImplEntry )
364  pImplEntry->mnFlags = nFlags;
365 }
366 
368 {
369  sal_Int32 nSelCount = 0;
370  for ( sal_Int32 n = GetEntryCount(); n; )
371  {
372  ImplEntryType* pImplEntry = GetEntry( --n );
373  if ( pImplEntry->mbIsSelected )
374  nSelCount++;
375  }
376  return nSelCount;
377 }
378 
379 OUString ImplEntryList::GetSelectedEntry( sal_Int32 nIndex ) const
380 {
381  return GetEntryText( GetSelectedEntryPos( nIndex ) );
382 }
383 
384 sal_Int32 ImplEntryList::GetSelectedEntryPos( sal_Int32 nIndex ) const
385 {
386  sal_Int32 nSelEntryPos = LISTBOX_ENTRY_NOTFOUND;
387  sal_Int32 nSel = 0;
388  sal_Int32 nEntryCount = GetEntryCount();
389 
390  for ( sal_Int32 n = 0; n < nEntryCount; n++ )
391  {
392  ImplEntryType* pImplEntry = GetEntry( n );
393  if ( pImplEntry->mbIsSelected )
394  {
395  if ( nSel == nIndex )
396  {
397  nSelEntryPos = n;
398  break;
399  }
400  nSel++;
401  }
402  }
403 
404  return nSelEntryPos;
405 }
406 
407 bool ImplEntryList::IsEntryPosSelected( sal_Int32 nIndex ) const
408 {
409  ImplEntryType* pImplEntry = GetEntry( nIndex );
410  return pImplEntry && pImplEntry->mbIsSelected;
411 }
412 
413 bool ImplEntryList::IsEntrySelectable( sal_Int32 nPos ) const
414 {
415  ImplEntryType* pImplEntry = GetEntry( nPos );
416  return pImplEntry == nullptr || ((pImplEntry->mnFlags & ListBoxEntryFlags::DisableSelection) == ListBoxEntryFlags::NONE);
417 }
418 
419 sal_Int32 ImplEntryList::FindFirstSelectable( sal_Int32 nPos, bool bForward /* = true */ ) const
420 {
421  if( IsEntrySelectable( nPos ) )
422  return nPos;
423 
424  if( bForward )
425  {
426  for( nPos = nPos + 1; nPos < GetEntryCount(); nPos++ )
427  {
428  if( IsEntrySelectable( nPos ) )
429  return nPos;
430  }
431  }
432  else
433  {
434  while( nPos )
435  {
436  nPos--;
437  if( IsEntrySelectable( nPos ) )
438  return nPos;
439  }
440  }
441 
442  return LISTBOX_ENTRY_NOTFOUND;
443 }
444 
446  Control( pParent, 0 ),
447  maEntryList( this ),
448  maQuickSelectionEngine( *this )
449 {
450 
451  mnTop = 0;
452  mnLeft = 0;
453  mnSelectModifier = 0;
455  mbTrack = false;
456  mbTravelSelect = false;
457  mbTrackingSelect = false;
458  mbSelectionChanged = false;
459  mbMouseMoveSelect = false;
460  mbMulti = false;
461  mbGrabFocus = false;
462  mbUserDrawEnabled = false;
463  mbInUserDraw = false;
464  mbReadOnly = false;
465  mbHasFocusRect = false;
466  mbRight = ( nWinStyle & WB_RIGHT );
467  mbCenter = ( nWinStyle & WB_CENTER );
468  mbSimpleMode = ( nWinStyle & WB_SIMPLEMODE );
469  mbSort = ( nWinStyle & WB_SORT );
470  mbIsDropdown = ( nWinStyle & WB_DROPDOWN );
471  mbEdgeBlending = false;
472 
475 
476  GetOutDev()->SetLineColor();
478  SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
479 
481  ImplCalcMetrics();
482 }
483 
485 {
486  disposeOnce();
487 }
488 
490 {
493 }
494 
496 {
497  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
498 
499  ApplyControlFont(rRenderContext, rStyleSettings.GetFieldFont());
500  ApplyControlForeground(rRenderContext, rStyleSettings.GetFieldTextColor());
501 
502  if (IsControlBackground())
503  rRenderContext.SetBackground(GetControlBackground());
504  else
505  rRenderContext.SetBackground(rStyleSettings.GetFieldColor());
506 }
507 
509 {
510  mnMaxWidth = 0;
511  mnMaxTxtWidth = 0;
512  mnMaxImgWidth = 0;
513  mnMaxImgTxtWidth= 0;
514  mnMaxImgHeight = 0;
515 
516  mnTextHeight = static_cast<sal_uInt16>(GetTextHeight());
519 
521  mnMaxHeight = static_cast<sal_uInt16>(maUserItemSize.Height());
522  if ( maUserItemSize.Width() > mnMaxWidth )
523  mnMaxWidth= static_cast<sal_uInt16>(maUserItemSize.Width());
524 
525  for ( sal_Int32 n = maEntryList.GetEntryCount(); n; )
526  {
528  ImplUpdateEntryMetrics( *pEntry );
529  }
530 
532  {
534  maFocusRect.SetSize( aSz );
535  }
536 }
537 
539 {
540  maEntryList.Clear();
541 
543  mnMaxWidth = 0;
544  mnMaxTxtWidth = 0;
545  mnMaxImgTxtWidth= 0;
546  mnMaxImgWidth = 0;
547  mnMaxImgHeight = 0;
548  mnTop = 0;
549  mnLeft = 0;
551 
554 
555  Invalidate();
556 }
557 
559 {
561  maUserItemSize = rSz;
562  ImplCalcMetrics();
563 }
564 
565 namespace {
566 
567 struct ImplEntryMetrics
568 {
569  bool bText;
570  bool bImage;
571  tools::Long nEntryWidth;
572  tools::Long nEntryHeight;
573  tools::Long nTextWidth;
574  tools::Long nImgWidth;
575  tools::Long nImgHeight;
576 };
577 
578 }
579 
581 {
583 }
584 
586 {
587  if (maStrGlyphs.IsValid())
588  // Use pre-calculated result.
589  return &maStrGlyphs;
590 
591  std::unique_ptr<SalLayout> pLayout = pOutputDevice->ImplLayout(
592  maStr, 0, maStr.getLength(), Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly);
593  if (!pLayout)
594  return nullptr;
595 
596  // Remember the calculation result.
597  maStrGlyphs = pLayout->GetGlyphs();
598 
599  return &maStrGlyphs;
600 }
601 
603 {
604  ImplEntryMetrics aMetrics;
605  aMetrics.bText = !rEntry.maStr.isEmpty();
606  aMetrics.bImage = !!rEntry.maImage;
607  aMetrics.nEntryWidth = 0;
608  aMetrics.nEntryHeight = 0;
609  aMetrics.nTextWidth = 0;
610  aMetrics.nImgWidth = 0;
611  aMetrics.nImgHeight = 0;
612 
613  if ( aMetrics.bText )
614  {
616  {
617  // multiline case
618  Size aCurSize( PixelToLogic( GetSizePixel() ) );
619  // set the current size to a large number
620  // GetTextRect should shrink it to the actual size
621  aCurSize.setHeight( 0x7fffff );
622  tools::Rectangle aTextRect( Point( 0, 0 ), aCurSize );
623  aTextRect = GetTextRect( aTextRect, rEntry.maStr, DrawTextFlags::WordBreak | DrawTextFlags::MultiLine );
624  aMetrics.nTextWidth = aTextRect.GetWidth();
625  if( aMetrics.nTextWidth > mnMaxTxtWidth )
626  mnMaxTxtWidth = aMetrics.nTextWidth;
627  aMetrics.nEntryWidth = mnMaxTxtWidth;
628  aMetrics.nEntryHeight = aTextRect.GetHeight() + gnBorder;
629  }
630  else
631  {
632  // normal single line case
633  const SalLayoutGlyphs* pGlyphs = rEntry.GetTextGlyphs(GetOutDev());
634  aMetrics.nTextWidth
635  = static_cast<sal_uInt16>(GetTextWidth(rEntry.maStr, 0, -1, nullptr, pGlyphs));
636  if( aMetrics.nTextWidth > mnMaxTxtWidth )
637  mnMaxTxtWidth = aMetrics.nTextWidth;
638  aMetrics.nEntryWidth = mnMaxTxtWidth;
639  aMetrics.nEntryHeight = mnTextHeight + gnBorder;
640  }
641  }
642  if ( aMetrics.bImage )
643  {
644  Size aImgSz = rEntry.maImage.GetSizePixel();
645  aMetrics.nImgWidth = static_cast<sal_uInt16>(CalcZoom( aImgSz.Width() ));
646  aMetrics.nImgHeight = static_cast<sal_uInt16>(CalcZoom( aImgSz.Height() ));
647 
648  if( aMetrics.nImgWidth > mnMaxImgWidth )
649  mnMaxImgWidth = aMetrics.nImgWidth;
650  if( aMetrics.nImgHeight > mnMaxImgHeight )
651  mnMaxImgHeight = aMetrics.nImgHeight;
652 
653  mnMaxImgTxtWidth = std::max( mnMaxImgTxtWidth, aMetrics.nTextWidth );
654  aMetrics.nEntryHeight = std::max( aMetrics.nImgHeight, aMetrics.nEntryHeight );
655 
656  }
657 
658  bool bIsUserDrawEnabled = IsUserDrawEnabled();
659  if (bIsUserDrawEnabled || aMetrics.bImage)
660  {
661  aMetrics.nEntryWidth = std::max( aMetrics.nImgWidth, maUserItemSize.Width() );
662  if (!bIsUserDrawEnabled && aMetrics.bText)
663  aMetrics.nEntryWidth += aMetrics.nTextWidth + IMG_TXT_DISTANCE;
664  aMetrics.nEntryHeight = std::max( std::max( mnMaxImgHeight, maUserItemSize.Height() ) + 2,
665  aMetrics.nEntryHeight );
666  }
667 
668  if (!aMetrics.bText && !aMetrics.bImage && !bIsUserDrawEnabled)
669  {
670  // entries which have no (aka an empty) text, and no image,
671  // and are not user-drawn, should be shown nonetheless
672  aMetrics.nEntryHeight = mnTextHeight + gnBorder;
673  }
674 
675  if ( aMetrics.nEntryWidth > mnMaxWidth )
676  mnMaxWidth = aMetrics.nEntryWidth;
677  if ( aMetrics.nEntryHeight > mnMaxHeight )
678  mnMaxHeight = aMetrics.nEntryHeight;
679 
680  rEntry.mnHeight = aMetrics.nEntryHeight;
681 }
682 
684 {
685  if ( !IsTravelSelect() && GetEntryList().GetMaxMRUCount() )
686  {
687  // Insert the selected entry as MRU, if not already first MRU
688  sal_Int32 nSelected = GetEntryList().GetSelectedEntryPos( 0 );
689  sal_Int32 nMRUCount = GetEntryList().GetMRUCount();
690  OUString aSelected = GetEntryList().GetEntryText( nSelected );
691  sal_Int32 nFirstMatchingEntryPos = GetEntryList().FindEntry( aSelected, true );
692  if ( nFirstMatchingEntryPos || !nMRUCount )
693  {
694  bool bSelectNewEntry = false;
695  if ( nFirstMatchingEntryPos < nMRUCount )
696  {
697  RemoveEntry( nFirstMatchingEntryPos );
698  nMRUCount--;
699  if ( nFirstMatchingEntryPos == nSelected )
700  bSelectNewEntry = true;
701  }
702  else if ( nMRUCount == GetEntryList().GetMaxMRUCount() )
703  {
704  RemoveEntry( nMRUCount - 1 );
705  nMRUCount--;
706  }
707 
709 
710  ImplEntryType* pNewEntry = new ImplEntryType( aSelected );
711  pNewEntry->mbIsSelected = bSelectNewEntry;
712  GetEntryList().InsertEntry( 0, pNewEntry, false );
713  ImplUpdateEntryMetrics( *pNewEntry );
714  GetEntryList().SetMRUCount( ++nMRUCount );
715  SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
716  maMRUChangedHdl.Call( nullptr );
717  }
718  }
719 
720  maSelectHdl.Call( nullptr );
721  mbSelectionChanged = false;
722 }
723 
724 sal_Int32 ImplListBoxWindow::InsertEntry(sal_Int32 nPos, ImplEntryType* pNewEntry, bool bSort)
725 {
726  assert(nPos >= 0);
728 
730  sal_Int32 nNewPos = maEntryList.InsertEntry( nPos, pNewEntry, bSort );
731 
732  if( GetStyle() & WB_WORDBREAK )
734 
735  ImplUpdateEntryMetrics( *pNewEntry );
736  return nNewPos;
737 }
738 
739 sal_Int32 ImplListBoxWindow::InsertEntry( sal_Int32 nPos, ImplEntryType* pNewEntry )
740 {
741  return InsertEntry(nPos, pNewEntry, mbSort);
742 }
743 
744 void ImplListBoxWindow::RemoveEntry( sal_Int32 nPos )
745 {
747  maEntryList.RemoveEntry( nPos );
750  ImplCalcMetrics();
751 }
752 
754 {
755  maEntryList.SetEntryFlags( nPos, nFlags );
756  ImplEntryType* pEntry = maEntryList.GetMutableEntryPtr( nPos );
757  if( pEntry )
758  ImplUpdateEntryMetrics( *pEntry );
759 }
760 
762 {
763  if ( mbHasFocusRect )
764  HideFocus();
766  mbHasFocusRect = true;
767 }
768 
770 {
771  if ( mbHasFocusRect )
772  {
773  HideFocus();
774  mbHasFocusRect = false;
775  }
776 }
777 
778 sal_Int32 ImplListBoxWindow::GetEntryPosForPoint( const Point& rPoint ) const
779 {
780  tools::Long nY = gnBorder;
781 
782  sal_Int32 nSelect = mnTop;
783  const ImplEntryType* pEntry = maEntryList.GetEntryPtr( nSelect );
784  while (pEntry)
785  {
786  tools::Long nEntryHeight = pEntry->getHeightWithMargin();
787  if (rPoint.Y() <= nEntryHeight + nY)
788  break;
789  nY += nEntryHeight;
790  pEntry = maEntryList.GetEntryPtr( ++nSelect );
791  }
792  if( pEntry == nullptr )
793  nSelect = LISTBOX_ENTRY_NOTFOUND;
794 
795  return nSelect;
796 }
797 
798 bool ImplListBoxWindow::IsVisible( sal_Int32 i_nEntry ) const
799 {
800  bool bRet = false;
801 
802  if( i_nEntry >= mnTop )
803  {
804  if( maEntryList.GetAddedHeight( i_nEntry, mnTop ) <
805  PixelToLogic( GetSizePixel() ).Height() )
806  {
807  bRet = true;
808  }
809  }
810 
811  return bRet;
812 }
813 
815 {
817  return mnMaxHeight + nMargin;
818 }
819 
821 {
822  sal_Int32 nPos = mnTop;
823  tools::Long nWindowHeight = GetSizePixel().Height();
824  sal_Int32 nCount = maEntryList.GetEntryCount();
825  tools::Long nDiff;
826  for( nDiff = 0; nDiff < nWindowHeight && nPos < nCount; nDiff = maEntryList.GetAddedHeight( nPos, mnTop ) )
827  nPos++;
828 
829  if( nDiff > nWindowHeight && nPos > mnTop )
830  nPos--;
831 
832  if( nPos >= nCount )
833  nPos = nCount-1;
834 
835  return nPos;
836 }
837 
839 {
840  mbMouseMoveSelect = false; // only till the first MouseButtonDown
842 
843  if ( !IsReadOnly() )
844  {
845  if( rMEvt.GetClicks() == 1 )
846  {
847  sal_Int32 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
848  if( nSelect != LISTBOX_ENTRY_NOTFOUND )
849  {
852  else
854 
855  mnCurrentPos = nSelect;
856  mbTrackingSelect = true;
857  bool bCurPosChange = (mnCurrentPos != nSelect);
858  (void)SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() ,bCurPosChange);
859  mbTrackingSelect = false;
860  if ( mbGrabFocus )
861  GrabFocus();
862 
864  }
865  }
866  if( rMEvt.GetClicks() == 2 )
867  {
868  maDoubleClickHdl.Call( this );
869  }
870  }
871  else // if ( mbGrabFocus )
872  {
873  GrabFocus();
874  }
875 }
876 
878 {
880  return;
881 
883  if( !aRect.Contains( rMEvt.GetPosPixel() ) )
884  return;
885 
886  if ( IsMouseMoveSelect() )
887  {
888  sal_Int32 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
889  if( nSelect == LISTBOX_ENTRY_NOTFOUND )
890  nSelect = maEntryList.GetEntryCount() - 1;
891  nSelect = std::min( nSelect, GetLastVisibleEntry() );
892  nSelect = std::min( nSelect, static_cast<sal_Int32>( maEntryList.GetEntryCount() - 1 ) );
893  // Select only visible Entries with MouseMove, otherwise Tracking...
894  if ( IsVisible( nSelect ) &&
895  maEntryList.IsEntrySelectable( nSelect ) &&
896  ( ( nSelect != mnCurrentPos ) || !GetEntryList().GetSelectedEntryCount() || ( nSelect != GetEntryList().GetSelectedEntryPos( 0 ) ) ) )
897  {
898  mbTrackingSelect = true;
899  if ( SelectEntries( nSelect, LET_TRACKING ) )
900  {
901  // When list box selection change by mouse move, notify
902  // VclEventId::ListboxSelect vcl event.
903  maListItemSelectHdl.Call(nullptr);
904  }
905  mbTrackingSelect = false;
906  }
907  }
908 
909  // if the DD button was pressed and someone moved into the ListBox
910  // with the mouse button pressed...
911  if ( rMEvt.IsLeft() && !rMEvt.IsSynthetic() )
912  {
915  else
917 
919  }
920 }
921 
923 {
924  while ( GetEntryList().GetSelectedEntryCount() )
925  {
926  sal_Int32 nS = GetEntryList().GetSelectedEntryPos( 0 );
927  SelectEntry( nS, false );
928  }
929 }
930 
931 void ImplListBoxWindow::SelectEntry( sal_Int32 nPos, bool bSelect )
932 {
933  if( (maEntryList.IsEntryPosSelected( nPos ) == bSelect) || !maEntryList.IsEntrySelectable( nPos ) )
934  return;
935 
937  if( bSelect )
938  {
939  if( !mbMulti )
940  {
941  // deselect the selected entry
942  sal_Int32 nDeselect = GetEntryList().GetSelectedEntryPos( 0 );
943  if( nDeselect != LISTBOX_ENTRY_NOTFOUND )
944  {
945  //SelectEntryPos( nDeselect, false );
946  GetEntryList().SelectEntry( nDeselect, false );
947  if (IsUpdateMode() && IsReallyVisible())
948  Invalidate();
949  }
950  }
951  maEntryList.SelectEntry( nPos, true );
952  mnCurrentPos = nPos;
953  if ( ( nPos != LISTBOX_ENTRY_NOTFOUND ) && IsUpdateMode() )
954  {
955  Invalidate();
956  if ( !IsVisible( nPos ) )
957  {
959  sal_Int32 nVisibleEntries = GetLastVisibleEntry()-mnTop;
960  if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
961  {
962  Resize();
963  ShowProminentEntry( nPos );
964  }
965  else
966  {
967  ShowProminentEntry( nPos );
968  }
969  }
970  }
971  }
972  else
973  {
974  maEntryList.SelectEntry( nPos, false );
975  Invalidate();
976  }
977  mbSelectionChanged = true;
978 }
979 
980 bool ImplListBoxWindow::SelectEntries( sal_Int32 nSelect, LB_EVENT_TYPE eLET, bool bShift, bool bCtrl, bool bSelectPosChange /*=FALSE*/ )
981 {
982  bool bSelectionChanged = false;
983 
984  if( IsEnabled() && maEntryList.IsEntrySelectable( nSelect ) )
985  {
986  bool bFocusChanged = false;
987 
988  // here (Single-ListBox) only one entry can be deselected
989  if( !mbMulti )
990  {
991  sal_Int32 nDeselect = maEntryList.GetSelectedEntryPos( 0 );
992  if( nSelect != nDeselect )
993  {
994  SelectEntry( nSelect, true );
995  maEntryList.SetLastSelected( nSelect );
996  bFocusChanged = true;
997  bSelectionChanged = true;
998  }
999  }
1000  // MultiListBox without Modifier
1001  else if( mbSimpleMode && !bCtrl && !bShift )
1002  {
1003  sal_Int32 nEntryCount = maEntryList.GetEntryCount();
1004  for ( sal_Int32 nPos = 0; nPos < nEntryCount; nPos++ )
1005  {
1006  bool bSelect = nPos == nSelect;
1007  if ( maEntryList.IsEntryPosSelected( nPos ) != bSelect )
1008  {
1009  SelectEntry( nPos, bSelect );
1010  bFocusChanged = true;
1011  bSelectionChanged = true;
1012  }
1013  }
1014  maEntryList.SetLastSelected( nSelect );
1015  maEntryList.SetSelectionAnchor( nSelect );
1016  }
1017  // MultiListBox only with CTRL/SHIFT or not in SimpleMode
1018  else if( ( !mbSimpleMode /* && !bShift */ ) || ( mbSimpleMode && ( bCtrl || bShift ) ) )
1019  {
1020  // Space for selection change
1021  if( !bShift && ( ( eLET == LET_KEYSPACE ) || ( eLET == LET_MBDOWN ) ) )
1022  {
1023  bool bSelect = !maEntryList.IsEntryPosSelected( nSelect );
1024  SelectEntry( nSelect, bSelect );
1025  maEntryList.SetLastSelected( nSelect );
1026  maEntryList.SetSelectionAnchor( nSelect );
1027  if ( !maEntryList.IsEntryPosSelected( nSelect ) )
1029  bFocusChanged = true;
1030  bSelectionChanged = true;
1031  }
1032  else if( ( ( eLET == LET_TRACKING ) && ( nSelect != mnCurrentPos ) ) ||
1033  ( bShift && ( ( eLET == LET_KEYMOVE ) || ( eLET == LET_MBDOWN ) ) ) )
1034  {
1035  mnCurrentPos = nSelect;
1036  bFocusChanged = true;
1037 
1038  sal_Int32 nAnchor = maEntryList.GetSelectionAnchor();
1039  if( ( nAnchor == LISTBOX_ENTRY_NOTFOUND ) && maEntryList.GetSelectedEntryCount() )
1040  {
1042  }
1043  if( nAnchor != LISTBOX_ENTRY_NOTFOUND )
1044  {
1045  // All entries from Anchor to nSelect have to be selected
1046  sal_Int32 nStart = std::min( nSelect, nAnchor );
1047  sal_Int32 nEnd = std::max( nSelect, nAnchor );
1048  for ( sal_Int32 n = nStart; n <= nEnd; n++ )
1049  {
1050  if ( !maEntryList.IsEntryPosSelected( n ) )
1051  {
1052  SelectEntry( n, true );
1053  bSelectionChanged = true;
1054  }
1055  }
1056 
1057  // if appropriate some more has to be deselected...
1058  sal_Int32 nLast = maEntryList.GetLastSelected();
1059  if ( nLast != LISTBOX_ENTRY_NOTFOUND )
1060  {
1061  if ( ( nLast > nSelect ) && ( nLast > nAnchor ) )
1062  {
1063  for ( sal_Int32 n = nSelect+1; n <= nLast; n++ )
1064  {
1065  if ( maEntryList.IsEntryPosSelected( n ) )
1066  {
1067  SelectEntry( n, false );
1068  bSelectionChanged = true;
1069  }
1070  }
1071  }
1072  else if ( ( nLast < nSelect ) && ( nLast < nAnchor ) )
1073  {
1074  for ( sal_Int32 n = nLast; n < nSelect; n++ )
1075  {
1076  if ( maEntryList.IsEntryPosSelected( n ) )
1077  {
1078  SelectEntry( n, false );
1079  bSelectionChanged = true;
1080  }
1081  }
1082  }
1083  }
1084  maEntryList.SetLastSelected( nSelect );
1085  }
1086  }
1087  else if( eLET != LET_TRACKING )
1088  {
1090  Invalidate();
1091  bFocusChanged = true;
1092  }
1093  }
1094  else if( bShift )
1095  {
1096  bFocusChanged = true;
1097  }
1098 
1099  if( bSelectionChanged )
1100  mbSelectionChanged = true;
1101 
1102  if( bFocusChanged )
1103  {
1104  tools::Long nHeightDiff = maEntryList.GetAddedHeight( nSelect, mnTop );
1105  maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1106  Size aSz( maFocusRect.GetWidth(),
1107  maEntryList.GetEntryHeight( nSelect ) );
1108  maFocusRect.SetSize( aSz );
1109  if( HasFocus() )
1111  if (bSelectPosChange)
1112  {
1113  maFocusHdl.Call(nSelect);
1114  }
1115  }
1117  }
1118  return bSelectionChanged;
1119 }
1120 
1122 {
1124  bool bInside = aRect.Contains( rTEvt.GetMouseEvent().GetPosPixel() );
1125 
1126  if( rTEvt.IsTrackingCanceled() || rTEvt.IsTrackingEnded() ) // MouseButtonUp
1127  {
1128  if ( bInside && !rTEvt.IsTrackingCanceled() )
1129  {
1131  ImplCallSelect();
1132  }
1133  else
1134  {
1135  maCancelHdl.Call( nullptr );
1136  if ( !mbMulti )
1137  {
1138  mbTrackingSelect = true;
1140  mbTrackingSelect = false;
1142  {
1144  maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1145  Size aSz( maFocusRect.GetWidth(),
1147  maFocusRect.SetSize( aSz );
1149  }
1150  }
1151  }
1152 
1153  mbTrack = false;
1154  }
1155  else
1156  {
1157  bool bTrackOrQuickClick = mbTrack;
1158  if( !mbTrack )
1159  {
1160  if ( bInside )
1161  {
1162  mbTrack = true;
1163  }
1164 
1165  // this case only happens, if the mouse button is pressed very briefly
1166  if( rTEvt.IsTrackingEnded() && mbTrack )
1167  {
1168  bTrackOrQuickClick = true;
1169  mbTrack = false;
1170  }
1171  }
1172 
1173  if( bTrackOrQuickClick )
1174  {
1175  MouseEvent aMEvt = rTEvt.GetMouseEvent();
1176  Point aPt( aMEvt.GetPosPixel() );
1177  bool bShift = aMEvt.IsShift();
1178  bool bCtrl = aMEvt.IsMod1();
1179 
1180  sal_Int32 nSelect = LISTBOX_ENTRY_NOTFOUND;
1181  if( aPt.Y() < 0 )
1182  {
1184  {
1185  nSelect = mnCurrentPos ? ( mnCurrentPos - 1 ) : 0;
1186  if( nSelect < mnTop )
1187  SetTopEntry( mnTop-1 );
1188  }
1189  }
1190  else if( aPt.Y() > GetOutputSizePixel().Height() )
1191  {
1193  {
1194  nSelect = std::min( static_cast<sal_Int32>(mnCurrentPos+1), static_cast<sal_Int32>(maEntryList.GetEntryCount()-1) );
1195  if( nSelect >= GetLastVisibleEntry() )
1196  SetTopEntry( mnTop+1 );
1197  }
1198  }
1199  else
1200  {
1201  nSelect = static_cast<sal_Int32>( ( aPt.Y() + gnBorder ) / mnMaxHeight ) + mnTop;
1202  nSelect = std::min( nSelect, GetLastVisibleEntry() );
1203  nSelect = std::min( nSelect, static_cast<sal_Int32>( maEntryList.GetEntryCount() - 1 ) );
1204  }
1205 
1206  if ( bInside )
1207  {
1208  if ( ( nSelect != mnCurrentPos ) || !GetEntryList().GetSelectedEntryCount() )
1209  {
1210  mbTrackingSelect = true;
1211  SelectEntries(nSelect, LET_TRACKING, bShift, bCtrl);
1212  mbTrackingSelect = false;
1213  }
1214  }
1215  else
1216  {
1217  if ( !mbMulti && GetEntryList().GetSelectedEntryCount() )
1218  {
1219  mbTrackingSelect = true;
1220  SelectEntry( GetEntryList().GetSelectedEntryPos( 0 ), false );
1221  mbTrackingSelect = false;
1222  }
1223  }
1224  mnCurrentPos = nSelect;
1226  {
1228  }
1229  else
1230  {
1232  maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1234  maFocusRect.SetSize( aSz );
1236  }
1237  }
1238  }
1239 }
1240 
1242 {
1243  if( !ProcessKeyInput( rKEvt ) )
1244  Control::KeyInput( rKEvt );
1245 }
1246 
1248 {
1249  // entry to be selected
1250  sal_Int32 nSelect = LISTBOX_ENTRY_NOTFOUND;
1251  LB_EVENT_TYPE eLET = LET_KEYMOVE;
1252 
1253  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1254 
1255  bool bShift = aKeyCode.IsShift();
1256  bool bCtrl = aKeyCode.IsMod1() || aKeyCode.IsMod3();
1257  bool bMod2 = aKeyCode.IsMod2();
1258  bool bDone = false;
1259  bool bHandleKey = false;
1260 
1261  switch( aKeyCode.GetCode() )
1262  {
1263  case KEY_UP:
1264  {
1265  if ( IsReadOnly() )
1266  {
1267  if ( GetTopEntry() )
1268  SetTopEntry( GetTopEntry()-1 );
1269  }
1270  else if ( !bMod2 )
1271  {
1273  {
1274  nSelect = maEntryList.FindFirstSelectable( 0 );
1275  }
1276  else if ( mnCurrentPos )
1277  {
1278  // search first selectable above the current position
1279  nSelect = maEntryList.FindFirstSelectable( mnCurrentPos - 1, false );
1280  }
1281 
1282  if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect < mnTop ) )
1283  SetTopEntry( mnTop-1 );
1284 
1285  bDone = true;
1286  }
1288  }
1289  break;
1290 
1291  case KEY_DOWN:
1292  {
1293  if ( IsReadOnly() )
1294  {
1295  SetTopEntry( GetTopEntry()+1 );
1296  }
1297  else if ( !bMod2 )
1298  {
1300  {
1301  nSelect = maEntryList.FindFirstSelectable( 0 );
1302  }
1303  else if ( (mnCurrentPos+1) < maEntryList.GetEntryCount() )
1304  {
1305  // search first selectable below the current position
1306  nSelect = maEntryList.FindFirstSelectable( mnCurrentPos + 1 );
1307  }
1308 
1309  if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= GetLastVisibleEntry() ) )
1310  SetTopEntry( mnTop+1 );
1311 
1312  bDone = true;
1313  }
1315  }
1316  break;
1317 
1318  case KEY_PAGEUP:
1319  {
1320  if ( IsReadOnly() )
1321  {
1322  sal_Int32 nCurVis = GetLastVisibleEntry() - mnTop +1;
1323  SetTopEntry( ( mnTop > nCurVis ) ?
1324  (mnTop-nCurVis) : 0 );
1325  }
1326  else if ( !bCtrl && !bMod2 )
1327  {
1329  {
1330  nSelect = maEntryList.FindFirstSelectable( 0 );
1331  }
1332  else if ( mnCurrentPos )
1333  {
1334  if( mnCurrentPos == mnTop )
1335  {
1336  sal_Int32 nCurVis = GetLastVisibleEntry() - mnTop +1;
1337  SetTopEntry( ( mnTop > nCurVis ) ? ( mnTop-nCurVis+1 ) : 0 );
1338  }
1339 
1340  // find first selectable starting from mnTop looking forward
1341  nSelect = maEntryList.FindFirstSelectable( mnTop );
1342  }
1343  bDone = true;
1344  }
1346  }
1347  break;
1348 
1349  case KEY_PAGEDOWN:
1350  {
1351  if ( IsReadOnly() )
1352  {
1354  }
1355  else if ( !bCtrl && !bMod2 )
1356  {
1358  {
1359  nSelect = maEntryList.FindFirstSelectable( 0 );
1360  }
1361  else if ( (mnCurrentPos+1) < maEntryList.GetEntryCount() )
1362  {
1363  sal_Int32 nCount = maEntryList.GetEntryCount();
1364  sal_Int32 nCurVis = GetLastVisibleEntry() - mnTop;
1365  sal_Int32 nTmp = std::min( nCurVis, nCount );
1366  nTmp += mnTop - 1;
1367  if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 )
1368  {
1369  tools::Long nTmp2 = std::min( static_cast<tools::Long>(nCount-nCurVis), static_cast<tools::Long>(static_cast<tools::Long>(mnTop)+static_cast<tools::Long>(nCurVis)-1) );
1370  nTmp2 = std::max( tools::Long(0) , nTmp2 );
1371  nTmp = static_cast<sal_Int32>(nTmp2+(nCurVis-1) );
1372  SetTopEntry( static_cast<sal_Int32>(nTmp2) );
1373  }
1374  // find first selectable starting from nTmp looking backwards
1375  nSelect = maEntryList.FindFirstSelectable( nTmp, false );
1376  }
1377  bDone = true;
1378  }
1380  }
1381  break;
1382 
1383  case KEY_HOME:
1384  {
1385  if ( IsReadOnly() )
1386  {
1387  SetTopEntry( 0 );
1388  }
1389  else if ( !bCtrl && !bMod2 && mnCurrentPos )
1390  {
1392  if( mnTop != 0 )
1393  SetTopEntry( 0 );
1394 
1395  bDone = true;
1396  }
1398  }
1399  break;
1400 
1401  case KEY_END:
1402  {
1403  if ( IsReadOnly() )
1404  {
1405  SetTopEntry( 0xFFFF );
1406  }
1407  else if ( !bCtrl && !bMod2 )
1408  {
1410  {
1411  nSelect = maEntryList.FindFirstSelectable( 0 );
1412  }
1413  else if ( (mnCurrentPos+1) < maEntryList.GetEntryCount() )
1414  {
1415  sal_Int32 nCount = maEntryList.GetEntryCount();
1416  nSelect = maEntryList.FindFirstSelectable( nCount - 1, false );
1417  sal_Int32 nCurVis = GetLastVisibleEntry() - mnTop + 1;
1418  if( nCount > nCurVis )
1419  SetTopEntry( nCount - nCurVis );
1420  }
1421  bDone = true;
1422  }
1424  }
1425  break;
1426 
1427  case KEY_LEFT:
1428  {
1429  if ( !bCtrl && !bMod2 )
1430  {
1431  ScrollHorz( -HORZ_SCROLL );
1432  bDone = true;
1433  }
1435  }
1436  break;
1437 
1438  case KEY_RIGHT:
1439  {
1440  if ( !bCtrl && !bMod2 )
1441  {
1443  bDone = true;
1444  }
1446  }
1447  break;
1448 
1449  case KEY_RETURN:
1450  {
1451  if ( !bMod2 && !IsReadOnly() )
1452  {
1454  ImplCallSelect();
1455  bDone = false; // do not catch RETURN
1456  }
1458  }
1459  break;
1460 
1461  case KEY_SPACE:
1462  {
1463  if ( !bMod2 && !IsReadOnly() )
1464  {
1465  if( mbMulti && ( !mbSimpleMode || ( mbSimpleMode && bCtrl && !bShift ) ) )
1466  {
1467  nSelect = mnCurrentPos;
1468  eLET = LET_KEYSPACE;
1469  }
1470  bDone = true;
1471  }
1472  bHandleKey = true;
1473  }
1474  break;
1475 
1476  case KEY_A:
1477  {
1478  if( bCtrl && mbMulti )
1479  {
1480  // paint only once
1481  bool bUpdates = IsUpdateMode();
1482  SetUpdateMode( false );
1483 
1484  sal_Int32 nEntryCount = maEntryList.GetEntryCount();
1485  for( sal_Int32 i = 0; i < nEntryCount; i++ )
1486  SelectEntry( i, true );
1487 
1488  // tdf#97066 - Update selected items
1489  ImplCallSelect();
1490 
1491  // restore update mode
1492  SetUpdateMode( bUpdates );
1493  Invalidate();
1494 
1496 
1497  bDone = true;
1498  }
1499  else
1500  {
1501  bHandleKey = true;
1502  }
1503  }
1504  break;
1505 
1506  default:
1507  bHandleKey = true;
1508  break;
1509  }
1510  if (bHandleKey && !IsReadOnly())
1511  {
1512  bDone = maQuickSelectionEngine.HandleKeyEvent( rKEvt );
1513  }
1514 
1515  if ( ( nSelect != LISTBOX_ENTRY_NOTFOUND )
1516  && ( ( !maEntryList.IsEntryPosSelected( nSelect ) )
1517  || ( eLET == LET_KEYSPACE )
1518  )
1519  )
1520  {
1521  SAL_WARN_IF( maEntryList.IsEntryPosSelected( nSelect ) && !mbMulti, "vcl", "ImplListBox: Selecting same Entry" );
1522  sal_Int32 nCount = maEntryList.GetEntryCount();
1523  if (nSelect >= nCount)
1524  nSelect = nCount ? nCount-1 : LISTBOX_ENTRY_NOTFOUND;
1525  bool bCurPosChange = (mnCurrentPos != nSelect);
1526  mnCurrentPos = nSelect;
1527  if(SelectEntries( nSelect, eLET, bShift, bCtrl, bCurPosChange))
1528  {
1529  // tdf#129043 Correctly deliver events when changing values with arrow keys in combobox
1530  if (mbIsDropdown && IsReallyVisible())
1531  mbTravelSelect = true;
1533  ImplCallSelect();
1534  mbTravelSelect = false;
1535  }
1536  }
1537 
1538  return bDone;
1539 }
1540 
1541 namespace
1542 {
1543  vcl::StringEntryIdentifier lcl_getEntry( const ImplEntryList& _rList, sal_Int32 _nPos, OUString& _out_entryText )
1544  {
1545  OSL_PRECOND( ( _nPos != LISTBOX_ENTRY_NOTFOUND ), "lcl_getEntry: invalid position!" );
1546  sal_Int32 nEntryCount( _rList.GetEntryCount() );
1547  if ( _nPos >= nEntryCount )
1548  _nPos = 0;
1549  _out_entryText = _rList.GetEntryText( _nPos );
1550 
1551  // vcl::StringEntryIdentifier does not allow for 0 values, but our position is 0-based
1552  // => normalize
1553  return reinterpret_cast< vcl::StringEntryIdentifier >( _nPos + 1 );
1554  }
1555 
1556  sal_Int32 lcl_getEntryPos( vcl::StringEntryIdentifier _entry )
1557  {
1558  // our pos is 0-based, but StringEntryIdentifier does not allow for a NULL
1559  return static_cast< sal_Int32 >( reinterpret_cast< sal_Int64 >( _entry ) ) - 1;
1560  }
1561 }
1562 
1564 {
1565  return lcl_getEntry( GetEntryList(), ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) ? 0 : mnCurrentPos, _out_entryText );
1566 }
1567 
1569 {
1570  sal_Int32 nNextPos = lcl_getEntryPos( _currentEntry ) + 1;
1571  return lcl_getEntry( GetEntryList(), nNextPos, _out_entryText );
1572 }
1573 
1575 {
1576  sal_Int32 nSelect = lcl_getEntryPos( _entry );
1577  if ( maEntryList.IsEntryPosSelected( nSelect ) )
1578  {
1579  // ignore that. This method is a callback from the QuickSelectionEngine, which means the user attempted
1580  // to select the given entry by typing its starting letters. No need to act.
1581  return;
1582  }
1583 
1584  // normalize
1585  OSL_ENSURE( nSelect < maEntryList.GetEntryCount(), "ImplListBoxWindow::SelectEntry: how that?" );
1586  sal_Int32 nCount = maEntryList.GetEntryCount();
1587  if (nSelect >= nCount)
1588  nSelect = nCount ? nCount-1 : LISTBOX_ENTRY_NOTFOUND;
1589 
1590  // make visible
1591  ShowProminentEntry( nSelect );
1592 
1593  // actually select
1594  mnCurrentPos = nSelect;
1595  if ( SelectEntries( nSelect, LET_KEYMOVE ) )
1596  {
1597  mbTravelSelect = true;
1598  mnSelectModifier = 0;
1599  ImplCallSelect();
1600  mbTravelSelect = false;
1601  }
1602 }
1603 
1604 void ImplListBoxWindow::ImplPaint(vcl::RenderContext& rRenderContext, sal_Int32 nPos)
1605 {
1606  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1607 
1608  const ImplEntryType* pEntry = maEntryList.GetEntryPtr( nPos );
1609  if (!pEntry)
1610  return;
1611 
1612  tools::Long nWidth = GetOutputSizePixel().Width();
1614  tools::Rectangle aRect(Point(0, nY), Size(nWidth, pEntry->getHeightWithMargin()));
1615 
1616  bool bSelected = maEntryList.IsEntryPosSelected(nPos);
1617  if (bSelected)
1618  {
1619  rRenderContext.SetTextColor(!IsEnabled() ? rStyleSettings.GetDisableColor() : rStyleSettings.GetHighlightTextColor());
1620  rRenderContext.SetFillColor(rStyleSettings.GetHighlightColor());
1621  rRenderContext.SetLineColor();
1622  rRenderContext.DrawRect(aRect);
1623  }
1624  else
1625  {
1626  ApplySettings(rRenderContext);
1627  if (!IsEnabled())
1628  rRenderContext.SetTextColor(rStyleSettings.GetDisableColor());
1629  }
1630  rRenderContext.SetTextFillColor();
1631 
1632  if (IsUserDrawEnabled())
1633  {
1634  mbInUserDraw = true;
1635  mnUserDrawEntry = nPos;
1636  aRect.AdjustLeft( -mnLeft );
1637  if (nPos < GetEntryList().GetMRUCount())
1638  nPos = GetEntryList().FindEntry(GetEntryList().GetEntryText(nPos));
1639  nPos = nPos - GetEntryList().GetMRUCount();
1640 
1641  UserDrawEvent aUDEvt(&rRenderContext, aRect, nPos, bSelected);
1642  maUserDrawHdl.Call( &aUDEvt );
1643  mbInUserDraw = false;
1644  }
1645  else
1646  {
1647  DrawEntry(rRenderContext, nPos, true, true);
1648  }
1649 }
1650 
1651 void ImplListBoxWindow::DrawEntry(vcl::RenderContext& rRenderContext, sal_Int32 nPos, bool bDrawImage, bool bDrawText)
1652 {
1653  const ImplEntryType* pEntry = maEntryList.GetEntryPtr(nPos);
1654  if (!pEntry)
1655  return;
1656 
1657  tools::Long nEntryHeight = pEntry->getHeightWithMargin();
1658 
1659  // when changing this function don't forget to adjust ImplWin::DrawEntry()
1660 
1661  if (mbInUserDraw)
1662  nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU
1663 
1665 
1666  if (bDrawImage && maEntryList.HasImages())
1667  {
1668  Image aImage = maEntryList.GetEntryImage(nPos);
1669  if (!!aImage)
1670  {
1671  Size aImgSz = aImage.GetSizePixel();
1672  Point aPtImg(gnBorder - mnLeft, nY + ((nEntryHeight - aImgSz.Height()) / 2));
1673 
1674  if (!IsZoom())
1675  {
1676  rRenderContext.DrawImage(aPtImg, aImage);
1677  }
1678  else
1679  {
1680  aImgSz.setWidth( CalcZoom(aImgSz.Width()) );
1681  aImgSz.setHeight( CalcZoom(aImgSz.Height()) );
1682  rRenderContext.DrawImage(aPtImg, aImgSz, aImage);
1683  }
1684 
1685  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1686  const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
1687 
1688  if (nEdgeBlendingPercent && aImgSz.Width() && aImgSz.Height())
1689  {
1690  const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
1691  const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
1692  const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
1693  const BitmapEx aBlendFrame(createBlendFrame(aImgSz, nAlpha, rTopLeft, rBottomRight));
1694 
1695  if (!aBlendFrame.IsEmpty())
1696  {
1697  rRenderContext.DrawBitmapEx(aPtImg, aBlendFrame);
1698  }
1699  }
1700  }
1701  }
1702 
1703  if (bDrawText)
1704  {
1705  OUString aStr(maEntryList.GetEntryText(nPos));
1706  if (!aStr.isEmpty())
1707  {
1708  tools::Long nMaxWidth = std::max(mnMaxWidth, GetOutputSizePixel().Width() - 2 * gnBorder);
1709  // a multiline entry should only be as wide as the window
1710  if (pEntry->mnFlags & ListBoxEntryFlags::MultiLine)
1711  nMaxWidth = GetOutputSizePixel().Width() - 2 * gnBorder;
1712 
1713  tools::Rectangle aTextRect(Point(gnBorder - mnLeft, nY),
1714  Size(nMaxWidth, nEntryHeight));
1715 
1717  {
1718  tools::Long nImageWidth = std::max(mnMaxImgWidth, maUserItemSize.Width());
1719  aTextRect.AdjustLeft(nImageWidth + IMG_TXT_DISTANCE );
1720  }
1721 
1722  DrawTextFlags nDrawStyle = ImplGetTextStyle();
1723  if (pEntry->mnFlags & ListBoxEntryFlags::MultiLine)
1724  nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS;
1726  nDrawStyle |= DrawTextFlags::Disable;
1727 
1728  rRenderContext.DrawText(aTextRect, aStr, nDrawStyle);
1729  }
1730  }
1731 
1732  if ( !maSeparators.empty() && ( isSeparator(nPos) || isSeparator(nPos-1) ) )
1733  {
1734  Color aOldLineColor(rRenderContext.GetLineColor());
1735  rRenderContext.SetLineColor((GetBackground() != COL_LIGHTGRAY) ? COL_LIGHTGRAY : COL_GRAY);
1736  Point aStartPos(0, nY);
1737  if (isSeparator(nPos))
1738  aStartPos.AdjustY(pEntry->getHeightWithMargin() - 1 );
1739  Point aEndPos(aStartPos);
1740  aEndPos.setX( GetOutputSizePixel().Width() );
1741  rRenderContext.DrawLine(aStartPos, aEndPos);
1742  rRenderContext.SetLineColor(aOldLineColor);
1743  }
1744 }
1745 
1747 {
1748  mxLayoutData.emplace();
1749  const_cast<ImplListBoxWindow*>(this)->Invalidate(tools::Rectangle(Point(0, 0), GetOutDev()->GetOutputSize()));
1750 }
1751 
1753 {
1754  sal_Int32 nCount = maEntryList.GetEntryCount();
1755 
1756  bool bShowFocusRect = mbHasFocusRect;
1757  if (mbHasFocusRect)
1759 
1760  tools::Long nY = 0; // + gnBorder;
1761  tools::Long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + gnBorder;
1762 
1763  for (sal_Int32 i = mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++)
1764  {
1765  const ImplEntryType* pEntry = maEntryList.GetEntryPtr(i);
1766  tools::Long nEntryHeight = pEntry->getHeightWithMargin();
1767  if (nY + nEntryHeight >= rRect.Top() &&
1768  nY <= rRect.Bottom() + mnMaxHeight)
1769  {
1770  ImplPaint(rRenderContext, i);
1771  }
1772  nY += nEntryHeight;
1773  }
1774 
1776  maFocusRect.SetPos(Point(0, nHeightDiff));
1778  maFocusRect.SetSize(aSz);
1779  if (HasFocus() && bShowFocusRect)
1781 }
1782 
1784 {
1786  {
1787  // This widget is explicitly double-buffered, so avoid partial paints.
1788  tools::Rectangle aRect(Point(0, 0), GetOutputSizePixel());
1789  ImplDoPaint(rRenderContext, aRect);
1790  }
1791  else
1792  ImplDoPaint(rRenderContext, rRect);
1793 }
1794 
1796 {
1797  // FIXME: ListBoxEntryFlags::MultiLine
1798 
1799  const sal_Int32 nCount = maEntryList.GetEntryCount()-mnTop;
1800  tools::Long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + gnBorder;
1801  sal_uInt16 nEntries = static_cast< sal_uInt16 >( ( nHeight + mnMaxHeight - 1 ) / mnMaxHeight );
1802  if( nEntries > nCount )
1803  nEntries = static_cast<sal_uInt16>(nCount);
1804 
1805  return nEntries;
1806 }
1807 
1809 {
1810  Control::Resize();
1811 
1812  bool bShowFocusRect = mbHasFocusRect;
1813  if ( bShowFocusRect )
1815 
1817  {
1819  maFocusRect.SetSize( aSz );
1820  }
1821 
1822  if ( bShowFocusRect )
1824 
1826 }
1827 
1829 {
1830  sal_Int32 nPos = mnCurrentPos;
1831  if ( nPos == LISTBOX_ENTRY_NOTFOUND )
1832  nPos = 0;
1833  tools::Long nHeightDiff = maEntryList.GetAddedHeight( nPos, mnTop );
1834  maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1836  maFocusRect.SetSize( aSz );
1839 }
1840 
1842 {
1845 }
1846 
1847 void ImplListBoxWindow::SetTopEntry( sal_Int32 nTop )
1848 {
1849  if( maEntryList.GetEntryCount() == 0 )
1850  return;
1851 
1852  tools::Long nWHeight = PixelToLogic( GetSizePixel() ).Height();
1853 
1854  sal_Int32 nLastEntry = maEntryList.GetEntryCount()-1;
1855  if( nTop > nLastEntry )
1856  nTop = nLastEntry;
1857  const ImplEntryType* pLast = maEntryList.GetEntryPtr( nLastEntry );
1858  while( nTop > 0 && maEntryList.GetAddedHeight( nLastEntry, nTop-1 ) + pLast->getHeightWithMargin() <= nWHeight )
1859  nTop--;
1860 
1861  if ( nTop == mnTop )
1862  return;
1863 
1865  tools::Long nDiff = maEntryList.GetAddedHeight( mnTop, nTop );
1866  PaintImmediately();
1868  mnTop = nTop;
1869  Scroll( 0, nDiff );
1870  PaintImmediately();
1871  if( HasFocus() )
1873  maScrollHdl.Call( this );
1874 }
1875 
1876 void ImplListBoxWindow::ShowProminentEntry( sal_Int32 nEntryPos )
1877 {
1878  SetTopEntry( nEntryPos );
1879 }
1880 
1882 {
1883  ScrollHorz( n - mnLeft );
1884 }
1885 
1887 {
1888  tools::Long nDiff = 0;
1889  if ( n > 0 )
1890  {
1891  tools::Long nWidth = GetOutputSizePixel().Width();
1892  if( ( mnMaxWidth - mnLeft + n ) > nWidth )
1893  nDiff = n;
1894  }
1895  else if ( n < 0 )
1896  {
1897  if( mnLeft )
1898  {
1899  tools::Long nAbs = -n;
1900  nDiff = - std::min( mnLeft, nAbs );
1901  }
1902  }
1903 
1904  if ( nDiff )
1905  {
1907  mnLeft = sal::static_int_cast<sal_uInt16>(mnLeft + nDiff);
1908  PaintImmediately();
1910  Scroll( -nDiff, 0 );
1911  PaintImmediately();
1912  if( HasFocus() )
1914  maScrollHdl.Call( this );
1915  }
1916 }
1917 
1919 {
1920  maSeparators.clear();
1921 
1922  if ( n != LISTBOX_ENTRY_NOTFOUND )
1923  {
1924  maSeparators.insert( n );
1925  }
1926 }
1927 
1929 {
1930  if (!maSeparators.empty())
1931  return *(maSeparators.begin());
1932  else
1933  return LISTBOX_ENTRY_NOTFOUND;
1934 }
1935 
1936 bool ImplListBoxWindow::isSeparator( const sal_Int32 &n) const
1937 {
1938  return maSeparators.find(n) != maSeparators.end();
1939 }
1940 
1941 Size ImplListBoxWindow::CalcSize(sal_Int32 nMaxLines) const
1942 {
1943  // FIXME: ListBoxEntryFlags::MultiLine
1944 
1945  Size aSz;
1946  aSz.setHeight(nMaxLines * GetEntryHeightWithMargin());
1947  aSz.setWidth( mnMaxWidth + 2*gnBorder );
1948  return aSz;
1949 }
1950 
1952 {
1953  const ImplEntryType* pEntry = maEntryList.GetEntryPtr( nItem );
1954  Size aSz( GetSizePixel().Width(), pEntry ? pEntry->getHeightWithMargin() : GetEntryHeightWithMargin() );
1956  tools::Rectangle aRect( Point( 0, nY ), aSz );
1957  return aRect;
1958 }
1959 
1961 {
1962  Control::StateChanged( nType );
1963 
1964  if ( nType == StateChangedType::Zoom )
1965  {
1967  ImplCalcMetrics();
1968  Invalidate();
1969  }
1970  else if ( nType == StateChangedType::UpdateMode )
1971  {
1972  if ( IsUpdateMode() && IsReallyVisible() )
1973  Invalidate();
1974  }
1975  else if ( nType == StateChangedType::ControlFont )
1976  {
1978  ImplCalcMetrics();
1979  Invalidate();
1980  }
1981  else if ( nType == StateChangedType::ControlForeground )
1982  {
1984  Invalidate();
1985  }
1986  else if ( nType == StateChangedType::ControlBackground )
1987  {
1989  Invalidate();
1990  }
1991  else if( nType == StateChangedType::Enable )
1992  {
1993  Invalidate();
1994  }
1995 
1997 }
1998 
2000 {
2001  Control::DataChanged( rDCEvt );
2002 
2003  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
2005  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2006  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
2007  {
2010  ImplCalcMetrics();
2011  Invalidate();
2012  }
2013 }
2014 
2016 {
2018 
2019  if (maEntryList.HasImages())
2020  nTextStyle |= DrawTextFlags::Left;
2021  else if (mbCenter)
2022  nTextStyle |= DrawTextFlags::Center;
2023  else if (mbRight)
2024  nTextStyle |= DrawTextFlags::Right;
2025  else
2026  nTextStyle |= DrawTextFlags::Left;
2027 
2028  return nTextStyle;
2029 }
2030 
2032  Control( pParent, nWinStyle ),
2033  maLBWindow(VclPtr<ImplListBoxWindow>::Create( this, nWinStyle&(~WB_BORDER) ))
2034 {
2035  // for native widget rendering we must be able to detect this window type
2036  SetType( WindowType::LISTBOXWINDOW );
2037 
2041 
2042  Link<ScrollBar*,void> aLink( LINK( this, ImplListBox, ScrollBarHdl ) );
2043  mpVScrollBar->SetScrollHdl( aLink );
2044  mpHScrollBar->SetScrollHdl( aLink );
2045 
2046  mbVScroll = false;
2047  mbHScroll = false;
2048  mbAutoHScroll = ( nWinStyle & WB_AUTOHSCROLL );
2049  mbEdgeBlending = false;
2050 
2051  maLBWindow->SetScrollHdl( LINK( this, ImplListBox, LBWindowScrolled ) );
2052  maLBWindow->SetMRUChangedHdl( LINK( this, ImplListBox, MRUChanged ) );
2054  maLBWindow->Show();
2055 }
2056 
2058 {
2059  disposeOnce();
2060 }
2061 
2063 {
2068  Control::dispose();
2069 }
2070 
2072 {
2073  maLBWindow->Clear();
2074  if ( GetEntryList().GetMRUCount() )
2075  {
2078  }
2079  mpVScrollBar->SetThumbPos( 0 );
2080  mpHScrollBar->SetThumbPos( 0 );
2082 }
2083 
2084 sal_Int32 ImplListBox::InsertEntry( sal_Int32 nPos, const OUString& rStr )
2085 {
2086  ImplEntryType* pNewEntry = new ImplEntryType( rStr );
2087  sal_Int32 nNewPos = maLBWindow->InsertEntry( nPos, pNewEntry );
2089  return nNewPos;
2090 }
2091 
2092 sal_Int32 ImplListBox::InsertEntry( sal_Int32 nPos, const OUString& rStr, const Image& rImage )
2093 {
2094  ImplEntryType* pNewEntry = new ImplEntryType( rStr, rImage );
2095  sal_Int32 nNewPos = maLBWindow->InsertEntry( nPos, pNewEntry );
2097  return nNewPos;
2098 }
2099 
2100 void ImplListBox::RemoveEntry( sal_Int32 nPos )
2101 {
2102  maLBWindow->RemoveEntry( nPos );
2104 }
2105 
2106 void ImplListBox::SetEntryFlags( sal_Int32 nPos, ListBoxEntryFlags nFlags )
2107 {
2108  maLBWindow->SetEntryFlags( nPos, nFlags );
2109 }
2110 
2111 void ImplListBox::SelectEntry( sal_Int32 nPos, bool bSelect )
2112 {
2113  maLBWindow->SelectEntry( nPos, bSelect );
2114 }
2115 
2117 {
2119 }
2120 
2122 {
2123  if (maLBWindow)
2124  maLBWindow->GrabFocus();
2125  else
2127 }
2128 
2130 {
2131  Control::Resize();
2134 }
2135 
2137 {
2138  CompatStateChanged( StateChangedType::Data );
2139 }
2140 
2142 {
2143  tools::Long nSet = GetTopEntry();
2144  if( nSet > mpVScrollBar->GetRangeMax() )
2145  mpVScrollBar->SetRangeMax( GetEntryList().GetEntryCount() );
2146  mpVScrollBar->SetThumbPos( GetTopEntry() );
2147 
2148  mpHScrollBar->SetThumbPos( GetLeftIndent() );
2149 
2150  maScrollHdl.Call( this );
2151 }
2152 
2153 IMPL_LINK( ImplListBox, ScrollBarHdl, ScrollBar*, pSB, void )
2154 {
2155  sal_uInt16 nPos = static_cast<sal_uInt16>(pSB->GetThumbPos());
2156  if( pSB == mpVScrollBar )
2157  SetTopEntry( nPos );
2158  else if( pSB == mpHScrollBar )
2159  SetLeftIndent( nPos );
2160  if( GetParent() )
2161  GetParent()->Invalidate( InvalidateFlags::Update );
2162 }
2163 
2165 {
2166  bool bArrange = false;
2167 
2168  Size aOutSz = GetOutputSizePixel();
2169  sal_Int32 nEntries = GetEntryList().GetEntryCount();
2170  sal_uInt16 nMaxVisEntries = static_cast<sal_uInt16>(aOutSz.Height() / GetEntryHeightWithMargin());
2171 
2172  // vertical ScrollBar
2173  if( nEntries > nMaxVisEntries )
2174  {
2175  if( !mbVScroll )
2176  bArrange = true;
2177  mbVScroll = true;
2178 
2179  // check of the scrolled-out region
2180  if( GetEntryList().GetSelectedEntryCount() == 1 &&
2183  else
2184  SetTopEntry( GetTopEntry() ); // MaxTop is being checked...
2185  }
2186  else
2187  {
2188  if( mbVScroll )
2189  bArrange = true;
2190  mbVScroll = false;
2191  SetTopEntry( 0 );
2192  }
2193 
2194  // horizontal ScrollBar
2195  if( mbAutoHScroll )
2196  {
2197  tools::Long nWidth = static_cast<sal_uInt16>(aOutSz.Width());
2198  if ( mbVScroll )
2199  nWidth -= mpVScrollBar->GetSizePixel().Width();
2200 
2201  tools::Long nMaxWidth = GetMaxEntryWidth();
2202  if( nWidth < nMaxWidth )
2203  {
2204  if( !mbHScroll )
2205  bArrange = true;
2206  mbHScroll = true;
2207 
2208  if ( !mbVScroll ) // maybe we do need one now
2209  {
2210  nMaxVisEntries = static_cast<sal_uInt16>( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeightWithMargin() );
2211  if( nEntries > nMaxVisEntries )
2212  {
2213  bArrange = true;
2214  mbVScroll = true;
2215 
2216  // check of the scrolled-out region
2217  if( GetEntryList().GetSelectedEntryCount() == 1 &&
2220  else
2221  SetTopEntry( GetTopEntry() ); // MaxTop is being checked...
2222  }
2223  }
2224 
2225  // check of the scrolled-out region
2226  sal_uInt16 nMaxLI = static_cast<sal_uInt16>(nMaxWidth - nWidth);
2227  if ( nMaxLI < GetLeftIndent() )
2228  SetLeftIndent( nMaxLI );
2229  }
2230  else
2231  {
2232  if( mbHScroll )
2233  bArrange = true;
2234  mbHScroll = false;
2235  SetLeftIndent( 0 );
2236  }
2237  }
2238 
2239  if( bArrange )
2241 
2243 }
2244 
2246 {
2247  Size aOutSz = maLBWindow->GetOutputSizePixel();
2248 
2249  if ( mbVScroll )
2250  {
2251  sal_Int32 nEntries = GetEntryList().GetEntryCount();
2252  sal_uInt16 nVisEntries = static_cast<sal_uInt16>(aOutSz.Height() / GetEntryHeightWithMargin());
2253  mpVScrollBar->SetRangeMax( nEntries );
2254  mpVScrollBar->SetVisibleSize( nVisEntries );
2255  mpVScrollBar->SetPageSize( nVisEntries - 1 );
2256  }
2257 
2258  if ( mbHScroll )
2259  {
2261  mpHScrollBar->SetVisibleSize( static_cast<sal_uInt16>(aOutSz.Width()) );
2263  mpHScrollBar->SetPageSize( aOutSz.Width() - HORZ_SCROLL );
2264  }
2265 }
2266 
2268 {
2269  // Here we only position the Controls; if the Scrollbars are to be
2270  // visible is already determined in ImplCheckScrollBars
2271 
2272  Size aOutSz = GetOutputSizePixel();
2274  nSBWidth = CalcZoom( nSBWidth );
2275 
2276  Size aInnerSz( aOutSz );
2277  if ( mbVScroll )
2278  aInnerSz.AdjustWidth( -nSBWidth );
2279  if ( mbHScroll )
2280  aInnerSz.AdjustHeight( -nSBWidth );
2281 
2282  Point aWinPos( 0, 0 );
2283  maLBWindow->SetPosSizePixel( aWinPos, aInnerSz );
2284 
2285  // ScrollBarBox
2286  if( mbVScroll && mbHScroll )
2287  {
2288  Point aBoxPos( aInnerSz.Width(), aInnerSz.Height() );
2289  mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
2290  mpScrollBarBox->Show();
2291  }
2292  else
2293  {
2294  mpScrollBarBox->Hide();
2295  }
2296 
2297  // vertical ScrollBar
2298  if( mbVScroll )
2299  {
2300  // Scrollbar on left or right side?
2301  Point aVPos( aOutSz.Width() - nSBWidth, 0 );
2302  mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, aInnerSz.Height() ) );
2303  mpVScrollBar->Show();
2304  }
2305  else
2306  {
2307  mpVScrollBar->Hide();
2308  // #107254# Don't reset top entry after resize, but check for max top entry
2309  SetTopEntry( GetTopEntry() );
2310  }
2311 
2312  // horizontal ScrollBar
2313  if( mbHScroll )
2314  {
2315  Point aHPos( 0, aOutSz.Height() - nSBWidth );
2316  mpHScrollBar->SetPosSizePixel( aHPos, Size( aInnerSz.Width(), nSBWidth ) );
2317  mpHScrollBar->Show();
2318  }
2319  else
2320  {
2321  mpHScrollBar->Hide();
2322  SetLeftIndent( 0 );
2323  }
2324 }
2325 
2327 {
2328  if ( nType == StateChangedType::InitShow )
2329  {
2331  }
2332  else if ( ( nType == StateChangedType::UpdateMode ) || ( nType == StateChangedType::Data ) )
2333  {
2334  bool bUpdate = IsUpdateMode();
2335  maLBWindow->SetUpdateMode( bUpdate );
2336  if ( bUpdate && IsReallyVisible() )
2338  }
2339  else if( nType == StateChangedType::Enable )
2340  {
2344  maLBWindow->Enable( IsEnabled() );
2345 
2346  Invalidate();
2347  }
2348  else if ( nType == StateChangedType::Zoom )
2349  {
2350  maLBWindow->SetZoom( GetZoom() );
2351  Resize();
2352  }
2353  else if ( nType == StateChangedType::ControlFont )
2354  {
2356  }
2357  else if ( nType == StateChangedType::ControlForeground )
2358  {
2360  }
2361  else if ( nType == StateChangedType::ControlBackground )
2362  {
2364  }
2365  else if( nType == StateChangedType::Mirroring )
2366  {
2371  }
2372 
2373  Control::StateChanged( nType );
2374 }
2375 
2377 {
2378  bool bDone = false;
2379  if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
2380  {
2381  const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2382  if ( rCEvt.GetCommand() == CommandEventId::Wheel )
2383  {
2384  const CommandWheelData* pData = rCEvt.GetWheelData();
2385  if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
2386  {
2387  bDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
2388  }
2389  }
2390  else if (rCEvt.GetCommand() == CommandEventId::Gesture)
2391  {
2393  }
2394  }
2395 
2396  return bDone || Window::EventNotify( rNEvt );
2397 }
2398 
2400 {
2401  return maLBWindow->GetDisplayBackground();
2402 }
2403 
2405 {
2406  bool bDone = false;
2407  if ( rCEvt.GetCommand() == CommandEventId::Wheel )
2408  {
2409  const CommandWheelData* pData = rCEvt.GetWheelData();
2410  if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
2411  {
2412  if (!rControl.HasChildPathFocus())
2413  rControl.GrabFocus();
2414  sal_uInt16 nKey = ( pData->GetDelta() < 0 ) ? KEY_DOWN : KEY_UP;
2415  KeyEvent aKeyEvent( 0, vcl::KeyCode( nKey ) );
2416  bDone = ProcessKeyInput( aKeyEvent );
2417  }
2418  }
2419  return bDone;
2420 }
2421 
2422 void ImplListBox::SetMRUEntries( const OUString& rEntries, sal_Unicode cSep )
2423 {
2424  bool bChanges = GetEntryList().GetMRUCount() != 0;
2425 
2426  // Remove old MRU entries
2427  for ( sal_Int32 n = GetEntryList().GetMRUCount();n; )
2428  maLBWindow->RemoveEntry( --n );
2429 
2430  sal_Int32 nMRUCount = 0;
2431  sal_Int32 nIndex = 0;
2432  do
2433  {
2434  OUString aEntry = rEntries.getToken( 0, cSep, nIndex );
2435  // Accept only existing entries
2436  if ( GetEntryList().FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND )
2437  {
2438  ImplEntryType* pNewEntry = new ImplEntryType( aEntry );
2439  maLBWindow->InsertEntry(nMRUCount++, pNewEntry, false);
2440  bChanges = true;
2441  }
2442  }
2443  while ( nIndex >= 0 );
2444 
2445  if ( bChanges )
2446  {
2447  maLBWindow->GetEntryList().SetMRUCount( nMRUCount );
2448  SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
2450  }
2451 }
2452 
2454 {
2455  OUStringBuffer aEntries;
2456  for ( sal_Int32 n = 0; n < GetEntryList().GetMRUCount(); n++ )
2457  {
2458  aEntries.append(GetEntryList().GetEntryText( n ));
2459  if( n < ( GetEntryList().GetMRUCount() - 1 ) )
2460  aEntries.append(cSep);
2461  }
2462  return aEntries.makeStringAndClear();
2463 }
2464 
2466 {
2467  if(mbEdgeBlending != bNew)
2468  {
2469  mbEdgeBlending = bNew;
2471  }
2472 }
2473 
2474 ImplWin::ImplWin( vcl::Window* pParent, WinBits nWinStyle ) :
2475  Control ( pParent, nWinStyle )
2476 {
2479  SetBackground();
2480  else
2481  SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2482 
2484 
2485  mbEdgeBlending = false;
2487 }
2488 
2490 {
2491  if( IsEnabled() )
2492  {
2493  maMBDownHdl.Call(this);
2494  }
2495 }
2496 
2498 {
2499  mxLayoutData.emplace();
2500  ImplWin* pThis = const_cast<ImplWin*>(this);
2501  pThis->ImplDraw(*pThis->GetOutDev(), true);
2502 }
2503 
2505 {
2506  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
2507  {
2508  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
2509  if( pMouseEvt && (pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow()) )
2510  {
2511  // trigger redraw as mouse over state has changed
2514  {
2516  }
2517  }
2518  }
2519 
2520  return Control::PreNotify(rNEvt);
2521 }
2522 
2523 void ImplWin::ImplDraw(vcl::RenderContext& rRenderContext, bool bLayout)
2524 {
2525  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
2526 
2527  if (!bLayout)
2528  {
2529  bool bNativeOK = false;
2530  bool bHasFocus = HasFocus();
2531  bool bIsEnabled = IsEnabled();
2532 
2536  {
2537  // Repaint the (focused) area similarly to
2538  // ImplSmallBorderWindowView::DrawWindow() in
2539  // vcl/source/window/brdwin.cxx
2540  vcl::Window *pWin = GetParent();
2541 
2542  ImplControlValue aControlValue;
2543  bIsEnabled &= pWin->IsEnabled();
2544  if ( !bIsEnabled )
2545  nState &= ~ControlState::ENABLED;
2546  bHasFocus |= pWin->HasFocus();
2547  if ( bHasFocus )
2548  nState |= ControlState::FOCUSED;
2549 
2550  // The listbox is painted over the entire control including the
2551  // border, but ImplWin does not contain the border => correction
2552  // needed.
2553  sal_Int32 nLeft, nTop, nRight, nBottom;
2554  pWin->GetBorder( nLeft, nTop, nRight, nBottom );
2555  Point aPoint( -nLeft, -nTop );
2556  tools::Rectangle aCtrlRegion( aPoint - GetPosPixel(), pWin->GetSizePixel() );
2557 
2558  bool bMouseOver = false;
2559  vcl::Window *pChild = pWin->GetWindow( GetWindowType::FirstChild );
2560  while( pChild )
2561  {
2562  bMouseOver = pChild->IsMouseOver();
2563  if (bMouseOver)
2564  break;
2565  pChild = pChild->GetWindow( GetWindowType::Next );
2566  }
2567  if( bMouseOver )
2568  nState |= ControlState::ROLLOVER;
2569 
2570  // if parent has no border, then nobody has drawn the background
2571  // since no border window exists. so draw it here.
2572  WinBits nParentStyle = pWin->GetStyle();
2573  if( ! (nParentStyle & WB_BORDER) || (nParentStyle & WB_NOBORDER) )
2574  {
2575  tools::Rectangle aParentRect( Point( 0, 0 ), pWin->GetSizePixel() );
2577  nState, aControlValue, OUString() );
2578  }
2579 
2580  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Listbox, ControlPart::Entire, aCtrlRegion,
2581  nState, aControlValue, OUString());
2582  }
2583 
2584  if (bIsEnabled)
2585  {
2586  if (bHasFocus && !ImplGetSVData()->maNWFData.mbDDListBoxNoTextArea)
2587  {
2588  if ( !ImplGetSVData()->maNWFData.mbNoFocusRects )
2589  {
2590  rRenderContext.SetFillColor( rStyleSettings.GetHighlightColor() );
2591  rRenderContext.SetTextColor( rStyleSettings.GetHighlightTextColor() );
2592  }
2593  else
2594  {
2595  rRenderContext.SetLineColor();
2596  rRenderContext.SetFillColor();
2597  rRenderContext.SetTextColor( rStyleSettings.GetFieldTextColor() );
2598  }
2599  rRenderContext.DrawRect( maFocusRect );
2600  }
2601  else
2602  {
2603  Color aColor;
2604  if (IsControlForeground())
2605  aColor = GetControlForeground();
2606  else if (ImplGetSVData()->maNWFData.mbDDListBoxNoTextArea)
2607  {
2608  if( bNativeOK && (nState & ControlState::ROLLOVER) )
2609  aColor = rStyleSettings.GetButtonRolloverTextColor();
2610  else
2611  aColor = rStyleSettings.GetButtonTextColor();
2612  }
2613  else
2614  {
2615  if( bNativeOK && (nState & ControlState::ROLLOVER) )
2616  aColor = rStyleSettings.GetFieldRolloverTextColor();
2617  else
2618  aColor = rStyleSettings.GetFieldTextColor();
2619  }
2620  rRenderContext.SetTextColor(aColor);
2621  if (!bNativeOK)
2622  rRenderContext.Erase(maFocusRect);
2623  }
2624  }
2625  else // Disabled
2626  {
2627  rRenderContext.SetTextColor(rStyleSettings.GetDisableColor());
2628  if (!bNativeOK)
2629  rRenderContext.Erase(maFocusRect);
2630  }
2631  }
2632 
2633  DrawEntry(rRenderContext, bLayout);
2634 }
2635 
2637 {
2638  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
2639 
2640  ApplyControlFont(rRenderContext, rStyleSettings.GetFieldFont());
2641  ApplyControlForeground(rRenderContext, rStyleSettings.GetFieldTextColor());
2642 
2643  if (IsControlBackground())
2644  rRenderContext.SetBackground(GetControlBackground());
2645  else
2646  rRenderContext.SetBackground(rStyleSettings.GetFieldColor());
2647 }
2648 
2649 void ImplWin::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
2650 {
2651  ImplDraw(rRenderContext);
2652 }
2653 
2654 void ImplWin::DrawEntry(vcl::RenderContext& rRenderContext, bool bLayout)
2655 {
2656  tools::Long nBorder = 1;
2657  Size aOutSz(GetOutputSizePixel());
2658 
2659  bool bImage = !!maImage;
2660  if (bImage && !bLayout)
2661  {
2663  Size aImgSz = maImage.GetSizePixel();
2664  Point aPtImg( nBorder, ( ( aOutSz.Height() - aImgSz.Height() ) / 2 ) );
2665  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2666 
2667  // check for HC mode
2668  Image *pImage = &maImage;
2669 
2670  if ( !IsZoom() )
2671  {
2672  rRenderContext.DrawImage( aPtImg, *pImage, nStyle );
2673  }
2674  else
2675  {
2676  aImgSz.setWidth( CalcZoom( aImgSz.Width() ) );
2677  aImgSz.setHeight( CalcZoom( aImgSz.Height() ) );
2678  rRenderContext.DrawImage( aPtImg, aImgSz, *pImage, nStyle );
2679  }
2680 
2681  const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
2682 
2683  if(nEdgeBlendingPercent)
2684  {
2685  const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
2686  const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
2687  const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
2688  const BitmapEx aBlendFrame(createBlendFrame(aImgSz, nAlpha, rTopLeft, rBottomRight));
2689 
2690  if(!aBlendFrame.IsEmpty())
2691  {
2692  rRenderContext.DrawBitmapEx(aPtImg, aBlendFrame);
2693  }
2694  }
2695  }
2696 
2697  if( !maString.isEmpty() )
2698  {
2700 
2701  if ( bImage && !bLayout )
2702  nTextStyle |= DrawTextFlags::Left;
2703  else if ( GetStyle() & WB_CENTER )
2704  nTextStyle |= DrawTextFlags::Center;
2705  else if ( GetStyle() & WB_RIGHT )
2706  nTextStyle |= DrawTextFlags::Right;
2707  else
2708  nTextStyle |= DrawTextFlags::Left;
2709 
2710  tools::Rectangle aTextRect( Point( nBorder, 0 ), Size( aOutSz.Width()-2*nBorder, aOutSz.Height() ) );
2711 
2712  if ( bImage )
2713  {
2715  }
2716 
2717  std::vector< tools::Rectangle >* pVector = bLayout ? &mxLayoutData->m_aUnicodeBoundRects : nullptr;
2718  OUString* pDisplayText = bLayout ? &mxLayoutData->m_aDisplayText : nullptr;
2719  rRenderContext.DrawText( aTextRect, maString, nTextStyle, pVector, pDisplayText );
2720  }
2721 
2722  if( HasFocus() && !bLayout )
2724 }
2725 
2727 {
2728  Control::Resize();
2730  Invalidate();
2731 }
2732 
2734 {
2736  if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
2739  {
2741  if( ! pWin )
2742  pWin = GetParent();
2743  pWin->Invalidate();
2744  }
2745  else
2746  Invalidate();
2748 }
2749 
2751 {
2752  HideFocus();
2753  if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
2756  {
2758  if( ! pWin )
2759  pWin = GetParent();
2760  pWin->Invalidate();
2761  }
2762  else
2763  Invalidate();
2765 }
2766 
2768 {
2770  {
2771  ImplControlValue aControlValue;
2772 
2773  vcl::Window *pWin = GetParent();
2774  tools::Rectangle aParentRect(Point(0, 0), pWin->GetSizePixel());
2776  ControlState::FOCUSED, aControlValue, OUString());
2777  }
2778  Control::ShowFocus(rRect);
2779 }
2780 
2781 ImplBtn::ImplBtn( vcl::Window* pParent, WinBits nWinStyle ) :
2782  PushButton( pParent, nWinStyle )
2783 {
2784 }
2785 
2787 {
2788  if( IsEnabled() )
2789  maMBDownHdl.Call(this);
2790 }
2791 
2793  FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW ) // no drop shadow for list boxes
2794 {
2795  // for native widget rendering we must be able to detect this window type
2796  SetType( WindowType::LISTBOXWINDOW );
2797 
2798  mpImplLB = nullptr;
2799  mnDDLineCount = 0;
2800  mbAutoWidth = false;
2801 
2803 
2804  vcl::Window * pBorderWindow = ImplGetBorderWindow();
2805  if( pBorderWindow )
2806  {
2807  SetAccessibleRole(accessibility::AccessibleRole::PANEL);
2808  pBorderWindow->SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
2809  }
2810  else
2811  {
2812  SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
2813  }
2814 
2815 }
2816 
2818 {
2819  disposeOnce();
2820 }
2821 
2823 {
2824  mpImplLB.clear();
2826 }
2827 
2828 
2830 {
2831  if( rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS )
2832  {
2833  if( !GetParent()->HasChildPathFocus( true ) )
2834  EndPopupMode();
2835  }
2836 
2837  return FloatingWindow::PreNotify( rNEvt );
2838 }
2839 
2841 {
2842  FloatingWindow::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
2843 
2844  // Fix #60890# ( MBA ): to be able to resize the Listbox even in its open state
2845  // after a call to Resize(), we adjust its position if necessary
2846  if ( IsReallyVisible() && ( nFlags & PosSizeFlags::Height ) )
2847  {
2848  Point aPos = GetParent()->GetPosPixel();
2849  aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
2850 
2851  if ( nFlags & PosSizeFlags::X )
2852  aPos.setX( nX );
2853 
2854  if ( nFlags & PosSizeFlags::Y )
2855  aPos.setY( nY );
2856 
2857  sal_uInt16 nIndex;
2859  }
2860 
2861 // if( !IsReallyVisible() )
2862  {
2863  // The ImplListBox does not get a Resize() as not visible.
2864  // But the windows must get a Resize(), so that the number of
2865  // visible entries is correct for PgUp/PgDown.
2866  // The number also cannot be calculated by List/Combobox, as for
2867  // this the presence of the vertical Scrollbar has to be known.
2869  static_cast<vcl::Window*>(mpImplLB)->Resize();
2870  static_cast<vcl::Window*>(mpImplLB->GetMainWindow())->Resize();
2871  }
2872 }
2873 
2875 {
2878 }
2879 
2881 {
2882  Size aFloatSz( maPrefSz );
2883 
2884  sal_Int32 nLeft, nTop, nRight, nBottom;
2885  GetBorder( nLeft, nTop, nRight, nBottom );
2886 
2887  sal_Int32 nLines = mpImplLB->GetEntryList().GetEntryCount();
2888  if ( mnDDLineCount && ( nLines > mnDDLineCount ) )
2889  nLines = mnDDLineCount;
2890 
2891  Size aSz = mpImplLB->CalcSize( nLines );
2892  tools::Long nMaxHeight = aSz.Height() + nTop + nBottom;
2893 
2894  if ( mnDDLineCount )
2895  aFloatSz.setHeight( nMaxHeight );
2896 
2897  if( mbAutoWidth )
2898  {
2899  // AutoSize first only for width...
2900 
2901  aFloatSz.setWidth( aSz.Width() + nLeft + nRight );
2902  aFloatSz.AdjustWidth(nRight ); // adding some space looks better...
2903 
2904  if ( ( aFloatSz.Height() < nMaxHeight ) || ( mnDDLineCount && ( mnDDLineCount < mpImplLB->GetEntryList().GetEntryCount() ) ) )
2905  {
2906  // then we also need the vertical Scrollbar
2908  aFloatSz.AdjustWidth(nSBWidth );
2909  }
2910 
2911  tools::Long nDesktopWidth = GetDesktopRectPixel().getWidth();
2912  if (aFloatSz.Width() > nDesktopWidth)
2913  // Don't exceed the desktop width.
2914  aFloatSz.setWidth( nDesktopWidth );
2915  }
2916 
2917  if ( aFloatSz.Height() > nMaxHeight )
2918  aFloatSz.setHeight( nMaxHeight );
2919 
2920  // Minimal height, in case height is not set to Float height.
2921  // The parent of FloatWin must be DropDown-Combo/Listbox.
2922  Size aParentSz = GetParent()->GetSizePixel();
2923  if( (!mnDDLineCount || !nLines) && ( aFloatSz.Height() < aParentSz.Height() ) )
2924  aFloatSz.setHeight( aParentSz.Height() );
2925 
2926  // do not get narrower than the parent...
2927  if( aFloatSz.Width() < aParentSz.Width() )
2928  aFloatSz.setWidth( aParentSz.Width() );
2929 
2930  // align height to entries...
2931  tools::Long nInnerHeight = aFloatSz.Height() - nTop - nBottom;
2932  tools::Long nEntryHeight = mpImplLB->GetEntryHeightWithMargin();
2933  if ( nInnerHeight % nEntryHeight )
2934  {
2935  nInnerHeight /= nEntryHeight;
2936  nInnerHeight++;
2937  nInnerHeight *= nEntryHeight;
2938  aFloatSz.setHeight( nInnerHeight + nTop + nBottom );
2939  }
2940 
2941  if (aFloatSz.Width() < aSz.Width())
2942  {
2943  // The max width of list box entries exceeds the window width.
2944  // Account for the scroll bar height.
2946  aFloatSz.AdjustHeight(nSBWidth );
2947  }
2948 
2949  return aFloatSz;
2950 }
2951 
2952 void ImplListBoxFloatingWindow::StartFloat( bool bStartTracking )
2953 {
2954  if( IsInPopupMode() )
2955  return;
2956 
2957  Size aFloatSz = CalcFloatSize();
2958 
2959  SetSizePixel( aFloatSz );
2961 
2962  sal_Int32 nPos = mpImplLB->GetEntryList().GetSelectedEntryPos( 0 );
2964 
2965  Size aSz = GetParent()->GetSizePixel();
2966  Point aPos = GetParent()->GetPosPixel();
2967  aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
2968  // FIXME: this ugly hack is for Mac/Aqua
2969  // should be replaced by a real mechanism to place the float rectangle
2970  if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
2972  {
2973  const sal_Int32 nLeft = 4, nTop = 4, nRight = 4, nBottom = 4;
2974  aPos.AdjustX(nLeft );
2975  aPos.AdjustY(nTop );
2976  aSz.AdjustWidth( -(nLeft + nRight) );
2977  aSz.AdjustHeight( -(nTop + nBottom) );
2978  }
2979  tools::Rectangle aRect( aPos, aSz );
2980 
2981  // check if the control's parent is un-mirrored which is the case for form controls in a mirrored UI
2982  // where the document is unmirrored
2983  // because StartPopupMode() expects a rectangle in mirrored coordinates we have to re-mirror
2984  vcl::Window *pGrandparent = GetParent()->GetParent();
2985  const OutputDevice *pGrandparentOutDev = pGrandparent->GetOutDev();
2986 
2987  if( pGrandparent->GetOutDev()->ImplIsAntiparallel() )
2988  pGrandparentOutDev->ReMirror( aRect );
2989 
2990  // mouse-button right: close the List-Box-Float-win and don't stop the handling fdo#84795
2992 
2993  if( nPos != LISTBOX_ENTRY_NOTFOUND )
2994  mpImplLB->ShowProminentEntry( nPos );
2995 
2996  if( bStartTracking )
2998 
3001 
3003 
3004 }
3005 
3006 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Definition: window.cxx:2791
tools::Rectangle maFocusRect
Definition: listbox.hxx:541
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: window3.cxx:65
void SelectEntry(sal_Int32 nPos, bool bSelect)
Size GetSizePixel() const
Definition: Image.cxx:86
void SetPos(const Point &rPoint)
bool IsControlBackground() const
Definition: window2.cxx:1081
bool GetEdgeBlending() const
Definition: listbox.hxx:493
virtual void EnableRTL(bool bEnable=true) override
Definition: ctrl.cxx:64
virtual void ShowFocus(const tools::Rectangle &rRect) override
bool IsInPopupMode() const
Definition: floatwin.hxx:130
virtual const Wallpaper & GetDisplayBackground() const
Definition: window.cxx:3067
bool mbAutoHScroll
Definition: listbox.hxx:387
WinBits const WB_NOSHADOW
virtual void LoseFocus() override
void SetBackground()
Definition: window3.cxx:100
Link< sal_Int32, void > maFocusHdl
Definition: listbox.hxx:231
bool mbEdgeBlending
Definition: listbox.hxx:545
void SetMRUEntries(const OUString &rEntries, sal_Unicode cSep)
sal_Int32 NaturalSortCompare(const OUString &rA, const OUString &rB)
void StartPopupMode(const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: floatwin.cxx:773
void HideFocus()
Definition: window2.cxx:93
sal_Int32 nIndex
SalLayoutGlyphs maStrGlyphs
Definition: listbox.hxx:53
bool mbTrack
Tracking.
Definition: listbox.hxx:208
virtual void Resize() override
#define HORZ_SCROLL
Definition: listbox.hxx:39
virtual void LoseFocus() override
bool HandleKeyEvent(const KeyEvent &_rKEvt)
WinBits const WB_SYSTEMWINDOW
bool HasEntryImage(sal_Int32 nPos) const
virtual void StateChanged(StateChangedType nType) override
void SetNoSelection()
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
OUString maString
Definition: listbox.hxx:538
void SetSelectionAnchor(sal_Int32 nPos)
Definition: listbox.hxx:151
static OUString filterFormattingChars(const OUString &)
Definition: i18nhelp.cxx:93
virtual void FillLayoutData() const override
void setWidth(tools::Long nWidth)
const ImplEntryList & GetEntryList() const
Definition: listbox.hxx:265
virtual void setPosSizePixel(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags=PosSizeFlags::All) override
sal_Int32 GetSelectedEntryPos(sal_Int32 nIndex) const
void SetUserItemSize(const Size &rSz)
const CommandEvent * GetCommandEvent() const
Definition: event.hxx:332
const Color & GetHighlightTextColor() const
BitmapEx createBlendFrame(const Size &rSize, sal_uInt8 nAlpha, Color aColorTopLeft, Color aColorBottomRight)
Create a blend frame as BitmapEx.
Definition: BitmapEx.cxx:1000
std::unique_ptr< ContentProperties > pData
void SetEntryFlags(sal_Int32 nPos, ListBoxEntryFlags nFlags)
virtual ~ImplListBoxWindow() override
tools::Long getWidth() const
std::optional< vcl::ControlLayoutData > mxLayoutData
Definition: ctrl.hxx:84
A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for refer...
Definition: button.hxx:34
void ScrollHorz(tools::Long nDiff)
Image maImage
Definition: listbox.hxx:54
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
Definition: bitmapex.cxx:33
bool mbVScroll
Definition: listbox.hxx:385
bool Contains(const Point &rPOINT) const
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
SAL_DLLPRIVATE void ImplClearLayoutData() const
Definition: ctrl.cxx:325
tools::Rectangle maFocusRect
Definition: listbox.hxx:179
sal_uIntPtr sal_uLong
long Long
void disposeAndClear()
Definition: vclptr.hxx:200
tools::Long mnHeight
Definition: listbox.hxx:58
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:733
constexpr sal_uInt16 KEY_A
Definition: keycodes.hxx:56
tools::Long mnMaxImgWidth
Maximum width of an image item.
Definition: listbox.hxx:188
bool mbSelectionChanged
Do not call Select() too often ...
Definition: listbox.hxx:213
void ImplResizeControls()
bool mbEdgeBlending
Definition: listbox.hxx:388
virtual void StateChanged(StateChangedType nStateChange) override
Definition: ctrl.cxx:255
ImplSVNWFData maNWFData
Definition: svdata.hxx:402
sal_Int64 n
SAL_DLLPRIVATE vcl::Window * ImplGetBorderWindow() const
Definition: window2.cxx:864
Link< ImplListBoxWindow *, void > maScrollHdl
Definition: listbox.hxx:225
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
void EnableMouseMoveSelect(bool bMouseMoveSelect)
Definition: listbox.hxx:335
sal_Int32 GetTopEntry() const
Definition: listbox.hxx:449
virtual Size GetSizePixel() const
Definition: window.cxx:2402
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1256
WinBits const WB_RIGHT
constexpr tools::Long gnBorder
Definition: imp_listbox.cxx:48
#define IMG_TXT_DISTANCE
Definition: listbox.hxx:40
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:527
sal_Int32 GetEntryPosForPoint(const Point &rPoint) const
sal_Int32 GetLastSelected() const
Definition: listbox.hxx:149
SAL_DLLPRIVATE void CompatStateChanged(StateChangedType nStateChange)
Definition: window.cxx:3891
bool IsShift() const
Definition: event.hxx:158
bool MatchString(const OUString &rStr1, const OUString &rStr2) const
Definition: i18nhelp.cxx:124
void SetMRUCount(sal_Int32 n)
Definition: listbox.hxx:157
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
void SetTextFillColor()
Definition: text.cxx:706
const Color & GetFieldRolloverTextColor() const
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
void SelectEntry(sal_Int32 nPos, bool bSelect)
Definition: imp_listbox.cxx:88
sal_Int32 FindEntry(std::u16string_view rStr, bool bSearchMRUArea=false) const
sal_Int32 GetSelectedEntryCount() const
PosSizeFlags
Definition: window.hxx:125
DataChangedEventType GetType() const
Definition: event.hxx:362
The invalidated area is updated immediately.
tools::Rectangle GetDesktopRectPixel() const
Definition: window.cxx:2796
sal_Int32 mnMRUCount
Definition: listbox.hxx:93
bool mbMouseMoveSelect
Select at MouseMove.
Definition: listbox.hxx:214
WinBits const WB_VSCROLL
sal_Int32 mnTop
output from line on
Definition: listbox.hxx:200
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
sal_uInt16 GetDisplayLineCount() const
const Color & GetControlBackground() const
Definition: window2.cxx:1076
const CommandWheelData * GetWheelData() const
constexpr sal_uInt16 KEY_SPACE
Definition: keycodes.hxx:123
void SetRangeMax(tools::Long nNewRange)
Definition: scrbar.cxx:1332
void SetSeparatorPos(sal_Int32 n)
Removes existing separators, and sets the position of the one and only separator. ...
void SetType(WindowType nType)
Definition: window2.cxx:962
bool mbCenter
center Text output
Definition: listbox.hxx:219
sal_Int32 GetSelectionAnchor() const
Definition: listbox.hxx:152
void PaintImmediately()
Definition: paint.cxx:1292
bool HandleScrollCommand(const CommandEvent &rCmd, ScrollBar *pHScrl, ScrollBar *pVScrl)
Definition: window2.cxx:598
void SetEntryFlags(sal_Int32 nPos, ListBoxEntryFlags nFlags)
virtual void Tracking(const TrackingEvent &rTEvt) override
bool IsRTLEnabled() const
Definition: window3.cxx:127
static Point ImplCalcPos(vcl::Window *pWindow, const tools::Rectangle &rRect, FloatWinPopupFlags nFlags, sal_uInt16 &rArrangeIndex, Point *pLOKTwipsPos=nullptr)
Definition: floatwin.cxx:231
void StartTracking(StartTrackingFlags nFlags=StartTrackingFlags::NONE)
Definition: window2.cxx:244
bool HasChildPathFocus(bool bSystemWindow=false) const
Definition: window.cxx:3004
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
const vcl::Font & GetFieldFont() const
tools::Long GetLeftIndent() const
Definition: listbox.hxx:454
DrawTextFlags
const Color & GetFieldTextColor() const
int mnListBoxEntryMargin
Definition: svdata.hxx:345
void ImplUpdateEntryMetrics(ImplEntryType &rEntry)
constexpr sal_uInt16 KEY_UP
Definition: keycodes.hxx:111
#define LISTBOX_ENTRY_NOTFOUND
Definition: lstbox.hxx:37
const Color & GetHighlightColor() const
VclPtr< ImplListBoxWindow > maLBWindow
Definition: listbox.hxx:380
bool mbReadOnly
ReadOnly.
Definition: listbox.hxx:218
ImplEntryList(vcl::Window *pWindow)
Definition: imp_listbox.cxx:59
The invalidated area is painted with the background color/pattern.
void ImplInitScrollBars()
Link< void *, void > maMBDownHdl
Definition: listbox.hxx:584
sal_Int32 GetTopEntry() const
Definition: listbox.hxx:287
constexpr sal_uInt16 KEY_END
Definition: keycodes.hxx:115
void RemoveEntry(sal_Int32 nPos)
const Fraction & GetZoom() const
Definition: window2.cxx:1204
void * GetEntryData(sal_Int32 nPos) const
StateChangedType
Definition: window.hxx:289
constexpr tools::Long Width() const
tools::Long mnMaxWidth
Maximum width of an entry.
Definition: listbox.hxx:190
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
tools::Long mnTextHeight
text height
Definition: listbox.hxx:202
tools::Long GetMaxEntryWidth() const
Definition: listbox.hxx:472
sal_uInt16 GetEdgeBlending() const
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), tools::Long nLogicWidth=0, const tools::Long *pLogicDXArray=nullptr, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::text::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
Definition: text.cxx:1223
sal_uInt16 GetClicks() const
Definition: event.hxx:126
VclPtr< vcl::Window > mpWindow
For getting the current locale when matching strings.
Definition: listbox.hxx:88
sal_Int64 WinBits
IMPL_LINK_NOARG(ImplListBox, MRUChanged, LinkParamNone *, void)
sal_uInt16 sal_Unicode
bool IsTravelSelect() const
Definition: listbox.hxx:322
std::set< sal_Int32 > maSeparators
Separator positions.
Definition: listbox.hxx:196
virtual bool PreNotify(NotifyEvent &rNEvt) override
void RemoveEntry(sal_Int32 nPos)
void SetBackground()
Definition: background.cxx:27
void SetControlFont()
Definition: window2.cxx:403
tools::Long mnMaxImgTxtWidth
Maximum width of a text item.
Definition: listbox.hxx:186
void Enable(bool bEnable=true, bool bChild=true)
Definition: window.cxx:2433
void SetPageSize(tools::Long nNewSize)
Definition: scrbar.hxx:125
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:665
this flags lets the item be drawn disabled (e.g.
VclPtr< ImplListBox > mpImplLB
Definition: listbox.hxx:500
void SetSymbol(SymbolType eSymbol)
Definition: button.cxx:1561
virtual void StateChanged(StateChangedType nType) override
LB_EVENT_TYPE
Definition: listbox.hxx:42
virtual ~ImplListBoxFloatingWindow() override
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
bool IsControlForeground() const
Definition: window2.cxx:1071
DrawImageFlags
bool IsEnterWindow() const
Definition: event.hxx:138
bool mbHScroll
Definition: listbox.hxx:386
WinBits const WB_HSCROLL
int nCount
void SetMRUChangedHdl(const Link< LinkParamNone *, void > &rLink)
Definition: listbox.hxx:350
void Hide()
Definition: window.hxx:884
AllSettingsFlags GetFlags() const
Definition: event.hxx:363
constexpr sal_uInt16 KEY_PAGEUP
Definition: keycodes.hxx:116
virtual const Wallpaper & GetDisplayBackground() const override
bool mbIsDropdown
Listbox is actually a dropdown (either combobox, or popup window treated as dropdown) ...
Definition: listbox.hxx:223
constexpr tools::Long GetWidth() const
tools::Long mnMaxTxtWidth
Maximum width of a text item.
Definition: listbox.hxx:184
tools::Long getHeightWithMargin() const
virtual void Resize() override
sal_uInt16 GetModifier() const
Definition: keycod.hxx:52
const void * StringEntryIdentifier
Link< LinkParamNone *, void > maListItemSelectHdl
Definition: listbox.hxx:232
bool IsValid() const
ImplWin(vcl::Window *pParent, WinBits nWinStyle)
sal_Int32 mnMaxMRUCount
Definition: listbox.hxx:94
bool mbSimpleMode
SimpleMode for MultiListBox.
Definition: listbox.hxx:210
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:160
void SetThumbPos(tools::Long nThumbPos)
Definition: scrbar.cxx:1361
const Color & GetEdgeBlendingBottomRightColor() const
Image GetEntryImage(sal_Int32 nPos) const
void SetTextFillColor()
Definition: window3.cxx:97
void SetLineSize(tools::Long nNewSize)
Definition: scrbar.hxx:123
ImplListBoxWindow * GetMainWindow()
Definition: listbox.hxx:411
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
sal_Int32 mnTrackingSaveSelection
Selection before Tracking();.
Definition: listbox.hxx:194
void SetEntryFlags(sal_Int32 nPos, ListBoxEntryFlags nFlags)
const Color & GetControlForeground() const
Definition: window2.cxx:1066
this flag disables a selection of an entry completely.
void SetTopEntry(sal_Int32 nTop)
Definition: listbox.hxx:448
constexpr sal_uInt16 KEY_DOWN
Definition: keycodes.hxx:110
void RemoveEntry(sal_Int32 nPos)
void SetScrollHdl(const Link< ImplListBoxWindow *, void > &rLink)
Definition: listbox.hxx:345
Link< void *, void > maMBDownHdl
Definition: listbox.hxx:543
ImplListBoxFloatingWindow(vcl::Window *pParent)
sal_Int32 GetSeparatorPos() const
Gets the position of the separator which was added first.
sal_Int32 GetMRUCount() const
Definition: listbox.hxx:158
bool IsEmpty() const
Definition: BitmapEx.cxx:177
void ShowProminentEntry(sal_Int32 nPos)
Definition: listbox.hxx:450
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
bool ProcessKeyInput(const KeyEvent &rKEvt)
this flag can be used to make an entry multiline capable A normal entry is single line and will there...
void SetLineColor()
Definition: line.cxx:36
sal_Int32 GetScrollBarSize() const
virtual void KeyInput(const KeyEvent &rKEvt) override
void clear()
Definition: vclptr.hxx:190
const Color & GetDisableColor() const
ImplEntryType * GetMutableEntryPtr(sal_Int32 nPos) const
Definition: listbox.hxx:114
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: syswin.cxx:196
std::vector< std::unique_ptr< ImplEntryType > > maEntries
Definition: listbox.hxx:98
virtual bool PreNotify(NotifyEvent &rNEvt)
Definition: event.cxx:52
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
bool IsLeaveWindow() const
Definition: event.hxx:140
int i
virtual void Resize() override
bool IsEntryPosSelected(sal_Int32 nIndex) const
bool IsNativeWidgetEnabled() const
Definition: window.cxx:3703
ImplBtn(vcl::Window *pParent, WinBits nWinStyle)
virtual void Resize() override
constexpr sal_uInt16 KEY_HOME
Definition: keycodes.hxx:114
virtual ~ImplListBox() override
void SetControlBackground()
Definition: window2.cxx:491
virtual bool PreNotify(NotifyEvent &rNEvt) override
WinBits const WB_SIMPLEMODE
IMPL_LINK(ImplListBox, ScrollBarHdl, ScrollBar *, pSB, void)
bool mbMulti
MultiListBox.
Definition: listbox.hxx:209
void SetVisibleSize(tools::Long nNewSize)
Definition: scrbar.cxx:1375
tools::Long mnLeft
output from column on
Definition: listbox.hxx:201
void ImplCheckScrollBars()
Link< ImplListBoxWindow *, void > maDoubleClickHdl
Definition: listbox.hxx:228
void SetSize(const Size &rSize)
void SetControlForeground()
Definition: window2.cxx:451
CommandWheelMode GetMode() const
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1165
SAL_DLLPRIVATE bool ImplIsAntiparallel() const
Definition: outdev.cxx:649
void SetUpdateMode(bool bUpdate)
Definition: window.cxx:2967
sal_Int32 mnSelectionAnchor
Definition: listbox.hxx:90
ImplListBox(vcl::Window *pParent, WinBits nWinStyle)
bool IsUpdateMode() const
Definition: window2.cxx:1167
void SetFillColor()
Definition: fill.cxx:29
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_GRAY
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:168
const AllSettings & GetSettings() const
Definition: window3.cxx:129
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const Color & GetFieldColor() const
tools::Long GetEntryHeightWithMargin() const
CommandEventId GetCommand() const
const Color & GetLineColor() const
Definition: outdev.hxx:506
VclPtr< ScrollBarBox > mpScrollBarBox
Definition: listbox.hxx:383
void SetZoom(const Fraction &rZoom)
Definition: window2.cxx:364
sal_uInt16 GetModifier() const
Size CalcSize(sal_Int32 nMaxLines) const
void SetTextColor(const Color &rColor)
Definition: text.cxx:688
void SetLastSelected(sal_Int32 nPos)
Definition: listbox.hxx:148
constexpr sal_uInt16 KEY_PAGEDOWN
Definition: keycodes.hxx:117
DrawTextFlags ImplGetTextStyle() const
bool IsZoom() const
Definition: window2.cxx:1209
constexpr tools::Long Top() const
void SetEdgeBlending(bool bNew)
Definition: listbox.hxx:365
void ImplDoPaint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
MouseNotifyEvent GetType() const
Definition: event.hxx:308
void SetLeftIndent(tools::Long n)
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: ctrl.cxx:57
WinBits const WB_DROPDOWN
const AllSettings & GetSettings() const
Definition: outdev.hxx:287
vcl::QuickSelectionEngine maQuickSelectionEngine
Definition: listbox.hxx:234
bool GetEdgeBlending() const
Definition: listbox.hxx:571
Point PixelToLogic(const Point &rDevicePt) const
Definition: window3.cxx:161
VclPtr< ScrollBar > mpHScrollBar
Definition: listbox.hxx:381
bool HandleWheelAsCursorTravel(const CommandEvent &rCEvt, Control &rControl)
void ApplyControlForeground(vcl::RenderContext &rRenderContext, const Color &rDefaultColor)
Definition: window2.cxx:483
Link< LinkParamNone *, void > maCancelHdl
Definition: listbox.hxx:227
WinBits const WB_SORT
sal_uInt16 GetModifier() const
Definition: event.hxx:156
bool mbSort
ListBox sorted.
Definition: listbox.hxx:207
virtual void LoseFocus()
Definition: window.cxx:1855
bool GetEdgeBlending() const
Definition: listbox.hxx:364
void DrawEntry(vcl::RenderContext &rRenderContext, sal_Int32 nPos, bool bDrawImage, bool bDrawText)
OUString maStr
Definition: listbox.hxx:52
void GrabFocus()
Definition: window.cxx:2976
Link< UserDrawEvent *, void > maUserDrawHdl
Definition: listbox.hxx:229
virtual void ShowFocus(const tools::Rectangle &rRect)
Definition: window2.cxx:51
bool mbTravelSelect
TravelSelect.
Definition: listbox.hxx:211
vcl::Window * GetParent() const
Definition: window2.cxx:1091
ListBoxEntryFlags mnFlags
Definition: listbox.hxx:57
sal_Int32 FindMatchingEntry(const OUString &rStr, sal_Int32 nStart, bool bLazy) const
void SetLeftIndent(sal_uInt16 n)
Definition: listbox.hxx:455
void ImplPaint(vcl::RenderContext &rRenderContext, sal_Int32 nPos)
bool IsTrackingEnded() const
Definition: event.hxx:261
Link< LinkParamNone *, void > maMRUChangedHdl
Definition: listbox.hxx:230
virtual void MouseMove(const MouseEvent &rMEvt) override
void DrawEntry(vcl::RenderContext &rRenderContext, bool bLayout)
Size CalcSize(sal_Int32 nMaxLines) const
Definition: listbox.hxx:469
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
WinBits const WB_NOBORDER
const Color & GetButtonRolloverTextColor() const
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1262
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
constexpr sal_uInt16 KEY_RIGHT
Definition: keycodes.hxx:113
#define MULTILINE_ENTRY_DRAW_FLAGS
Definition: imp_listbox.cxx:44
bool mbIsSelected
Definition: listbox.hxx:56
sal_Int32 mnCurrentPos
Position (Focus)
Definition: listbox.hxx:193
constexpr tools::Long Bottom() const
bool mbUserDrawEnabled
UserDraw possible.
Definition: listbox.hxx:216
VclPtr< ScrollBar > mpVScrollBar
Definition: listbox.hxx:382
tools::Long const nBorder
bool IsMouseMoveSelect() const
Definition: listbox.hxx:336
virtual void setPosSizePixel(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags=PosSizeFlags::All)
Definition: window.cxx:2666
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1805
const LanguageTag & getLocale()
const vcl::I18nHelper & GetLocaleI18nHelper() const
bool mbUseNativeFocus
Definition: window.h:311
tools::Long mnMaxTxtHeight
Maximum height of a text item.
Definition: listbox.hxx:183
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2424
void * mpUserData
Definition: listbox.hxx:55
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
void Erase()
Definition: wallpaper.cxx:96
bool IsShift() const
Definition: keycod.hxx:54
tools::Long GetAddedHeight(sal_Int32 nEndIndex, sal_Int32 nBeginIndex) const
helper: add up heights up to index nEndIndex.
bool IsUserDrawEnabled() const
Definition: listbox.hxx:328
bool IsMouseOver() const
Definition: mouse.cxx:612
virtual void Resize() override
Definition: ctrl.cxx:73
ImplEntryType * GetEntry(sal_Int32 nPos) const
Definition: listbox.hxx:100
bool ProcessKeyInput(const KeyEvent &rKEvt)
Definition: listbox.hxx:429
virtual void Scroll(tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags=ScrollFlags::NONE)
Definition: window.cxx:2944
const ImplEntryType * GetEntryPtr(sal_Int32 nPos) const
Definition: listbox.hxx:113
Definition: ctrl.hxx:81
bool IsEntrySelectable(sal_Int32 nPos) const
An Entry is selectable if its mnFlags does not have the ListBoxEntryFlags::DisableSelection flag set...
#define LISTBOX_MAX_ENTRIES
Definition: lstbox.hxx:38
ListBoxEntryFlags
Definition: lstbox.hxx:47
bool IsSynthetic() const
Definition: event.hxx:142
virtual void GetFocus()
Definition: window.cxx:1841
const Color & GetButtonTextColor() const
bool mbNoFocusRects
Definition: svdata.hxx:326
sal_Int32 mnItemPos
because of UserDraw I have to know which item I draw
Definition: listbox.hxx:537
#define SAL_WARN_IF(condition, area, stream)
constexpr tools::Long Height() const
WinBits const WB_BORDER
unsigned char sal_uInt8
bool bIsEnabled
const MouseEvent * GetMouseEvent() const
Definition: event.hxx:324
virtual void GetFocus() override
sal_Int32 mnLastSelected
Definition: listbox.hxx:89
tools::Long GetEntryHeightWithMargin() const
Definition: listbox.hxx:471
bool IsVisible() const
Definition: window2.cxx:1096
virtual vcl::StringEntryIdentifier CurrentEntry(OUString &_out_entryText) const override
returns the current entry in the list of searchable strings.
sal_Int32 mnPopupModeStartSaveSelection
Definition: listbox.hxx:503
void SetSeparatorPos(sal_Int32 n)
Removes existing separators, and sets the position of the one and only separator. ...
Definition: listbox.hxx:436
bool SelectEntries(sal_Int32 nSelect, LB_EVENT_TYPE eLET, bool bShift=false, bool bCtrl=false, bool bSelectPosChange=false)
sal_Int32 FindFirstSelectable(sal_Int32 nPos, bool bForward=true) const
sal_uInt16 mnSelectModifier
Modifiers.
Definition: listbox.hxx:204
::OutputDevice const * GetOutDev() const
Definition: window.cxx:568
bool IsLeft() const
Definition: event.hxx:149
tools::Long AdjustWidth(tools::Long n)
void SetScrollHdl(const Link< ScrollBar *, void > &rLink)
Definition: scrbar.hxx:133
Definition: image.hxx:39
bool IsMod1() const
Definition: keycod.hxx:56
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
tools::Long mnMaxImgHeight
Maximum height of an image item.
Definition: listbox.hxx:189
tools::Rectangle GetTextRect(const tools::Rectangle &rRect, const OUString &rStr, DrawTextFlags nStyle=DrawTextFlags::WordBreak, TextRectInfo *pInfo=nullptr, const vcl::ITextLayout *_pTextLayout=nullptr) const
Definition: window3.cxx:201
Reference< XComponentContext > getProcessComponentContext()
tools::Long CalcZoom(tools::Long n) const
Definition: window2.cxx:391
ImplListBoxWindow(vcl::Window *pParent, WinBits nWinStyle)
bool IsGrabFocusAllowed() const
Definition: listbox.hxx:299
const Point & GetPosPixel() const
Definition: event.hxx:123
sal_Int32 mnImages
Definition: listbox.hxx:91
WinBits const WB_AUTOHSCROLL
tools::Long AdjustHeight(tools::Long n)
virtual void GetFocus() override
tools::Long GetEntryHeight(sal_Int32 nPos) const
sal_Int32 InsertEntry(sal_Int32 nPos, ImplEntryType *pNewEntry)
Size GetOutputSizePixel() const
Definition: window3.cxx:89
void setHeight(tools::Long nHeight)
virtual bool EventNotify(NotifyEvent &rNEvt) override
Event to pass information for UserDraw() handling eg. in comboboxes.
Definition: event.hxx:221
tools::Long GetDelta() const
WinBits const WB_CENTER
sal_Int32 InsertEntry(sal_Int32 nPos, const OUString &rStr)
bool isSeparator(const sal_Int32 &n) const
Checks if the given number n is an element of the separator positions set.
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
Definition: window3.cxx:66
ScXMLEditAttributeMap::Entry const aEntries[]
bool IsEnabled() const
Definition: window2.cxx:1116
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
#define SAL_WARN(area, stream)
Image maImage
Definition: listbox.hxx:539
OUString GetSelectedEntry(sal_Int32 nIndex) const
void SetTopEntry(sal_Int32 nTop)
bool IsTrackingCanceled() const
Definition: event.hxx:263
OUString GetMRUEntries(sal_Unicode cSep) const
WinBits GetStyle() const
Definition: window2.cxx:947
void SelectEntry(sal_Int32 nPos, bool bSelect)
Link< sal_Int32, void > maSelectionChangedHdl
Definition: listbox.hxx:96
sal_Int32 mnUserDrawEntry
Definition: listbox.hxx:198
virtual void FillLayoutData() const override
bool IsReadOnly() const
Definition: listbox.hxx:360
void ApplyControlFont(vcl::RenderContext &rRenderContext, const vcl::Font &rDefaultFont)
Definition: window2.cxx:443
OUString GetEntryText(sal_Int32 nPos) const
constexpr sal_uInt16 KEY_LEFT
Definition: keycodes.hxx:112
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2803
void StartFloat(bool bStartTracking)
sal_Int32 GetLastVisibleEntry() const
void SetEntryData(sal_Int32 nPos, void *pNewData)
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
Definition: window3.cxx:74
void ImplInitDropDownButton(PushButton *pButton)
Definition: imp_listbox.cxx:50
sal_Int32 compare(const OUString &rLHS, const OUString &rRHS) const
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
void SetAccessibleRole(sal_uInt16 nRole)
bool HasImages() const
Definition: listbox.hxx:129
bool mbInUserDraw
In UserDraw.
Definition: listbox.hxx:217
const MouseEvent & GetMouseEvent() const
Definition: event.hxx:257
bool IsReallyVisible() const
Definition: window2.cxx:1101
vcl::Font GetControlFont() const
Definition: window2.cxx:432
bool mbGrabFocus
Grab focus at MBDown.
Definition: listbox.hxx:215
virtual vcl::StringEntryIdentifier NextEntry(vcl::StringEntryIdentifier _currentEntry, OUString &_out_entryText) const override
returns the next entry in the list.
SalLayoutGlyphs * GetTextGlyphs(const OutputDevice *pOutputDevice)
Computes maStr's text layout (glyphs), cached in maStrGlyphs.
const Wallpaper & GetBackground() const
Definition: window3.cxx:63
bool HasFocus() const
Definition: window.cxx:2981
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: floatwin.cxx:204
const Color & GetEdgeBlendingTopLeftColor() const
void SetEdgeBlending(bool bNew)
WinBits const WB_WORDBREAK
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
bool SupportsDoubleBuffering() const
Can the widget derived from this Window do the double-buffering via RenderContext properly...
Definition: window.cxx:3853
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
Definition: text.cxx:774
tools::Long mnMaxHeight
Maximum height of an entry.
Definition: listbox.hxx:191
void ShowProminentEntry(sal_Int32 nEntryPos)
ShowProminentEntry will set the entry corresponding to nEntryPos either at top or in the middle depen...
void EndPopupMode(FloatWinPopupEndFlags nFlags=FloatWinPopupEndFlags::NONE)
Definition: floatwin.cxx:946
sal_Int32 InsertEntry(sal_Int32 nPos, ImplEntryType *pNewEntry, bool bSort)
sal_Int32 nState
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1251
aStr
virtual void Resize() override
Definition: syswin.cxx:999
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
virtual void GetFocus() override
bool mbCallSelectionChangedHdl
Definition: listbox.hxx:97
sal_Int32 GetEntryCount() const
Definition: listbox.hxx:128
bool IsMod3() const
Definition: keycod.hxx:60
sal_uInt16 nPos
tools::Rectangle GetBoundingRectangle(sal_Int32 nItem) const
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
virtual void DataChanged(const DataChangedEvent &rDCEvt)
Definition: event.cxx:36
Link< LinkParamNone *, void > maSelectHdl
Definition: listbox.hxx:226
bool IsMod1() const
Definition: event.hxx:160
void ImplDraw(vcl::RenderContext &rRenderContext, bool bLayout=false)
constexpr tools::Long GetHeight() const
WinBits const WB_DRAG
bool IsMod2() const
Definition: keycod.hxx:58
bool mbTrackingSelect
Selected at a MouseMove.
Definition: listbox.hxx:212
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2187
ImplEntryList maEntryList
EntryList.
Definition: listbox.hxx:178
const ImplEntryList & GetEntryList() const
Definition: listbox.hxx:410
bool mbRight
right align Text output
Definition: listbox.hxx:220
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo