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