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