LibreOffice Module vcl (master)  1
combobox.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 <vcl/combobox.hxx>
21 
22 #include <set>
23 
24 #include <comphelper/string.hxx>
25 #include <vcl/lstbox.hxx>
26 #include <vcl/commandevent.hxx>
27 #include <vcl/event.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/uitest/uiobject.hxx>
30 #include <sal/log.hxx>
31 
32 #include <listbox.hxx>
33 #include <controldata.hxx>
34 #include <comphelper/lok.hxx>
35 
37 {
40 
43 };
44 
46 {
52  sal_uInt16 m_nDDHeight;
54  bool m_isDDAutoSize : 1;
56  bool m_isMatchCase : 1;
57  sal_Int32 m_nMaxWidthChars;
58  sal_Int32 m_nWidthInChars;
61 
62  explicit Impl(ComboBox & rThis)
63  : m_rThis(rThis)
64  , m_nDDHeight(0)
65  , m_cMultiSep(0)
66  , m_isDDAutoSize(false)
67  , m_isSyntheticModify(false)
68  , m_isMatchCase(false)
69  , m_nMaxWidthChars(0)
70  , m_nWidthInChars(-1)
71  {
72  }
73 
74  void ImplInitComboBoxData();
77  const Size &rOutSize, const Size &rBorderOutSize) const;
78 
79  DECL_DLLPRIVATE_LINK( ImplSelectHdl, LinkParamNone*, void );
80  DECL_DLLPRIVATE_LINK( ImplCancelHdl, LinkParamNone*, void );
81  DECL_DLLPRIVATE_LINK( ImplDoubleClickHdl, ImplListBoxWindow*, void );
82  DECL_DLLPRIVATE_LINK( ImplClickBtnHdl, void*, void );
83  DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl, FloatingWindow*, void );
84  DECL_DLLPRIVATE_LINK( ImplSelectionChangedHdl, sal_Int32, void );
85  DECL_DLLPRIVATE_LINK( ImplUserDrawHdl, UserDrawEvent*, void );
86  DECL_DLLPRIVATE_LINK( ImplAutocompleteHdl, Edit&, void );
87  DECL_DLLPRIVATE_LINK( ImplListItemSelectHdl , LinkParamNone*, void );
88 };
89 
90 
91 static void lcl_GetSelectedEntries( ::std::set< sal_Int32 >& rSelectedPos, const OUString& rText, sal_Unicode cTokenSep, const ImplEntryList* pEntryList )
92 {
93  if (rText.isEmpty())
94  return;
95 
96  sal_Int32 nIdx{0};
97  do {
98  const sal_Int32 nPos = pEntryList->FindEntry(comphelper::string::strip(rText.getToken(0, cTokenSep, nIdx), ' '));
99  if ( nPos != LISTBOX_ENTRY_NOTFOUND )
100  rSelectedPos.insert( nPos );
101  } while (nIdx>=0);
102 }
103 
104 ComboBox::ComboBox(vcl::Window *const pParent, WinBits const nStyle)
105  : Edit( WindowType::COMBOBOX )
106  , m_pImpl(new Impl(*this))
107 {
108  m_pImpl->ImplInitComboBoxData();
109  ImplInit( pParent, nStyle );
110  SetWidthInChars(-1);
111 }
112 
114 {
115  disposeOnce();
116 }
117 
119 {
120  m_pImpl->m_pSubEdit.disposeAndClear();
121 
122  VclPtr< ImplListBox > pImplLB = m_pImpl->m_pImplLB;
123  m_pImpl->m_pImplLB.clear();
124  pImplLB.disposeAndClear();
125 
126  m_pImpl->m_pFloatWin.disposeAndClear();
127  m_pImpl->m_pBtn.disposeAndClear();
128  Edit::dispose();
129 }
130 
132 {
134  m_pBtn = nullptr;
135  m_pImplLB = nullptr;
136  m_pFloatWin = nullptr;
137 
138  m_nDDHeight = 0;
139  m_isDDAutoSize = true;
140  m_isSyntheticModify = false;
141  m_isMatchCase = false;
142  m_cMultiSep = ';';
143  m_nMaxWidthChars = -1;
144  m_nWidthInChars = -1;
145 }
146 
148 {
149  sal_Int32 nLeft, nTop, nRight, nBottom;
150  GetBorder( nLeft, nTop, nRight, nBottom );
151  m_pImpl->m_nDDHeight = static_cast<sal_uInt16>(m_pImpl->m_pSubEdit->GetTextHeight() + nTop + nBottom + 4);
152  if ( !IsDropDownBox() )
153  m_pImpl->m_nDDHeight += 4;
154 
155  tools::Rectangle aCtrlRegion( Point( 0, 0 ), Size( 10, 10 ) );
156  tools::Rectangle aBoundRegion, aContentRegion;
157  ImplControlValue aControlValue;
160  aCtrlRegion,
162  aControlValue,
163  aBoundRegion, aContentRegion ) )
164  {
165  const long nNCHeight = aBoundRegion.GetHeight();
166  if (m_pImpl->m_nDDHeight < nNCHeight)
167  m_pImpl->m_nDDHeight = sal::static_int_cast<sal_uInt16>(nNCHeight);
168  }
169 }
170 
171 void ComboBox::ImplInit( vcl::Window* pParent, WinBits nStyle )
172 {
173  bool bNoBorder = ( nStyle & WB_NOBORDER ) != 0;
174  if ( !(nStyle & WB_DROPDOWN) )
175  {
176  nStyle &= ~WB_BORDER;
177  nStyle |= WB_NOBORDER;
178  }
179  else
180  {
181  if ( !bNoBorder )
182  nStyle |= WB_BORDER;
183  }
184 
185  Edit::ImplInit( pParent, nStyle );
186  SetBackground();
187 
188  // DropDown ?
189  WinBits nEditStyle = nStyle & ( WB_LEFT | WB_RIGHT | WB_CENTER );
190  WinBits nListStyle = nStyle;
191  if( nStyle & WB_DROPDOWN )
192  {
193  m_pImpl->m_pFloatWin = VclPtr<ImplListBoxFloatingWindow>::Create( this );
195  m_pImpl->m_pFloatWin->RequestDoubleBuffering(true);
196  m_pImpl->m_pFloatWin->SetAutoWidth( true );
197  m_pImpl->m_pFloatWin->SetPopupModeEndHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplPopupModeEndHdl) );
198 
200  ImplInitDropDownButton( m_pImpl->m_pBtn );
201  m_pImpl->m_pBtn->SetMBDownHdl( LINK( m_pImpl.get(), ComboBox::Impl, ImplClickBtnHdl ) );
202  m_pImpl->m_pBtn->Show();
203 
204  nEditStyle |= WB_NOBORDER;
205  nListStyle &= ~WB_BORDER;
206  nListStyle |= WB_NOBORDER;
207  }
208  else
209  {
210  if ( !bNoBorder )
211  {
212  nEditStyle |= WB_BORDER;
213  nListStyle &= ~WB_NOBORDER;
214  nListStyle |= WB_BORDER;
215  }
216  }
217 
218  m_pImpl->m_pSubEdit.set( VclPtr<Edit>::Create( this, nEditStyle ) );
219  m_pImpl->m_pSubEdit->EnableRTL( false );
220  SetSubEdit( m_pImpl->m_pSubEdit );
221  m_pImpl->m_pSubEdit->SetPosPixel( Point() );
222  EnableAutocomplete( true );
223  m_pImpl->m_pSubEdit->Show();
224 
225  vcl::Window* pLBParent = this;
226  if (m_pImpl->m_pFloatWin)
227  pLBParent = m_pImpl->m_pFloatWin;
228  m_pImpl->m_pImplLB = VclPtr<ImplListBox>::Create( pLBParent, nListStyle|WB_SIMPLEMODE|WB_AUTOHSCROLL );
229  m_pImpl->m_pImplLB->SetPosPixel( Point() );
230  m_pImpl->m_pImplLB->SetSelectHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplSelectHdl) );
231  m_pImpl->m_pImplLB->SetCancelHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplCancelHdl) );
232  m_pImpl->m_pImplLB->SetDoubleClickHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplDoubleClickHdl) );
233  m_pImpl->m_pImplLB->SetUserDrawHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplUserDrawHdl) );
234  m_pImpl->m_pImplLB->SetSelectionChangedHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplSelectionChangedHdl) );
235  m_pImpl->m_pImplLB->SetListItemSelectHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplListItemSelectHdl) );
236  m_pImpl->m_pImplLB->Show();
237 
238  if (m_pImpl->m_pFloatWin)
239  m_pImpl->m_pFloatWin->SetImplListBox( m_pImpl->m_pImplLB );
240  else
241  m_pImpl->m_pImplLB->GetMainWindow()->AllowGrabFocus( true );
242 
244 
245  SetCompoundControl( true );
246 }
247 
249 {
250  if ( !(nStyle & WB_NOTABSTOP) )
251  nStyle |= WB_TABSTOP;
252  if ( !(nStyle & WB_NOGROUP) )
253  nStyle |= WB_GROUP;
254  return nStyle;
255 }
256 
257 void ComboBox::EnableAutocomplete( bool bEnable, bool bMatchCase )
258 {
259  m_pImpl->m_isMatchCase = bMatchCase;
260 
261  if ( bEnable )
262  m_pImpl->m_pSubEdit->SetAutocompleteHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplAutocompleteHdl) );
263  else
264  m_pImpl->m_pSubEdit->SetAutocompleteHdl( Link<Edit&,void>() );
265 }
266 
268 {
269  return m_pImpl->m_pSubEdit->GetAutocompleteHdl().IsSet();
270 }
271 
272 IMPL_LINK_NOARG(ComboBox::Impl, ImplClickBtnHdl, void*, void)
273 {
274  m_rThis.CallEventListeners( VclEventId::DropdownPreOpen );
275  m_pSubEdit->GrabFocus();
276  if (!m_pImplLB->GetEntryList()->GetMRUCount())
277  ImplUpdateFloatSelection();
278  else
279  m_pImplLB->SelectEntry( 0 , true );
280  m_pBtn->SetPressed( true );
281  m_rThis.SetSelection( Selection( 0, SELECTION_MAX ) );
282  m_pFloatWin->StartFloat( true );
283  m_rThis.CallEventListeners( VclEventId::DropdownOpen );
284 
285  m_rThis.ImplClearLayoutData();
286  if (m_pImplLB)
287  m_pImplLB->GetMainWindow()->ImplClearLayoutData();
288 }
289 
290 IMPL_LINK_NOARG(ComboBox::Impl, ImplPopupModeEndHdl, FloatingWindow*, void)
291 {
292  if (m_pFloatWin->IsPopupModeCanceled())
293  {
294  if (!m_pImplLB->GetEntryList()->IsEntryPosSelected(
295  m_pFloatWin->GetPopupModeStartSaveSelection()))
296  {
297  m_pImplLB->SelectEntry(m_pFloatWin->GetPopupModeStartSaveSelection(), true);
298  bool bTravelSelect = m_pImplLB->IsTravelSelect();
299  m_pImplLB->SetTravelSelect( true );
300  m_rThis.Select();
301  m_pImplLB->SetTravelSelect( bTravelSelect );
302  }
303  }
304 
305  m_rThis.ImplClearLayoutData();
306  if (m_pImplLB)
307  m_pImplLB->GetMainWindow()->ImplClearLayoutData();
308 
309  m_pBtn->SetPressed( false );
310  m_rThis.CallEventListeners( VclEventId::DropdownClose );
311 }
312 
313 IMPL_LINK(ComboBox::Impl, ImplAutocompleteHdl, Edit&, rEdit, void)
314 {
315  Selection aSel = rEdit.GetSelection();
316 
317  {
318  OUString aFullText = rEdit.GetText();
319  OUString aStartText = aFullText.copy( 0, static_cast<sal_Int32>(aSel.Max()) );
320  sal_Int32 nStart = m_pImplLB->GetCurrentPos();
321 
322  if ( nStart == LISTBOX_ENTRY_NOTFOUND )
323  nStart = 0;
324 
325  sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND;
326  if (!m_isMatchCase)
327  {
328  // Try match case insensitive from current position
329  nPos = m_pImplLB->GetEntryList()->FindMatchingEntry(aStartText, nStart, true);
330  if ( nPos == LISTBOX_ENTRY_NOTFOUND )
331  // Try match case insensitive, but from start
332  nPos = m_pImplLB->GetEntryList()->FindMatchingEntry(aStartText, 0, true);
333  }
334 
335  if ( nPos == LISTBOX_ENTRY_NOTFOUND )
336  // Try match full from current position
337  nPos = m_pImplLB->GetEntryList()->FindMatchingEntry(aStartText, nStart, false);
338  if ( nPos == LISTBOX_ENTRY_NOTFOUND )
339  // Match full, but from start
340  nPos = m_pImplLB->GetEntryList()->FindMatchingEntry(aStartText, 0, false);
341 
342  if ( nPos != LISTBOX_ENTRY_NOTFOUND )
343  {
344  OUString aText = m_pImplLB->GetEntryList()->GetEntryText( nPos );
345  Selection aSelection( aText.getLength(), aStartText.getLength() );
346  rEdit.SetText( aText, aSelection );
347  }
348  }
349 }
350 
352 {
353  bool bPopup = m_rThis.IsInDropDown();
354  bool bCallSelect = false;
355  if (m_pImplLB->IsSelectionChanged() || bPopup)
356  {
357  OUString aText;
358  if (m_rThis.IsMultiSelectionEnabled())
359  {
360  aText = m_pSubEdit->GetText();
361 
362  // remove all entries to which there is an entry, but which is not selected
363  sal_Int32 nIndex = 0;
364  while ( nIndex >= 0 )
365  {
366  sal_Int32 nPrevIndex = nIndex;
367  OUString aToken = aText.getToken( 0, m_cMultiSep, nIndex );
368  sal_Int32 nTokenLen = aToken.getLength();
369  aToken = comphelper::string::strip(aToken, ' ');
370  sal_Int32 nP = m_pImplLB->GetEntryList()->FindEntry( aToken );
371  if ((nP != LISTBOX_ENTRY_NOTFOUND) && (!m_pImplLB->GetEntryList()->IsEntryPosSelected(nP)))
372  {
373  aText = aText.replaceAt( nPrevIndex, nTokenLen, "" );
374  nIndex = nIndex - nTokenLen;
375  sal_Int32 nSepCount=0;
376  if ((nPrevIndex+nSepCount < aText.getLength()) && (aText[nPrevIndex+nSepCount] == m_cMultiSep))
377  {
378  nIndex--;
379  ++nSepCount;
380  }
381  aText = aText.replaceAt( nPrevIndex, nSepCount, "" );
382  }
383  aText = comphelper::string::strip(aText, ' ');
384  }
385 
386  // attach missing entries
387  ::std::set< sal_Int32 > aSelInText;
388  lcl_GetSelectedEntries( aSelInText, aText, m_cMultiSep, m_pImplLB->GetEntryList() );
389  sal_Int32 nSelectedEntries = m_pImplLB->GetEntryList()->GetSelectedEntryCount();
390  for ( sal_Int32 n = 0; n < nSelectedEntries; n++ )
391  {
392  sal_Int32 nP = m_pImplLB->GetEntryList()->GetSelectedEntryPos( n );
393  if ( !aSelInText.count( nP ) )
394  {
395  if (!aText.isEmpty() && (aText[aText.getLength()-1] != m_cMultiSep))
396  aText += OUStringChar(m_cMultiSep);
397  if ( !aText.isEmpty() )
398  aText += " "; // slightly loosen
399  aText += m_pImplLB->GetEntryList()->GetEntryText( nP ) +
400  OUStringChar(m_cMultiSep);
401  }
402  }
403  aText = comphelper::string::stripEnd( aText, m_cMultiSep );
404  }
405  else
406  {
407  aText = m_pImplLB->GetEntryList()->GetSelectedEntry( 0 );
408  }
409 
410  m_pSubEdit->SetText( aText );
411 
412  Selection aNewSelection( 0, aText.getLength() );
413  if (m_rThis.IsMultiSelectionEnabled())
414  aNewSelection.Min() = aText.getLength();
415  m_pSubEdit->SetSelection( aNewSelection );
416 
417  bCallSelect = true;
418  }
419 
420  // #84652# Call GrabFocus and EndPopupMode before calling Select/Modify, but after changing the text
421 
422  if (bPopup && !m_pImplLB->IsTravelSelect() &&
423  (!m_rThis.IsMultiSelectionEnabled() || !m_pImplLB->GetSelectModifier()))
424  {
425  m_pFloatWin->EndPopupMode();
426  m_rThis.GrabFocus();
427  }
428 
429  if ( bCallSelect )
430  {
431  m_pSubEdit->SetModifyFlag();
432  m_isSyntheticModify = true;
433  m_rThis.Modify();
434  m_isSyntheticModify = false;
435  m_rThis.Select();
436  }
437 }
438 
439 IMPL_LINK_NOARG( ComboBox::Impl, ImplListItemSelectHdl, LinkParamNone*, void )
440 {
441  m_rThis.CallEventListeners( VclEventId::DropdownSelect );
442 }
443 
445 {
446  if (m_rThis.IsInDropDown())
447  m_pFloatWin->EndPopupMode();
448 }
449 
450 IMPL_LINK( ComboBox::Impl, ImplSelectionChangedHdl, sal_Int32, nChanged, void )
451 {
452  if (!m_pImplLB->IsTrackingSelect())
453  {
454  if (!m_pSubEdit->IsReadOnly() && m_pImplLB->GetEntryList()->IsEntryPosSelected(nChanged))
455  m_pSubEdit->SetText(m_pImplLB->GetEntryList()->GetEntryText(nChanged));
456  }
457 }
458 
460 {
461  m_rThis.DoubleClick();
462 }
463 
465 {
466  if( IsDropDownBox() )
467  {
468  if (m_pImpl->m_pFloatWin->IsInPopupMode())
469  m_pImpl->m_pFloatWin->EndPopupMode();
470  else
471  {
472  m_pImpl->m_pSubEdit->GrabFocus();
473  if (!m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount())
474  m_pImpl->ImplUpdateFloatSelection();
475  else
476  m_pImpl->m_pImplLB->SelectEntry( 0 , true );
478  m_pImpl->m_pBtn->SetPressed( true );
480  m_pImpl->m_pFloatWin->StartFloat( true );
482  }
483  }
484 }
485 
487 {
488  ImplCallEventListenersAndHandler( VclEventId::ComboboxSelect, [this] () { m_pImpl->m_SelectHdl.Call(*this); } );
489 }
490 
492 {
493  ImplCallEventListenersAndHandler( VclEventId::ComboboxDoubleClick, [this] () { m_pImpl->m_DoubleClickHdl.Call(*this); } );
494 }
495 
496 bool ComboBox::IsAutoSizeEnabled() const { return m_pImpl->m_isDDAutoSize; }
497 
498 void ComboBox::EnableAutoSize( bool bAuto )
499 {
500  m_pImpl->m_isDDAutoSize = bAuto;
501  if (m_pImpl->m_pFloatWin)
502  {
503  if (bAuto && !m_pImpl->m_pFloatWin->GetDropDownLineCount())
504  {
505  // Adapt to GetListBoxMaximumLineCount here; was on fixed number of five before
507  }
508  else if ( !bAuto )
509  {
510  m_pImpl->m_pFloatWin->SetDropDownLineCount( 0 );
511  }
512  }
513 }
515 {
516  m_pImpl->m_pSubEdit->SetSelectAllSingleClick(true);
517 }
518 
519 void ComboBox::SetDropDownLineCount( sal_uInt16 nLines )
520 {
521  if (m_pImpl->m_pFloatWin)
522  m_pImpl->m_pFloatWin->SetDropDownLineCount( nLines );
523 }
524 
526 {
527  // Adapt to maximum allowed number.
528  // Limit for LOK as we can't render outside of the dialog canvas.
531  else
532  SetDropDownLineCount(GetSettings().GetStyleSettings().GetListBoxMaximumLineCount());
533 }
534 
536 {
537  sal_uInt16 nLines = 0;
538  if (m_pImpl->m_pFloatWin)
539  nLines = m_pImpl->m_pFloatWin->GetDropDownLineCount();
540  return nLines;
541 }
542 
543 void ComboBox::setPosSizePixel( long nX, long nY, long nWidth, long nHeight,
544  PosSizeFlags nFlags )
545 {
546  if( IsDropDownBox() && ( nFlags & PosSizeFlags::Size ) )
547  {
548  Size aPrefSz = m_pImpl->m_pFloatWin->GetPrefSize();
549  if ((nFlags & PosSizeFlags::Height) && (nHeight >= 2*m_pImpl->m_nDDHeight))
550  aPrefSz.setHeight( nHeight-m_pImpl->m_nDDHeight );
551  if ( nFlags & PosSizeFlags::Width )
552  aPrefSz.setWidth( nWidth );
553  m_pImpl->m_pFloatWin->SetPrefSize( aPrefSz );
554 
555  if (IsAutoSizeEnabled())
556  nHeight = m_pImpl->m_nDDHeight;
557  }
558 
559  Edit::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
560 }
561 
563 {
564  Control::Resize();
565 
566  if (m_pImpl->m_pSubEdit)
567  {
568  Size aOutSz = GetOutputSizePixel();
569  if( IsDropDownBox() )
570  {
571  ComboBoxBounds aBounds(m_pImpl->calcComboBoxDropDownComponentBounds(aOutSz,
573  m_pImpl->m_pSubEdit->SetPosSizePixel(aBounds.aSubEditPos, aBounds.aSubEditSize);
574  m_pImpl->m_pBtn->SetPosSizePixel(aBounds.aButtonPos, aBounds.aButtonSize);
575  }
576  else
577  {
578  m_pImpl->m_pSubEdit->SetSizePixel(Size(aOutSz.Width(), m_pImpl->m_nDDHeight));
579  m_pImpl->m_pImplLB->setPosSizePixel(0, m_pImpl->m_nDDHeight,
580  aOutSz.Width(), aOutSz.Height() - m_pImpl->m_nDDHeight);
581  if ( !GetText().isEmpty() )
582  m_pImpl->ImplUpdateFloatSelection();
583  }
584  }
585 
586  // adjust the size of the FloatingWindow even when invisible
587  // as KEY_PGUP/DOWN is being processed...
588  if (m_pImpl->m_pFloatWin)
589  m_pImpl->m_pFloatWin->SetSizePixel(m_pImpl->m_pFloatWin->CalcFloatSize());
590 }
591 
592 bool ComboBox::IsDropDownBox() const { return m_pImpl->m_pFloatWin != nullptr; }
593 
595 {
596  mpControlData->mpLayoutData.reset( new vcl::ControlLayoutData );
597  AppendLayoutData( *m_pImpl->m_pSubEdit );
598  m_pImpl->m_pSubEdit->SetLayoutDataParent( this );
599  ImplListBoxWindow* rMainWindow = m_pImpl->m_pImplLB->GetMainWindow();
600  if (m_pImpl->m_pFloatWin)
601  {
602  // dropdown mode
603  if (m_pImpl->m_pFloatWin->IsReallyVisible())
604  {
605  AppendLayoutData( *rMainWindow );
606  rMainWindow->SetLayoutDataParent( this );
607  }
608  }
609  else
610  {
611  AppendLayoutData( *rMainWindow );
612  rMainWindow->SetLayoutDataParent( this );
613  }
614 }
615 
617 {
618  Edit::StateChanged( nType );
619 
620  if ( nType == StateChangedType::ReadOnly )
621  {
622  m_pImpl->m_pImplLB->SetReadOnly( IsReadOnly() );
623  if (m_pImpl->m_pBtn)
624  m_pImpl->m_pBtn->Enable( IsEnabled() && !IsReadOnly() );
625  }
626  else if ( nType == StateChangedType::Enable )
627  {
628  m_pImpl->m_pSubEdit->Enable( IsEnabled() );
629  m_pImpl->m_pImplLB->Enable( IsEnabled() && !IsReadOnly() );
630  if (m_pImpl->m_pBtn)
631  m_pImpl->m_pBtn->Enable( IsEnabled() && !IsReadOnly() );
632  Invalidate();
633  }
634  else if( nType == StateChangedType::UpdateMode )
635  {
636  m_pImpl->m_pImplLB->SetUpdateMode( IsUpdateMode() );
637  }
638  else if ( nType == StateChangedType::Zoom )
639  {
640  m_pImpl->m_pImplLB->SetZoom( GetZoom() );
641  m_pImpl->m_pSubEdit->SetZoom( GetZoom() );
643  Resize();
644  }
645  else if ( nType == StateChangedType::ControlFont )
646  {
647  m_pImpl->m_pImplLB->SetControlFont( GetControlFont() );
648  m_pImpl->m_pSubEdit->SetControlFont( GetControlFont() );
650  Resize();
651  }
652  else if ( nType == StateChangedType::ControlForeground )
653  {
654  m_pImpl->m_pImplLB->SetControlForeground( GetControlForeground() );
655  m_pImpl->m_pSubEdit->SetControlForeground( GetControlForeground() );
656  }
657  else if ( nType == StateChangedType::ControlBackground )
658  {
659  m_pImpl->m_pImplLB->SetControlBackground( GetControlBackground() );
660  m_pImpl->m_pSubEdit->SetControlBackground( GetControlBackground() );
661  }
662  else if ( nType == StateChangedType::Style )
663  {
665  m_pImpl->m_pImplLB->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT ) != 0 );
666  }
667  else if( nType == StateChangedType::Mirroring )
668  {
669  if (m_pImpl->m_pBtn)
670  {
671  m_pImpl->m_pBtn->EnableRTL( IsRTLEnabled() );
672  ImplInitDropDownButton( m_pImpl->m_pBtn );
673  }
674  m_pImpl->m_pSubEdit->CompatStateChanged( StateChangedType::Mirroring );
675  m_pImpl->m_pImplLB->EnableRTL( IsRTLEnabled() );
676  Resize();
677  }
678 }
679 
681 {
682  Control::DataChanged( rDCEvt );
683 
684  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
686  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
687  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
688  {
689  if (m_pImpl->m_pBtn)
690  {
691  m_pImpl->m_pBtn->SetSettings( GetSettings() );
692  ImplInitDropDownButton( m_pImpl->m_pBtn );
693  }
694  Resize();
695  m_pImpl->m_pImplLB->Resize(); // not called by ComboBox::Resize() if ImplLB is unchanged
696 
697  SetBackground(); // due to a hack in Window::UpdateSettings the background must be reset
698  // otherwise it will overpaint NWF drawn comboboxes
699  }
700 }
701 
703 {
704  bool bDone = false;
705  if ((rNEvt.GetType() == MouseNotifyEvent::KEYINPUT)
706  && (rNEvt.GetWindow() == m_pImpl->m_pSubEdit)
707  && !IsReadOnly())
708  {
709  KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
710  sal_uInt16 nKeyCode = aKeyEvt.GetKeyCode().GetCode();
711  switch( nKeyCode )
712  {
713  case KEY_UP:
714  case KEY_DOWN:
715  case KEY_PAGEUP:
716  case KEY_PAGEDOWN:
717  {
718  m_pImpl->ImplUpdateFloatSelection();
719  if ((nKeyCode == KEY_DOWN) && m_pImpl->m_pFloatWin
720  && !m_pImpl->m_pFloatWin->IsInPopupMode()
721  && aKeyEvt.GetKeyCode().IsMod2())
722  {
724  m_pImpl->m_pBtn->SetPressed( true );
725  if (m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount())
726  m_pImpl->m_pImplLB->SelectEntry( 0 , true );
728  m_pImpl->m_pFloatWin->StartFloat( false );
730  bDone = true;
731  }
732  else if ((nKeyCode == KEY_UP) && m_pImpl->m_pFloatWin
733  && m_pImpl->m_pFloatWin->IsInPopupMode()
734  && aKeyEvt.GetKeyCode().IsMod2())
735  {
736  m_pImpl->m_pFloatWin->EndPopupMode();
737  bDone = true;
738  }
739  else
740  {
741  bDone = m_pImpl->m_pImplLB->ProcessKeyInput( aKeyEvt );
742  }
743  }
744  break;
745 
746  case KEY_RETURN:
747  {
748  if ((rNEvt.GetWindow() == m_pImpl->m_pSubEdit) && IsInDropDown())
749  {
750  m_pImpl->m_pImplLB->ProcessKeyInput( aKeyEvt );
751  bDone = true;
752  }
753  }
754  break;
755  }
756  }
757  else if ((rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS) && m_pImpl->m_pFloatWin)
758  {
759  if (m_pImpl->m_pFloatWin->HasChildPathFocus())
760  m_pImpl->m_pSubEdit->GrabFocus();
761  else if (m_pImpl->m_pFloatWin->IsInPopupMode() && !HasChildPathFocus(true))
762  m_pImpl->m_pFloatWin->EndPopupMode();
763  }
764  else if( (rNEvt.GetType() == MouseNotifyEvent::COMMAND) &&
766  (rNEvt.GetWindow() == m_pImpl->m_pSubEdit) )
767  {
768  MouseWheelBehaviour nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() );
769  if ( ( nWheelBehavior == MouseWheelBehaviour::ALWAYS )
770  || ( ( nWheelBehavior == MouseWheelBehaviour::FocusOnly )
771  && HasChildPathFocus()
772  )
773  )
774  {
775  bDone = m_pImpl->m_pImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() );
776  }
777  else
778  {
779  bDone = false; // don't eat this event, let the default handling happen (i.e. scroll the context)
780  }
781  }
782  else if ((rNEvt.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN)
783  && (rNEvt.GetWindow() == m_pImpl->m_pImplLB->GetMainWindow()))
784  {
785  m_pImpl->m_pSubEdit->GrabFocus();
786  }
787 
788  return bDone || Edit::EventNotify( rNEvt );
789 }
790 
791 void ComboBox::SetText( const OUString& rStr )
792 {
794 
795  Edit::SetText( rStr );
796  m_pImpl->ImplUpdateFloatSelection();
797 }
798 
799 void ComboBox::SetText( const OUString& rStr, const Selection& rNewSelection )
800 {
802 
803  Edit::SetText( rStr, rNewSelection );
804  m_pImpl->ImplUpdateFloatSelection();
805 }
806 
808 {
809  if (!m_pImpl->m_isSyntheticModify)
810  m_pImpl->ImplUpdateFloatSelection();
811 
812  Edit::Modify();
813 }
814 
816 {
817  if (!m_pImplLB || !m_pSubEdit)
818  return;
819 
820  // move text in the ListBox into the visible region
821  m_pImplLB->SetCallSelectionChangedHdl( false );
822  if (!m_rThis.IsMultiSelectionEnabled())
823  {
824  OUString aSearchStr( m_pSubEdit->GetText() );
825  sal_Int32 nSelect = LISTBOX_ENTRY_NOTFOUND;
826  bool bSelect = true;
827 
828  if (m_pImplLB->GetCurrentPos() != LISTBOX_ENTRY_NOTFOUND)
829  {
830  OUString aCurrent = m_pImplLB->GetEntryList()->GetEntryText(
831  m_pImplLB->GetCurrentPos());
832  if ( aCurrent == aSearchStr )
833  nSelect = m_pImplLB->GetCurrentPos();
834  }
835 
836  if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
837  nSelect = m_pImplLB->GetEntryList()->FindEntry( aSearchStr );
838  if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
839  {
840  nSelect = m_pImplLB->GetEntryList()->FindMatchingEntry( aSearchStr, 0, true );
841  bSelect = false;
842  }
843 
844  if( nSelect != LISTBOX_ENTRY_NOTFOUND )
845  {
846  if (!m_pImplLB->IsVisible(nSelect))
847  m_pImplLB->ShowProminentEntry( nSelect );
848  m_pImplLB->SelectEntry( nSelect, bSelect );
849  }
850  else
851  {
852  nSelect = m_pImplLB->GetEntryList()->GetSelectedEntryPos( 0 );
853  if( nSelect != LISTBOX_ENTRY_NOTFOUND )
854  m_pImplLB->SelectEntry( nSelect, false );
855  m_pImplLB->ResetCurrentPos();
856  }
857  }
858  else
859  {
860  ::std::set< sal_Int32 > aSelInText;
861  lcl_GetSelectedEntries(aSelInText, m_pSubEdit->GetText(), m_cMultiSep, m_pImplLB->GetEntryList());
862  for (sal_Int32 n = 0; n < m_pImplLB->GetEntryList()->GetEntryCount(); n++)
863  m_pImplLB->SelectEntry( n, aSelInText.count( n ) != 0 );
864  }
865  m_pImplLB->SetCallSelectionChangedHdl( true );
866 }
867 
868 sal_Int32 ComboBox::InsertEntry(const OUString& rStr, sal_Int32 const nPos)
869 {
870  assert(nPos >= 0 && COMBOBOX_MAX_ENTRIES > m_pImpl->m_pImplLB->GetEntryList()->GetEntryCount());
871 
872  sal_Int32 nRealPos;
873  if (nPos == COMBOBOX_APPEND)
874  nRealPos = nPos;
875  else
876  {
877  const sal_Int32 nMRUCount = m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
878  assert(nPos <= COMBOBOX_MAX_ENTRIES - nMRUCount);
879  nRealPos = nPos + nMRUCount;
880  }
881 
882  nRealPos = m_pImpl->m_pImplLB->InsertEntry( nRealPos, rStr );
883  nRealPos -= m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
884  CallEventListeners( VclEventId::ComboboxItemAdded, reinterpret_cast<void*>(nRealPos) );
885  return nRealPos;
886 }
887 
889  const OUString& rStr, const Image& rImage, sal_Int32 const nPos)
890 {
891  assert(nPos >= 0 && COMBOBOX_MAX_ENTRIES > m_pImpl->m_pImplLB->GetEntryList()->GetEntryCount());
892 
893  sal_Int32 nRealPos;
894  if (nPos == COMBOBOX_APPEND)
895  nRealPos = nPos;
896  else
897  {
898  const sal_Int32 nMRUCount = m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
899  assert(nPos <= COMBOBOX_MAX_ENTRIES - nMRUCount);
900  nRealPos = nPos + nMRUCount;
901  }
902 
903  nRealPos = m_pImpl->m_pImplLB->InsertEntry( nRealPos, rStr, rImage );
904  nRealPos -= m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
905  CallEventListeners( VclEventId::ComboboxItemAdded, reinterpret_cast<void*>(nRealPos) );
906  return nRealPos;
907 }
908 
909 void ComboBox::RemoveEntry( const OUString& rStr )
910 {
911  RemoveEntryAt(GetEntryPos(rStr));
912 }
913 
914 void ComboBox::RemoveEntryAt(sal_Int32 const nPos)
915 {
916  const sal_Int32 nMRUCount = m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
917  assert(nPos >= 0 && nPos <= COMBOBOX_MAX_ENTRIES - nMRUCount);
918  m_pImpl->m_pImplLB->RemoveEntry( nPos + nMRUCount );
919  CallEventListeners( VclEventId::ComboboxItemRemoved, reinterpret_cast<void*>(nPos) );
920 }
921 
923 {
924  if (!m_pImpl->m_pImplLB)
925  return;
926  m_pImpl->m_pImplLB->Clear();
927  CallEventListeners( VclEventId::ComboboxItemRemoved, reinterpret_cast<void*>(-1) );
928 }
929 
930 Image ComboBox::GetEntryImage( sal_Int32 nPos ) const
931 {
932  if (m_pImpl->m_pImplLB->GetEntryList()->HasEntryImage(nPos))
933  return m_pImpl->m_pImplLB->GetEntryList()->GetEntryImage( nPos );
934  return Image();
935 }
936 
937 sal_Int32 ComboBox::GetEntryPos( const OUString& rStr ) const
938 {
939  sal_Int32 nPos = m_pImpl->m_pImplLB->GetEntryList()->FindEntry( rStr );
940  if ( nPos != LISTBOX_ENTRY_NOTFOUND )
941  nPos -= m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
942  return nPos;
943 }
944 
945 OUString ComboBox::GetEntry( sal_Int32 nPos ) const
946 {
947  const sal_Int32 nMRUCount = m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
948  if (nPos < 0 || nPos > COMBOBOX_MAX_ENTRIES - nMRUCount)
949  return OUString();
950 
951  return m_pImpl->m_pImplLB->GetEntryList()->GetEntryText( nPos + nMRUCount );
952 }
953 
954 sal_Int32 ComboBox::GetEntryCount() const
955 {
956  if (!m_pImpl->m_pImplLB)
957  return 0;
958  return m_pImpl->m_pImplLB->GetEntryList()->GetEntryCount() - m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount();
959 }
960 
962 {
963  return m_pImpl->m_pImplLB->IsTravelSelect();
964 }
965 
967 {
968  // when the dropdown is dismissed, first mbInPopupMode is set to false, and on the next event iteration then
969  // mbPopupMode is set to false
970  return m_pImpl->m_pFloatWin && m_pImpl->m_pFloatWin->IsInPopupMode() && m_pImpl->m_pFloatWin->ImplIsInPrivatePopupMode();
971 }
972 
974 {
975  return m_pImpl->m_pImplLB->IsMultiSelectionEnabled();
976 }
977 
978 void ComboBox::SetSelectHdl(const Link<ComboBox&,void>& rLink) { m_pImpl->m_SelectHdl = rLink; }
979 
980 const Link<ComboBox&,void>& ComboBox::GetSelectHdl() const { return m_pImpl->m_SelectHdl; }
981 
982 void ComboBox::SetDoubleClickHdl(const Link<ComboBox&,void>& rLink) { m_pImpl->m_DoubleClickHdl = rLink; }
983 
984 const Link<ComboBox&,void>& ComboBox::GetDoubleClickHdl() const { return m_pImpl->m_DoubleClickHdl; }
985 
987 {
988  if (!m_pImpl->m_pSubEdit)
989  return;
990  m_pImpl->m_pSubEdit->SetActivateHdl(rLink);
991 }
992 
993 long ComboBox::CalcWindowSizePixel(sal_uInt16 nLines) const
994 {
995  return m_pImpl->m_pImplLB->GetEntryHeight() * nLines;
996 }
997 
999 {
1000  return CalcMinimumSize();
1001 }
1002 
1004 {
1005  long nButtonDownWidth = 0;
1006 
1008  ImplControlValue aControlValue;
1009  tools::Rectangle aContent, aBound;
1010 
1011  // use the full extent of the control
1012  tools::Rectangle aArea( Point(), pBorder->GetOutputSizePixel() );
1013 
1015  aArea, ControlState::NONE, aControlValue, aBound, aContent) )
1016  {
1017  nButtonDownWidth = aContent.getWidth();
1018  }
1019 
1020  long nScrollBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
1021 
1022  return std::max(nScrollBarWidth, nButtonDownWidth);
1023 }
1024 
1026 {
1027  Size aSz;
1028 
1029  if (!m_pImpl->m_pImplLB)
1030  return aSz;
1031 
1032  if (!IsDropDownBox())
1033  {
1034  aSz = m_pImpl->m_pImplLB->CalcSize( m_pImpl->m_pImplLB->GetEntryList()->GetEntryCount() );
1035  aSz.AdjustHeight(m_pImpl->m_nDDHeight );
1036  }
1037  else
1038  {
1040 
1041  if (m_pImpl->m_nWidthInChars!= -1)
1042  aSz.setWidth(m_pImpl->m_nWidthInChars * approximate_digit_width());
1043  else
1044  aSz.setWidth(m_pImpl->m_pImplLB->GetMaxEntryWidth());
1045  }
1046 
1047  if (m_pImpl->m_nMaxWidthChars != -1)
1048  {
1049  long nMaxWidth = m_pImpl->m_nMaxWidthChars * approximate_char_width();
1050  aSz.setWidth( std::min(aSz.Width(), nMaxWidth) );
1051  }
1052 
1053  if (IsDropDownBox())
1055 
1056  ComboBoxBounds aBounds(m_pImpl->calcComboBoxDropDownComponentBounds(
1057  Size(0xFFFF, 0xFFFF), Size(0xFFFF, 0xFFFF)));
1058  aSz.AdjustWidth(aBounds.aSubEditPos.X()*2 );
1059 
1060  aSz.AdjustWidth(ImplGetExtraXOffset() * 2 );
1061 
1062  aSz = CalcWindowSize( aSz );
1063  return aSz;
1064 }
1065 
1066 Size ComboBox::CalcAdjustedSize( const Size& rPrefSize ) const
1067 {
1068  Size aSz = rPrefSize;
1069  sal_Int32 nLeft, nTop, nRight, nBottom;
1070  static_cast<vcl::Window*>(const_cast<ComboBox *>(this))->GetBorder( nLeft, nTop, nRight, nBottom );
1071  aSz.AdjustHeight( -(nTop+nBottom) );
1072  if ( !IsDropDownBox() )
1073  {
1074  long nEntryHeight = CalcBlockSize( 1, 1 ).Height();
1075  long nLines = aSz.Height() / nEntryHeight;
1076  if ( nLines < 1 )
1077  nLines = 1;
1078  aSz.setHeight( nLines * nEntryHeight );
1079  aSz.AdjustHeight(m_pImpl->m_nDDHeight );
1080  }
1081  else
1082  {
1083  aSz.setHeight( m_pImpl->m_nDDHeight );
1084  }
1085  aSz.AdjustHeight(nTop+nBottom );
1086 
1087  aSz = CalcWindowSize( aSz );
1088  return aSz;
1089 }
1090 
1091 Size ComboBox::CalcBlockSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
1092 {
1093  // show ScrollBars where appropriate
1094  Size aMinSz = CalcMinimumSize();
1095  Size aSz;
1096 
1097  // height
1098  if ( nLines )
1099  {
1100  if ( !IsDropDownBox() )
1101  aSz.setHeight( m_pImpl->m_pImplLB->CalcSize( nLines ).Height() + m_pImpl->m_nDDHeight );
1102  else
1103  aSz.setHeight( m_pImpl->m_nDDHeight );
1104  }
1105  else
1106  aSz.setHeight( aMinSz.Height() );
1107 
1108  // width
1109  if ( nColumns )
1110  aSz.setWidth( nColumns * approximate_char_width() );
1111  else
1112  aSz.setWidth( aMinSz.Width() );
1113 
1114  if ( IsDropDownBox() )
1116 
1117  if ( !IsDropDownBox() )
1118  {
1119  if ( aSz.Width() < aMinSz.Width() )
1120  aSz.AdjustHeight(GetSettings().GetStyleSettings().GetScrollBarSize() );
1121  if ( aSz.Height() < aMinSz.Height() )
1122  aSz.AdjustWidth(GetSettings().GetStyleSettings().GetScrollBarSize() );
1123  }
1124 
1125  aSz.AdjustWidth(ImplGetExtraXOffset() * 2 );
1126 
1127  aSz = CalcWindowSize( aSz );
1128  return aSz;
1129 }
1130 
1131 void ComboBox::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
1132 {
1133  long nCharWidth = GetTextWidth(OUString(u'x'));
1134  if ( !IsDropDownBox() )
1135  {
1136  Size aOutSz = m_pImpl->m_pImplLB->GetMainWindow()->GetOutputSizePixel();
1137  rnCols = (nCharWidth > 0) ? static_cast<sal_uInt16>(aOutSz.Width()/nCharWidth) : 1;
1138  rnLines = static_cast<sal_uInt16>(aOutSz.Height()/m_pImpl->m_pImplLB->GetEntryHeight());
1139  }
1140  else
1141  {
1142  Size aOutSz = m_pImpl->m_pSubEdit->GetOutputSizePixel();
1143  rnCols = (nCharWidth > 0) ? static_cast<sal_uInt16>(aOutSz.Width()/nCharWidth) : 1;
1144  rnLines = 1;
1145  }
1146 }
1147 
1148 void ComboBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, DrawFlags nFlags )
1149 {
1150  m_pImpl->m_pImplLB->GetMainWindow()->ApplySettings(*pDev);
1151 
1152  Point aPos = pDev->LogicToPixel( rPos );
1153  Size aSize = pDev->LogicToPixel( rSize );
1154  vcl::Font aFont = m_pImpl->m_pImplLB->GetMainWindow()->GetDrawPixelFont( pDev );
1155  OutDevType eOutDevType = pDev->GetOutDevType();
1156 
1157  pDev->Push();
1158  pDev->SetMapMode();
1159  pDev->SetFont( aFont );
1160  pDev->SetTextFillColor();
1161 
1162  // Border/Background
1163  pDev->SetLineColor();
1164  pDev->SetFillColor();
1165  bool bBorder = (GetStyle() & WB_BORDER);
1166  bool bBackground = IsControlBackground();
1167  if ( bBorder || bBackground )
1168  {
1169  tools::Rectangle aRect( aPos, aSize );
1170  // aRect.Top() += nEditHeight;
1171  if ( bBorder )
1172  {
1173  ImplDrawFrame( pDev, aRect );
1174  }
1175  if ( bBackground )
1176  {
1178  pDev->DrawRect( aRect );
1179  }
1180  }
1181 
1182  // contents
1183  if ( !IsDropDownBox() )
1184  {
1185  long nOnePixel = GetDrawPixel( pDev, 1 );
1186  long nTextHeight = pDev->GetTextHeight();
1187  long nEditHeight = nTextHeight + 6*nOnePixel;
1189 
1190  // First, draw the edit part
1191  m_pImpl->m_pSubEdit->Draw( pDev, aPos, Size( aSize.Width(), nEditHeight ), nFlags );
1192 
1193  // Second, draw the listbox
1194  if ( GetStyle() & WB_CENTER )
1195  nTextStyle |= DrawTextFlags::Center;
1196  else if ( GetStyle() & WB_RIGHT )
1197  nTextStyle |= DrawTextFlags::Right;
1198  else
1199  nTextStyle |= DrawTextFlags::Left;
1200 
1201  if ( ( nFlags & DrawFlags::Mono ) || ( eOutDevType == OUTDEV_PRINTER ) )
1202  {
1203  pDev->SetTextColor( COL_BLACK );
1204  }
1205  else
1206  {
1207  if ( !IsEnabled() )
1208  {
1209  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1210  pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1211  }
1212  else
1213  {
1214  pDev->SetTextColor( GetTextColor() );
1215  }
1216  }
1217 
1218  tools::Rectangle aClip( aPos, aSize );
1219  pDev->IntersectClipRegion( aClip );
1220  sal_Int32 nLines = static_cast<sal_Int32>( nTextHeight > 0 ? (aSize.Height()-nEditHeight)/nTextHeight : 1 );
1221  if ( !nLines )
1222  nLines = 1;
1223  const sal_Int32 nTEntry = IsReallyVisible() ? m_pImpl->m_pImplLB->GetTopEntry() : 0;
1224 
1225  tools::Rectangle aTextRect( aPos, aSize );
1226 
1227  aTextRect.AdjustLeft(3*nOnePixel );
1228  aTextRect.AdjustRight( -(3*nOnePixel) );
1229  aTextRect.AdjustTop(nEditHeight + nOnePixel );
1230  aTextRect.SetBottom( aTextRect.Top() + nTextHeight );
1231 
1232  // the drawing starts here
1233  for ( sal_Int32 n = 0; n < nLines; ++n )
1234  {
1235  pDev->DrawText( aTextRect, m_pImpl->m_pImplLB->GetEntryList()->GetEntryText( n+nTEntry ), nTextStyle );
1236  aTextRect.AdjustTop(nTextHeight );
1237  aTextRect.AdjustBottom(nTextHeight );
1238  }
1239  }
1240 
1241  pDev->Pop();
1242 
1243  // Call Edit::Draw after restoring the MapMode...
1244  if ( IsDropDownBox() )
1245  {
1246  m_pImpl->m_pSubEdit->Draw( pDev, rPos, rSize, nFlags );
1247  // DD-Button ?
1248  }
1249 
1250 }
1251 
1252 IMPL_LINK(ComboBox::Impl, ImplUserDrawHdl, UserDrawEvent*, pEvent, void)
1253 {
1254  m_rThis.UserDraw(*pEvent);
1255 }
1256 
1258 {
1259 }
1260 
1262 {
1263  m_pImpl->m_pImplLB->GetMainWindow()->SetUserItemSize( rSz );
1264 }
1265 
1266 void ComboBox::EnableUserDraw( bool bUserDraw )
1267 {
1268  m_pImpl->m_pImplLB->GetMainWindow()->EnableUserDraw( bUserDraw );
1269 }
1270 
1271 void ComboBox::DrawEntry(const UserDrawEvent& rEvt, bool bDrawImage, bool bDrawText, bool bDrawTextAtImagePos)
1272 {
1273  SAL_WARN_IF(rEvt.GetWindow() != m_pImpl->m_pImplLB->GetMainWindow(), "vcl", "DrawEntry?!");
1274  m_pImpl->m_pImplLB->GetMainWindow()->DrawEntry(*rEvt.GetRenderContext(), rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos);
1275 }
1276 
1277 void ComboBox::SetSeparatorPos( sal_Int32 n )
1278 {
1279  m_pImpl->m_pImplLB->SetSeparatorPos( n );
1280 }
1281 
1282 void ComboBox::AddSeparator( sal_Int32 n )
1283 {
1284  m_pImpl->m_pImplLB->AddSeparator( n );
1285 }
1286 
1287 void ComboBox::SetMRUEntries( const OUString& rEntries )
1288 {
1289  m_pImpl->m_pImplLB->SetMRUEntries( rEntries, ';' );
1290 }
1291 
1292 OUString ComboBox::GetMRUEntries() const
1293 {
1294  return m_pImpl->m_pImplLB ? m_pImpl->m_pImplLB->GetMRUEntries( ';' ) : OUString();
1295 }
1296 
1297 void ComboBox::SetMaxMRUCount( sal_Int32 n )
1298 {
1299  m_pImpl->m_pImplLB->SetMaxMRUCount( n );
1300 }
1301 
1302 sal_Int32 ComboBox::GetMaxMRUCount() const
1303 {
1304  return m_pImpl->m_pImplLB ? m_pImpl->m_pImplLB->GetMaxMRUCount() : 0;
1305 }
1306 
1308 {
1309  return m_pImpl->m_pImplLB ? m_pImpl->m_pImplLB->GetDisplayLineCount() : 0;
1310 }
1311 
1312 void ComboBox::SetEntryData( sal_Int32 nPos, void* pNewData )
1313 {
1314  m_pImpl->m_pImplLB->SetEntryData( nPos + m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount(), pNewData );
1315 }
1316 
1317 void* ComboBox::GetEntryData( sal_Int32 nPos ) const
1318 {
1319  return m_pImpl->m_pImplLB->GetEntryList()->GetEntryData(
1320  nPos + m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount() );
1321 }
1322 
1323 sal_Int32 ComboBox::GetTopEntry() const
1324 {
1325  sal_Int32 nPos = GetEntryCount() ? m_pImpl->m_pImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND;
1326  if (nPos < m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount())
1327  nPos = 0;
1328  return nPos;
1329 }
1330 
1332 {
1333  m_pImpl->m_pImplLB->SetProminentEntryType( eType );
1334 }
1335 
1337 {
1338  return m_pImpl->m_pFloatWin
1339  ? m_pImpl->m_pFloatWin->GetWindowExtentsRelative(const_cast<ComboBox*>(this))
1340  : tools::Rectangle();
1341 }
1342 
1344 {
1345  if (!m_pImpl->m_pSubEdit->IsBackground())
1347 
1348  const Wallpaper& rBack = m_pImpl->m_pSubEdit->GetBackground();
1349  if( ! rBack.IsBitmap() &&
1350  ! rBack.IsGradient() &&
1351  rBack == COL_TRANSPARENT
1352  )
1354  return rBack;
1355 }
1356 
1358 {
1359  return m_pImpl->m_pImplLB->GetEntryList()->GetSelectedEntryCount();
1360 }
1361 
1362 sal_Int32 ComboBox::GetSelectedEntryPos( sal_Int32 nIndex ) const
1363 {
1364  sal_Int32 nPos = m_pImpl->m_pImplLB->GetEntryList()->GetSelectedEntryPos( nIndex );
1365  if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1366  {
1367  if (nPos < m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount())
1368  nPos = m_pImpl->m_pImplLB->GetEntryList()->FindEntry(m_pImpl->m_pImplLB->GetEntryList()->GetEntryText(nPos));
1369  nPos = sal::static_int_cast<sal_Int32>(nPos - m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount());
1370  }
1371  return nPos;
1372 }
1373 
1374 bool ComboBox::IsEntryPosSelected( sal_Int32 nPos ) const
1375 {
1376  return m_pImpl->m_pImplLB->GetEntryList()->IsEntryPosSelected(
1377  nPos + m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount() );
1378 }
1379 
1380 void ComboBox::SelectEntryPos( sal_Int32 nPos, bool bSelect)
1381 {
1382  if (nPos < m_pImpl->m_pImplLB->GetEntryList()->GetEntryCount())
1383  m_pImpl->m_pImplLB->SelectEntry(
1384  nPos + m_pImpl->m_pImplLB->GetEntryList()->GetMRUCount(), bSelect);
1385 }
1386 
1388 {
1389  m_pImpl->m_pImplLB->SetNoSelection();
1390  m_pImpl->m_pSubEdit->SetText( OUString() );
1391 }
1392 
1394 {
1395  tools::Rectangle aRect = m_pImpl->m_pImplLB->GetMainWindow()->GetBoundingRectangle( nItem );
1396  tools::Rectangle aOffset = m_pImpl->m_pImplLB->GetMainWindow()->GetWindowExtentsRelative( static_cast<vcl::Window*>(const_cast<ComboBox *>(this)) );
1397  aRect.Move( aOffset.TopLeft().X(), aOffset.TopLeft().Y() );
1398  return aRect;
1399 }
1400 
1402 {
1403  Window::SetBorderStyle( nBorderStyle );
1404  if ( !IsDropDownBox() )
1405  {
1406  m_pImpl->m_pSubEdit->SetBorderStyle( nBorderStyle );
1407  m_pImpl->m_pImplLB->SetBorderStyle( nBorderStyle );
1408  }
1409 }
1410 
1411 long ComboBox::GetIndexForPoint( const Point& rPoint, sal_Int32& rPos ) const
1412 {
1413  if( !HasLayoutData() )
1414  FillLayoutData();
1415 
1416  // check whether rPoint fits at all
1417  long nIndex = Control::GetIndexForPoint( rPoint );
1418  if( nIndex != -1 )
1419  {
1420  // point must be either in main list window
1421  // or in impl window (dropdown case)
1422  ImplListBoxWindow* rMain = m_pImpl->m_pImplLB->GetMainWindow();
1423 
1424  // convert coordinates to ImplListBoxWindow pixel coordinate space
1425  Point aConvPoint = LogicToPixel( rPoint );
1426  aConvPoint = OutputToAbsoluteScreenPixel( aConvPoint );
1427  aConvPoint = rMain->AbsoluteScreenToOutputPixel( aConvPoint );
1428  aConvPoint = rMain->PixelToLogic( aConvPoint );
1429 
1430  // try to find entry
1431  sal_Int32 nEntry = rMain->GetEntryPosForPoint( aConvPoint );
1432  if( nEntry == LISTBOX_ENTRY_NOTFOUND )
1433  nIndex = -1;
1434  else
1435  rPos = nEntry;
1436  }
1437 
1438  // get line relative index
1439  if( nIndex != -1 )
1440  nIndex = ToRelativeLineIndex( nIndex );
1441 
1442  return nIndex;
1443 }
1444 
1446  const Size &rOutSz, const Size &rBorderOutSz) const
1447 {
1448  ComboBoxBounds aBounds;
1449 
1450  long nTop = 0;
1451  long nBottom = rOutSz.Height();
1452 
1453  vcl::Window *pBorder = m_rThis.GetWindow( GetWindowType::Border );
1454  ImplControlValue aControlValue;
1455  Point aPoint;
1456  tools::Rectangle aContent, aBound;
1457 
1458  // use the full extent of the control
1459  tools::Rectangle aArea( aPoint, rBorderOutSz );
1460 
1461  if (m_rThis.GetNativeControlRegion(ControlType::Combobox, ControlPart::ButtonDown,
1462  aArea, ControlState::NONE, aControlValue, aBound, aContent) )
1463  {
1464  // convert back from border space to local coordinates
1465  aPoint = pBorder->ScreenToOutputPixel(m_rThis.OutputToScreenPixel(aPoint));
1466  aContent.Move(-aPoint.X(), -aPoint.Y());
1467 
1468  aBounds.aButtonPos = Point(aContent.Left(), nTop);
1469  aBounds.aButtonSize = Size(aContent.getWidth(), (nBottom-nTop));
1470 
1471  // adjust the size of the edit field
1472  if (m_rThis.GetNativeControlRegion(ControlType::Combobox, ControlPart::SubEdit,
1473  aArea, ControlState::NONE, aControlValue, aBound, aContent) )
1474  {
1475  // convert back from border space to local coordinates
1476  aContent.Move(-aPoint.X(), -aPoint.Y());
1477 
1478  // use the themes drop down size
1479  aBounds.aSubEditPos = aContent.TopLeft();
1480  aBounds.aSubEditSize = aContent.GetSize();
1481  }
1482  else
1483  {
1484  // use the themes drop down size for the button
1485  aBounds.aSubEditSize = Size(rOutSz.Width() - aContent.getWidth(), rOutSz.Height());
1486  }
1487  }
1488  else
1489  {
1490  long nSBWidth = m_rThis.GetSettings().GetStyleSettings().GetScrollBarSize();
1491  nSBWidth = m_rThis.CalcZoom( nSBWidth );
1492  aBounds.aSubEditSize = Size(rOutSz.Width() - nSBWidth, rOutSz.Height());
1493  aBounds.aButtonPos = Point(rOutSz.Width() - nSBWidth, nTop);
1494  aBounds.aButtonSize = Size(nSBWidth, (nBottom-nTop));
1495  }
1496  return aBounds;
1497 }
1498 
1499 void ComboBox::SetWidthInChars(sal_Int32 nWidthInChars)
1500 {
1501  if (nWidthInChars != m_pImpl->m_nWidthInChars)
1502  {
1503  m_pImpl->m_nWidthInChars = nWidthInChars;
1504  queue_resize();
1505  }
1506 }
1507 
1508 void ComboBox::setMaxWidthChars(sal_Int32 nWidth)
1509 {
1510  if (nWidth != m_pImpl->m_nMaxWidthChars)
1511  {
1512  m_pImpl->m_nMaxWidthChars = nWidth;
1513  queue_resize();
1514  }
1515 }
1516 
1517 bool ComboBox::set_property(const OString &rKey, const OUString &rValue)
1518 {
1519  if (rKey == "width-chars")
1520  SetWidthInChars(rValue.toInt32());
1521  else if (rKey == "max-width-chars")
1522  setMaxWidthChars(rValue.toInt32());
1523  else if (rKey == "can-focus")
1524  {
1525  // as far as I can see in Gtk, setting a ComboBox as can.focus means
1526  // the focus gets stuck in it, so try here to behave like gtk does
1527  // with the settings that work, i.e. can.focus of false doesn't
1528  // set the hard WB_NOTABSTOP
1529  WinBits nBits = GetStyle();
1530  nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1531  if (toBool(rValue))
1532  nBits |= WB_TABSTOP;
1533  SetStyle(nBits);
1534  }
1535  else
1536  return Control::set_property(rKey, rValue);
1537  return true;
1538 }
1539 
1541 {
1542  return ComboBoxUIObject::create;
1543 }
1544 
1545 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 GetEntryPos(const OUString &rStr) const
Definition: combobox.cxx:937
Point TopLeft() const
long Width() const
void DrawEntry(const UserDrawEvent &rEvt, bool bDrawImage, bool bDrawText, bool bDrawTextAtImagePos=false)
Definition: combobox.cxx:1271
const Color & GetTextColor() const
Definition: outdev.hxx:1110
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
Definition: text.cxx:780
virtual FactoryFunction GetUITestFactory() const override
Definition: combobox.cxx:1540
OutDevType GetOutDevType() const
Definition: outdev.hxx:522
bool IsControlBackground() const
Definition: window2.cxx:1076
virtual const Wallpaper & GetDisplayBackground() const
Definition: window.cxx:3071
float approximate_char_width() const
Definition: text.cxx:902
bool ImplCallEventListenersAndHandler(VclEventId nEvent, std::function< void()> const &callHandler)
this calls both our event listeners, and a specified handler
Definition: ctrl.cxx:305
Size CalcBlockSize(sal_uInt16 nColumns, sal_uInt16 nLines) const
Definition: combobox.cxx:1091
OString stripEnd(const OString &rIn, sal_Char c)
long GetHeight() const
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
SAL_DLLPRIVATE void ImplCalcEditHeight()
Definition: combobox.cxx:147
long ToRelativeLineIndex(long nIndex) const
ToRelativeLineIndex changes a layout data index to a count relative to its line.
Definition: ctrl.cxx:211
static void lcl_GetSelectedEntries(::std::set< sal_Int32 > &rSelectedPos, const OUString &rText, sal_Unicode cTokenSep, const ImplEntryList *pEntryList)
Definition: combobox.cxx:91
Link< ComboBox &, void > m_SelectHdl
Definition: combobox.cxx:59
tools::Rectangle GetBoundingRectangle(sal_Int32 nItem) const
Definition: combobox.cxx:1393
long AdjustWidth(long n)
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
bool IsAutoSizeEnabled() const
Definition: combobox.cxx:496
#define KEY_PAGEDOWN
Definition: keycodes.hxx:117
const CommandEvent * GetCommandEvent() const
Definition: event.hxx:318
virtual void StateChanged(StateChangedType nType) override
Definition: combobox.cxx:616
bool m_isSyntheticModify
Definition: combobox.cxx:55
sal_uInt16 m_nDDHeight
Definition: combobox.cxx:52
long Height() const
SAL_DLLPRIVATE void ImplDrawFrame(OutputDevice *pDev, tools::Rectangle &rRect)
draws a frame around the give rectangle, onto the given device
Definition: ctrl.cxx:336
#define KEY_PAGEUP
Definition: keycodes.hxx:116
virtual void Draw(OutputDevice *pDev, const Point &rPos, const Size &rSize, DrawFlags nFlags) override
Definition: combobox.cxx:1148
void ImplUpdateFloatSelection()
Definition: combobox.cxx:815
WinBits const WB_NOGROUP
long getWidth() const
virtual Size CalcMinimumSizeForText(const OUString &rString) const
Definition: edit.cxx:2619
long AdjustLeft(long nHorzMoveDelta)
Point AbsoluteScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2877
sal_Int32 m_nWidthInChars
Definition: combobox.cxx:58
OUString GetMRUEntries() const
Definition: combobox.cxx:1292
void disposeAndClear()
Definition: vclptr.hxx:200
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: combobox.cxx:171
const StyleSettings & GetStyleSettings() const
void ToggleDropDown()
Definition: combobox.cxx:464
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
WinBits const WB_RIGHT
sal_Int32 GetEntryPosForPoint(const Point &rPoint) const
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: edit.cxx:213
void SetMaxMRUCount(sal_Int32 n)
Definition: combobox.cxx:1297
void SetTextFillColor()
Definition: text.cxx:698
sal_uInt16 GetCode() const
Definition: keycod.hxx:53
PosSizeFlags
Definition: window.hxx:141
DataChangedEventType GetType() const
Definition: event.hxx:348
const KeyEvent * GetKeyEvent() const
Definition: event.hxx:302
void IntersectClipRegion(const tools::Rectangle &rRect)
Point aSubEditPos
Definition: combobox.cxx:38
void AppendLayoutData(const Control &rSubControl) const
Definition: ctrl.cxx:273
bool IsTravelSelect() const
Definition: combobox.cxx:961
const Color & GetControlBackground() const
Definition: window2.cxx:1071
virtual void Select()
Definition: combobox.cxx:486
Impl(ComboBox &rThis)
Definition: combobox.cxx:62
SAL_DLLPRIVATE long getMaxWidthScrollBarAndDownButton() const
Definition: combobox.cxx:1003
long AdjustHeight(long n)
sal_Int32 FindEntry(const OUString &rStr, bool bSearchMRUArea=false) const
bool HasChildPathFocus(bool bSystemWindow=false) const
Definition: window.cxx:3008
VclPtr< ImplListBoxFloatingWindow > m_pFloatWin
Definition: combobox.cxx:51
sal_Int32 GetMaxMRUCount() const
Definition: combobox.cxx:1302
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
void SetMapMode()
Definition: map.cxx:655
const Link< ComboBox &, void > & GetDoubleClickHdl() const
Definition: combobox.cxx:984
void SetBorderStyle(WindowBorderStyle nBorderStyle)
Definition: combobox.cxx:1401
#define LISTBOX_ENTRY_NOTFOUND
Definition: lstbox.hxx:33
long AdjustBottom(long nVertMoveDelta)
VclPtr< ImplListBox > m_pImplLB
Definition: combobox.cxx:49
void Move(long nHorzMoveDelta, long nVertMoveDelta)
void SetEntryData(sal_Int32 nPos, void *pNewData)
Definition: combobox.cxx:1312
VclPtr< ImplBtn > m_pBtn
Definition: combobox.cxx:50
const Fraction & GetZoom() const
Definition: window2.cxx:1199
StateChangedType
Definition: window.hxx:311
OUString GetEntry(sal_Int32 nPos) const
Definition: combobox.cxx:945
virtual void setPosSizePixel(long nX, long nY, long nWidth, long nHeight, PosSizeFlags nFlags=PosSizeFlags::All)
Definition: window.cxx:2685
sal_uInt16 GetDisplayLineCount() const
Definition: combobox.cxx:1307
sal_Int64 WinBits
sal_uInt16 sal_Unicode
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
vcl::Window * GetWindow() const
Definition: event.hxx:295
void SetBackground()
bool IsEntryPosSelected(sal_Int32 nPos) const
Definition: combobox.cxx:1374
ESelection aNewSelection(GetSelection())
bool IsMultiSelectionEnabled() const
Definition: combobox.cxx:973
void EnableUserDraw(bool bUserDraw)
Definition: combobox.cxx:1266
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: combobox.cxx:118
Image GetEntryImage(sal_Int32 nPos) const
Definition: combobox.cxx:930
void Clear()
Definition: combobox.cxx:922
void SetSelectHdl(const Link< ComboBox &, void > &rLink)
Definition: combobox.cxx:978
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
sal_Unicode m_cMultiSep
Definition: combobox.cxx:53
sal_uInt16 GetDropDownLineCount() const
Definition: combobox.cxx:535
std::unique_ptr< Impl > m_pImpl
Definition: combobox.hxx:37
AllSettingsFlags GetFlags() const
Definition: event.hxx:349
bool IsInDropDown() const
Definition: combobox.cxx:966
virtual void queue_resize(StateChangedType eReason=StateChangedType::Layout)
Definition: window2.cxx:1303
void SetCompoundControl(bool bCompound)
Definition: window2.cxx:936
long Top() const
Definition: edit.hxx:57
OString strip(const OString &rIn, sal_Char c)
ComboBox(vcl::Window *pParent, WinBits nStyle=0)
Definition: combobox.cxx:104
void AdaptDropDownLineCountToMaximum()
Definition: combobox.cxx:525
virtual void SetSelection(const Selection &rSelection)
Definition: edit.cxx:2394
void SetProminentEntryType(ProminentEntry eType)
Definition: combobox.cxx:1331
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:32
void SetWidthInChars(sal_Int32 nWidthInChars)
Definition: combobox.cxx:1499
const Color & GetControlForeground() const
Definition: window2.cxx:1061
long GetDrawPixel(::OutputDevice const *pDev, long nPixels) const
Definition: window2.cxx:563
static SAL_DLLPRIVATE WinBits ImplInitStyle(WinBits nStyle)
Definition: combobox.cxx:248
long GetIndexForPoint(const Point &rPoint, sal_Int32 &rPos) const
Definition: combobox.cxx:1411
void SetUserItemSize(const Size &rSz)
Definition: combobox.cxx:1261
void RemoveEntry(const OUString &rStr)
Definition: combobox.cxx:909
virtual Size GetOptimalSize() const override
Definition: combobox.cxx:998
WinBits const WB_NOLIGHTBORDER
Size CalcWindowSize(const Size &rOutSz) const
Definition: window2.cxx:537
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: combobox.cxx:680
void SetLineColor()
virtual void setPosSizePixel(long nX, long nY, long nWidth, long nHeight, PosSizeFlags nFlags=PosSizeFlags::All) override
Definition: combobox.cxx:543
bool IsDropDownBox() const
Definition: combobox.cxx:592
const Color & GetDisableColor() const
bool IsRTLEnabled() const
Definition: outdev.hxx:1354
vcl::RenderContext * GetRenderContext() const
Definition: event.hxx:223
void SetEntryActivateHdl(const Link< Edit &, bool > &rLink)
Definition: combobox.cxx:986
DrawFlags
Definition: window.hxx:354
void setMaxWidthChars(sal_Int32 nWidth)
Definition: combobox.cxx:1508
OutDevType
Definition: outdev.hxx:278
The edit field part of a control, e.g.
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: combobox.cxx:702
virtual void StateChanged(StateChangedType nType) override
Definition: edit.cxx:2145
float approximate_digit_width() const
Definition: text.cxx:910
WinBits const WB_SIMPLEMODE
virtual void UserDraw(const UserDrawEvent &rUDEvt)
Definition: combobox.cxx:1257
SAL_DLLPRIVATE long ImplGetExtraXOffset() const
Definition: edit.cxx:394
void SetNoSelection()
Definition: combobox.cxx:1387
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1156
virtual OUString GetText() const override
Definition: edit.cxx:2564
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: ctrl.cxx:297
bool IsUpdateMode() const
Definition: window2.cxx:1162
void SetFillColor()
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
CommandEventId GetCommand() const
virtual void Modify()
Definition: edit.cxx:2305
sal_Int32 GetSelectedEntryPos(sal_Int32 nSelIndex=0) const
Definition: combobox.cxx:1362
float u
void SetTextColor(const Color &rColor)
Definition: text.cxx:663
WinBits const WB_RECTSTYLE
void RemoveEntryAt(sal_Int32 nPos)
Definition: combobox.cxx:914
MouseNotifyEvent GetType() const
Definition: event.hxx:294
IMPL_LINK_NOARG(ComboBox::Impl, ImplClickBtnHdl, void *, void)
Definition: combobox.cxx:272
void SetSubEdit(Edit *pEdit)
Definition: edit.cxx:2604
WinBits const WB_DROPDOWN
virtual ~ComboBox() override
Definition: combobox.cxx:113
static bool toBool(const OString &rValue)
Definition: builder.cxx:70
const AllSettings & GetSettings() const
Definition: outdev.hxx:420
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
DrawTextFlags
Definition: outdev.hxx:144
virtual bool set_property(const OString &rKey, const OUString &rValue)
Definition: window2.cxx:1420
WinBits const WB_SORT
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2824
long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:889
WinBits const WB_LEFT
IMPL_LINK(ComboBox::Impl, ImplAutocompleteHdl, Edit &, rEdit, void)
Definition: combobox.cxx:313
long X() const
void SetStyle(WinBits nStyle)
Definition: window.cxx:1925
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2867
Size GetSize() const
WinBits const WB_NOBORDER
sal_uInt16 GetItemId() const
Definition: event.hxx:225
ComboBox & m_rThis
Definition: combobox.cxx:47
void EnableAutocomplete(bool bEnable, bool bMatchCase=false)
Definition: combobox.cxx:257
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
void GetMaxVisColumnsAndLines(sal_uInt16 &rnCols, sal_uInt16 &rnLines) const
Definition: combobox.cxx:1131
ProminentEntry
Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1185
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:940
void ImplInitComboBoxData()
Definition: combobox.cxx:131
tools::Rectangle GetDropDownPosSizePixel() const
Definition: combobox.cxx:1336
void SetSeparatorPos(sal_Int32 n)
Definition: combobox.cxx:1277
long GetIndexForPoint(const Point &rPoint) const
Definition: ctrl.cxx:134
virtual const Wallpaper & GetDisplayBackground() const override
Definition: combobox.cxx:1343
ControlType
These types are all based on the supported variants vcl/salnativewidgets.hxx and must be kept in-sync...
#define KEY_RETURN
Definition: keycodes.hxx:119
void SetDoubleClickHdl(const Link< ComboBox &, void > &rLink)
Definition: combobox.cxx:982
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2386
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:53
bool IsGradient() const
Definition: wall.cxx:283
Link< ComboBox &, void > m_DoubleClickHdl
Definition: combobox.cxx:60
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: combobox.cxx:1517
virtual void Resize() override
Definition: ctrl.cxx:74
#define KEY_DOWN
Definition: keycodes.hxx:110
weld::Entry & rEdit
long AdjustRight(long nHorzMoveDelta)
VclPtr< Edit > m_pSubEdit
Definition: combobox.cxx:48
WindowType
sal_Int32 GetEntryCount() const
Definition: combobox.cxx:954
#define SAL_WARN_IF(condition, area, stream)
WinBits const WB_BORDER
Size aSubEditSize
Definition: combobox.cxx:39
void SetFont(const vcl::Font &rNewFont)
bool m_isMatchCase
Definition: combobox.cxx:56
std::unique_ptr< vcl::ImplControlData > mpControlData
Definition: ctrl.hxx:36
bool IsAutocompleteEnabled() const
Definition: combobox.cxx:267
Point aButtonPos
Definition: combobox.cxx:41
#define COMBOBOX_MAX_ENTRIES
Definition: combobox.hxx:29
sal_Int32 GetTopEntry() const
Definition: combobox.cxx:1323
bool m_isDDAutoSize
Definition: combobox.cxx:54
Definition: image.hxx:40
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
void SetBottom(long v)
Size CalcAdjustedSize(const Size &rPrefSize) const
Definition: combobox.cxx:1066
long AdjustTop(long nVertMoveDelta)
const Link< ComboBox &, void > & GetSelectHdl() const
Definition: combobox.cxx:980
void EnableSelectAll()
Definition: combobox.cxx:514
WinBits const WB_AUTOHSCROLL
long Left() const
sal_Int32 GetSelectedEntryCount() const
Definition: combobox.cxx:1357
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: text.cxx:878
WinBits const WB_TABSTOP
void * GetEntryData(sal_Int32 nPos) const
Definition: combobox.cxx:1317
virtual void FillLayoutData() const override
Definition: combobox.cxx:594
void DoubleClick()
Definition: combobox.cxx:491
Size aButtonSize
Definition: combobox.cxx:42
bool IsBitmap() const
Definition: wall.cxx:255
A widget used to choose from a list of items and which has an entry.
Definition: combobox.hxx:34
sal_Int32 m_nMaxWidthChars
Definition: combobox.cxx:57
Event to pass information for UserDraw() handling eg. in comboboxes.
Definition: event.hxx:205
WinBits const WB_CENTER
#define SELECTION_MAX
bool IsEnabled() const
Definition: window2.cxx:1111
void SetDropDownLineCount(sal_uInt16 nLines)
Definition: combobox.cxx:519
sal_Int32 InsertEntryWithImage(const OUString &rStr, const Image &rImage, sal_Int32 nPos=COMBOBOX_APPEND)
Definition: combobox.cxx:888
MouseWheelBehaviour
Definition: settings.hxx:83
WinBits GetStyle() const
Definition: window2.cxx:942
long Max() const
WindowBorderStyle
Definition: vclenum.hxx:108
WinBits const WB_GROUP
void SelectEntryPos(sal_Int32 nPos, bool bSelect=true)
Definition: combobox.cxx:1380
sal_Int32 InsertEntry(const OUString &rStr, sal_Int32 nPos=COMBOBOX_APPEND)
Definition: combobox.cxx:868
virtual bool IsReadOnly() const
Definition: edit.hxx:181
void ImplInitDropDownButton(PushButton *pButton)
Definition: imp_listbox.cxx:50
virtual void SetText(const OUString &rStr) override
Definition: edit.cxx:2545
void SetMRUEntries(const OUString &rEntries)
Definition: combobox.cxx:1287
long GetScrollBarSize() const
bool IsReallyVisible() const
Definition: window2.cxx:1096
vcl::Font GetControlFont() const
Definition: window2.cxx:438
DECL_DLLPRIVATE_LINK(ImplSelectHdl, LinkParamNone *, void)
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
sal_Int32 nPos
virtual void SetText(const OUString &rStr) override
Definition: combobox.cxx:791
void setWidth(long nWidth)
void AddSeparator(sal_Int32 n)
Adds a new separator at the given position n.
Definition: combobox.cxx:1282
vcl::Window * GetWindow() const
Definition: event.hxx:222
WinBits const WB_NOTABSTOP
Size CalcMinimumSize() const override
Definition: combobox.cxx:1025
void EnableAutoSize(bool bAuto)
Definition: combobox.cxx:498
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: edit.cxx:297
bool HasLayoutData() const
determines whether we currently have layout data
Definition: ctrl.cxx:90
virtual void Resize() override
Definition: combobox.cxx:562
long Y() const
ComboBoxBounds calcComboBoxDropDownComponentBounds(const Size &rOutSize, const Size &rBorderOutSize) const
Definition: combobox.cxx:1445
virtual void DataChanged(const DataChangedEvent &rDCEvt)
Definition: event.cxx:35
#define COMBOBOX_APPEND
Definition: combobox.hxx:27
long CalcWindowSizePixel(sal_uInt16 nLines) const
Definition: combobox.cxx:993
virtual void Modify() override
Definition: combobox.cxx:807
void SetLayoutDataParent(const Control *pParent) const
Definition: ctrl.cxx:324
#define KEY_UP
Definition: keycodes.hxx:111
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: ctrl.cxx:225
bool IsMod2() const
Definition: keycod.hxx:62
void setHeight(long nHeight)