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