bump product version to 6.3.0.0.beta1
[LibreOffice.git] / svtools / source / brwbox / ebbcontrols.cxx
blob5c834f768bc7e49a514e5e3fe7fecb52ec9317ba
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <svtools/editbrowsebox.hxx>
20 #include <vcl/decoview.hxx>
21 #include <vcl/fmtfield.hxx>
22 #include <vcl/xtextedt.hxx>
23 #include <vcl/textview.hxx>
25 #include <algorithm>
28 namespace svt
32 //= ComboBoxControl
34 ComboBoxControl::ComboBoxControl(vcl::Window* pParent)
35 :ComboBox(pParent, WB_DROPDOWN|WB_NOBORDER)
37 EnableAutoSize(false);
38 EnableAutocomplete(true);
39 SetDropDownLineCount(5);
43 bool ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
45 if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT && !IsInDropDown())
47 const KeyEvent *pEvt = rNEvt.GetKeyEvent();
48 const vcl::KeyCode rKey = pEvt->GetKeyCode();
50 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
51 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
53 // select next resp. previous entry
54 sal_Int32 nPos = GetEntryPos(GetText());
55 int nDir = (rKey.GetCode() == KEY_DOWN ? 1 : -1);
56 if (!((nPos == 0 && nDir == -1) || (nPos >= GetEntryCount() && nDir == 1)))
58 nPos += nDir;
59 SetText(GetEntry(nPos));
61 return true;
64 return ComboBox::PreNotify(rNEvt);
67 //= ComboBoxCellController
68 ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
69 :CellController(pWin)
71 GetComboBox().SetModifyHdl( LINK(this, ComboBoxCellController, ModifyHdl) );
74 IMPL_LINK_NOARG(ComboBoxCellController, ModifyHdl, Edit&, void)
76 callModifyHdl();
80 bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
82 ComboBoxControl& rBox = GetComboBox();
83 switch (rEvt.GetKeyCode().GetCode())
85 case KEY_END:
86 case KEY_RIGHT:
88 Selection aSel = rBox.GetSelection();
89 return !aSel && aSel.Max() == rBox.GetText().getLength();
91 case KEY_HOME:
92 case KEY_LEFT:
94 Selection aSel = rBox.GetSelection();
95 return !aSel && aSel.Min() == 0;
97 case KEY_UP:
98 case KEY_DOWN:
99 if (rBox.IsInDropDown())
100 return false;
101 if (!rEvt.GetKeyCode().IsShift() &&
102 rEvt.GetKeyCode().IsMod1())
103 return false;
104 // drop down the list box
105 else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
106 return false;
107 [[fallthrough]];
108 case KEY_PAGEUP:
109 case KEY_PAGEDOWN:
110 case KEY_RETURN:
111 if (rBox.IsInDropDown())
112 return false;
113 [[fallthrough]];
114 default:
115 return true;
120 bool ComboBoxCellController::IsModified() const
122 return GetComboBox().IsValueChangedFromSaved();
125 void ComboBoxCellController::ClearModified()
127 GetComboBox().SaveValue();
130 //= ListBoxControl
131 ListBoxControl::ListBoxControl(vcl::Window* pParent)
132 :ListBox(pParent, WB_DROPDOWN|WB_NOBORDER)
134 EnableAutoSize(false);
135 EnableMultiSelection(false);
136 SetDropDownLineCount(20);
139 bool ListBoxControl::PreNotify( NotifyEvent& rNEvt )
141 if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT && !IsInDropDown())
143 const KeyEvent *pEvt = rNEvt.GetKeyEvent();
144 const vcl::KeyCode rKey = pEvt->GetKeyCode();
146 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
147 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
149 // select next resp. previous entry
150 sal_Int32 nPos = GetSelectedEntryPos();
151 int nDir = (rKey.GetCode() == KEY_DOWN ? 1 : -1);
152 if (!((nPos == 0 && nDir == -1) || (nPos >= GetEntryCount() && nDir == 1)))
154 nPos += nDir;
155 SelectEntryPos(nPos);
157 Select(); // for calling Modify
158 return true;
160 else if (GetParent()->PreNotify(rNEvt))
161 return true;
163 return ListBox::PreNotify(rNEvt);
166 //= ListBoxCellController
167 ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
168 :CellController(pWin)
170 GetListBox().SetSelectHdl(LINK(this, ListBoxCellController, ListBoxSelectHdl));
174 bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
176 const ListBoxControl& rBox = GetListBox();
177 switch (rEvt.GetKeyCode().GetCode())
179 case KEY_UP:
180 case KEY_DOWN:
181 if (!rEvt.GetKeyCode().IsShift() &&
182 rEvt.GetKeyCode().IsMod1())
183 return false;
184 // drop down the list box
185 else
186 if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
187 return false;
188 [[fallthrough]];
189 case KEY_PAGEUP:
190 case KEY_PAGEDOWN:
191 if (rBox.IsTravelSelect())
192 return false;
193 [[fallthrough]];
194 default:
195 return true;
200 bool ListBoxCellController::IsModified() const
202 return GetListBox().IsValueChangedFromSaved();
206 void ListBoxCellController::ClearModified()
208 GetListBox().SaveValue();
212 IMPL_LINK_NOARG(ListBoxCellController, ListBoxSelectHdl, ListBox&, void)
214 callModifyHdl();
218 //= CheckBoxControl
221 CheckBoxControl::CheckBoxControl(vcl::Window* pParent)
222 :Control(pParent, 0)
224 const Wallpaper& rParentBackground = pParent->GetBackground();
225 if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() )
226 SetBackground( rParentBackground );
227 else
229 SetPaintTransparent( true );
230 SetBackground();
233 EnableChildTransparentMode();
235 pBox = VclPtr<TriStateBox>::Create(this,WB_CENTER|WB_VCENTER);
236 pBox->SetLegacyNoTextAlign( true );
237 pBox->EnableChildTransparentMode();
238 pBox->SetPaintTransparent( true );
239 pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) );
240 pBox->Show();
244 CheckBoxControl::~CheckBoxControl()
246 disposeOnce();
249 void CheckBoxControl::dispose()
251 pBox.disposeAndClear();
252 Control::dispose();
256 IMPL_LINK_NOARG(CheckBoxControl, OnClick, Button*, void)
258 m_aClickLink.Call(pBox);
259 m_aModifyLink.Call(nullptr);
263 void CheckBoxControl::Resize()
265 Control::Resize();
266 pBox->SetPosSizePixel(Point(0,0),GetSizePixel());
270 void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent )
272 if ( _rEvent.GetType() == DataChangedEventType::SETTINGS )
273 pBox->SetSettings( GetSettings() );
277 void CheckBoxControl::StateChanged( StateChangedType nStateChange )
279 Control::StateChanged(nStateChange);
280 if ( nStateChange == StateChangedType::Zoom )
281 pBox->SetZoom(GetZoom());
285 void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, DrawFlags nFlags )
287 pBox->Draw(pDev,rPos,rSize,nFlags);
291 void CheckBoxControl::GetFocus()
293 if (pBox)
294 pBox->GrabFocus();
298 void CheckBoxControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rClientRect)
300 Control::Paint(rRenderContext, rClientRect);
301 if (HasFocus())
302 ShowFocus(tools::Rectangle());
306 bool CheckBoxControl::PreNotify(NotifyEvent& rEvt)
308 switch (rEvt.GetType())
310 case MouseNotifyEvent::GETFOCUS:
311 ShowFocus(tools::Rectangle());
312 break;
313 case MouseNotifyEvent::LOSEFOCUS:
314 HideFocus();
315 break;
316 default:
317 break;
319 return Control::PreNotify(rEvt);
323 //= CheckBoxCellController
326 CheckBoxCellController::CheckBoxCellController(CheckBoxControl* pWin)
327 : CellController(pWin)
329 static_cast<CheckBoxControl &>(GetWindow()).SetModifyHdl( LINK(this, CheckBoxCellController, ModifyHdl) );
332 bool CheckBoxCellController::WantMouseEvent() const
334 return true;
338 CheckBox& CheckBoxCellController::GetCheckBox() const
340 return static_cast<CheckBoxControl &>(GetWindow()).GetBox();
344 bool CheckBoxCellController::IsModified() const
346 return GetCheckBox().IsValueChangedFromSaved();
350 void CheckBoxCellController::ClearModified()
352 GetCheckBox().SaveValue();
356 IMPL_LINK_NOARG(CheckBoxCellController, ModifyHdl, LinkParamNone*, void)
358 callModifyHdl();
361 //= MultiLineEditImplementation
364 OUString MultiLineEditImplementation::GetText( LineEnd aSeparator ) const
366 return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetText( aSeparator );
370 OUString MultiLineEditImplementation::GetSelected( LineEnd aSeparator ) const
372 return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetSelected( aSeparator );
376 //= EditCellController
379 EditCellController::EditCellController( Edit* _pEdit )
380 :CellController( _pEdit )
381 ,m_pEditImplementation( new EditImplementation( *_pEdit ) )
382 ,m_bOwnImplementation( true )
384 m_pEditImplementation->SetModifyHdl( LINK(this, EditCellController, ModifyHdl) );
388 EditCellController::EditCellController( IEditImplementation* _pImplementation )
389 :CellController( &_pImplementation->GetControl() )
390 ,m_pEditImplementation( _pImplementation )
391 ,m_bOwnImplementation( false )
393 m_pEditImplementation->SetModifyHdl( LINK(this, EditCellController, ModifyHdl) );
397 EditCellController::~EditCellController( )
399 if ( m_bOwnImplementation )
400 DELETEZ( m_pEditImplementation );
404 void EditCellController::SetModified()
406 m_pEditImplementation->SetModified();
410 void EditCellController::ClearModified()
412 m_pEditImplementation->ClearModified();
416 bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const
418 bool bResult;
419 switch (rEvt.GetKeyCode().GetCode())
421 case KEY_END:
422 case KEY_RIGHT:
424 Selection aSel = m_pEditImplementation->GetSelection();
425 bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).getLength();
426 } break;
427 case KEY_HOME:
428 case KEY_LEFT:
430 Selection aSel = m_pEditImplementation->GetSelection();
431 bResult = !aSel && aSel.Min() == 0;
432 } break;
433 default:
434 bResult = true;
436 return bResult;
440 bool EditCellController::IsModified() const
442 return m_pEditImplementation->IsModified();
446 IMPL_LINK_NOARG(EditCellController, ModifyHdl, Edit&, void)
448 callModifyHdl();
451 //= SpinCellController
454 SpinCellController::SpinCellController(SpinField* pWin)
455 :CellController(pWin)
457 GetSpinWindow().SetModifyHdl( LINK(this, SpinCellController, ModifyHdl) );
461 void SpinCellController::SetModified()
463 GetSpinWindow().SetModifyFlag();
467 void SpinCellController::ClearModified()
469 GetSpinWindow().ClearModifyFlag();
473 bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const
475 bool bResult;
476 switch (rEvt.GetKeyCode().GetCode())
478 case KEY_END:
479 case KEY_RIGHT:
481 Selection aSel = GetSpinWindow().GetSelection();
482 bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().getLength();
483 } break;
484 case KEY_HOME:
485 case KEY_LEFT:
487 Selection aSel = GetSpinWindow().GetSelection();
488 bResult = !aSel && aSel.Min() == 0;
489 } break;
490 default:
491 bResult = true;
493 return bResult;
497 bool SpinCellController::IsModified() const
499 return GetSpinWindow().IsModified();
502 IMPL_LINK_NOARG(SpinCellController, ModifyHdl, Edit&, void)
504 callModifyHdl();
507 //= FormattedFieldCellController
510 FormattedFieldCellController::FormattedFieldCellController( FormattedField* _pFormatted )
511 :EditCellController( _pFormatted )
516 void FormattedFieldCellController::CommitModifications()
518 static_cast< FormattedField& >( GetWindow() ).Commit();
522 //= MultiLineTextCell
525 void MultiLineTextCell::Modify()
527 GetTextEngine()->SetModified( true );
528 MultiLineEdit::Modify();
532 bool MultiLineTextCell::dispatchKeyEvent( const KeyEvent& _rEvent )
534 Selection aOldSelection( GetSelection() );
536 bool bWasModified = IsModified();
537 ClearModifyFlag( );
539 bool bHandled = GetTextView()->KeyInput( _rEvent );
541 bool bIsModified = IsModified();
542 if ( bWasModified && !bIsModified )
543 // not sure whether this can really happen
544 SetModifyFlag();
546 if ( bHandled ) // the view claimed it handled the key input
548 // unfortunately, KeyInput also returns <TRUE/> (means "I handled this key input")
549 // when nothing really changed. Let's care for this.
550 Selection aNewSelection( GetSelection() );
551 if ( aNewSelection != aOldSelection // selection changed
552 || bIsModified // or some other modification
554 return true;
556 return false;
560 bool MultiLineTextCell::PreNotify( NotifyEvent& rNEvt )
562 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
564 if ( IsWindowOrChild( rNEvt.GetWindow() ) )
566 // give the text view a chance to handle the keys
567 // this is necessary since a lot of keys which are normally handled
568 // by this view (in KeyInput) are intercepted by the EditBrowseBox,
569 // which uses them for other reasons. An example is the KeyUp key,
570 // which is used by both the text view and the edit browse box
572 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
573 const vcl::KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
574 sal_uInt16 nCode = rKeyCode.GetCode();
576 if ( ( nCode == KEY_RETURN ) && ( rKeyCode.GetModifier() == KEY_MOD1 ) )
578 KeyEvent aEvent( pKeyEvent->GetCharCode(),
579 vcl::KeyCode( KEY_RETURN ),
580 pKeyEvent->GetRepeat()
582 if ( dispatchKeyEvent( aEvent ) )
583 return true;
586 if ( ( nCode != KEY_TAB ) && ( nCode != KEY_RETURN ) ) // everything but tab and enter
588 if ( dispatchKeyEvent( *pKeyEvent ) )
589 return true;
593 return MultiLineEdit::PreNotify( rNEvt );
597 } // namespace svt
600 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */