Bump version to 5.0-14
[LibreOffice.git] / svtools / source / brwbox / ebbcontrols.cxx
bloba23e325f1bcbceaa2099e843fa03fe03cf314972
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svtools/editbrowsebox.hxx>
21 #include <vcl/decoview.hxx>
22 #include <svtools/fmtfield.hxx>
23 #include <vcl/xtextedt.hxx>
25 #include <algorithm>
28 namespace svt
32 TYPEINIT0(CellController);
33 TYPEINIT1(EditCellController, CellController);
34 TYPEINIT1(SpinCellController, CellController);
35 TYPEINIT1(CheckBoxCellController, CellController);
36 TYPEINIT1(ComboBoxCellController, CellController);
37 TYPEINIT1(ListBoxCellController, CellController);
39 TYPEINIT1( FormattedFieldCellController, EditCellController );
42 //= ComboBoxControl
44 ComboBoxControl::ComboBoxControl(vcl::Window* pParent, WinBits nWinStyle)
45 :ComboBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
47 EnableAutoSize(false);
48 EnableAutocomplete(true);
49 SetDropDownLineCount(5);
53 bool ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
55 if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT && !IsInDropDown())
57 const KeyEvent *pEvt = rNEvt.GetKeyEvent();
58 const vcl::KeyCode rKey = pEvt->GetKeyCode();
60 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
61 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
63 // select next resp. previous entry
64 sal_Int32 nPos = GetEntryPos(GetText());
65 int nDir = (rKey.GetCode() == KEY_DOWN ? 1 : -1);
66 if (!((nPos == 0 && nDir == -1) || (nPos >= GetEntryCount() && nDir == 1)))
68 nPos += nDir;
69 SetText(GetEntry(nPos));
71 return true;
74 return ComboBox::PreNotify(rNEvt);
77 //= ComboBoxCellController
78 ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
79 :CellController(pWin)
84 bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
86 ComboBoxControl& rBox = GetComboBox();
87 switch (rEvt.GetKeyCode().GetCode())
89 case KEY_END:
90 case KEY_RIGHT:
92 Selection aSel = rBox.GetSelection();
93 return !aSel && aSel.Max() == rBox.GetText().getLength();
95 case KEY_HOME:
96 case KEY_LEFT:
98 Selection aSel = rBox.GetSelection();
99 return !aSel && aSel.Min() == 0;
101 case KEY_UP:
102 case KEY_DOWN:
103 if (rBox.IsInDropDown())
104 return false;
105 if (!rEvt.GetKeyCode().IsShift() &&
106 rEvt.GetKeyCode().IsMod1())
107 return false;
108 // drop down the list box
109 else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
110 return false;
111 // fall-through
112 case KEY_PAGEUP:
113 case KEY_PAGEDOWN:
114 case KEY_RETURN:
115 if (rBox.IsInDropDown())
116 return false;
117 default:
118 return true;
123 bool ComboBoxCellController::IsModified() const
125 return GetComboBox().IsValueChangedFromSaved();
128 void ComboBoxCellController::ClearModified()
130 GetComboBox().SaveValue();
133 void ComboBoxCellController::SetModifyHdl(const Link<>& rLink)
135 GetComboBox().SetModifyHdl(rLink);
138 //= ListBoxControl
139 ListBoxControl::ListBoxControl(vcl::Window* pParent, WinBits nWinStyle)
140 :ListBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
142 EnableAutoSize(false);
143 EnableMultiSelection(false);
144 SetDropDownLineCount(20);
147 bool ListBoxControl::PreNotify( NotifyEvent& rNEvt )
149 if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT && !IsInDropDown())
151 const KeyEvent *pEvt = rNEvt.GetKeyEvent();
152 const vcl::KeyCode rKey = pEvt->GetKeyCode();
154 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
155 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
157 // select next resp. previous entry
158 sal_Int32 nPos = GetSelectEntryPos();
159 int nDir = (rKey.GetCode() == KEY_DOWN ? 1 : -1);
160 if (!((nPos == 0 && nDir == -1) || (nPos >= GetEntryCount() && nDir == 1)))
162 nPos += nDir;
163 SelectEntryPos(nPos);
165 Select(); // for calling Modify
166 return true;
168 else if (GetParent()->PreNotify(rNEvt))
169 return true;
171 return ListBox::PreNotify(rNEvt);
174 //= ListBoxCellController
175 ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
176 :CellController(pWin)
181 bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
183 const ListBoxControl& rBox = GetListBox();
184 switch (rEvt.GetKeyCode().GetCode())
186 case KEY_UP:
187 case KEY_DOWN:
188 if (!rEvt.GetKeyCode().IsShift() &&
189 rEvt.GetKeyCode().IsMod1())
190 return false;
191 // drop down the list box
192 else
193 if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
194 return false;
195 // fall-through
196 case KEY_PAGEUP:
197 case KEY_PAGEDOWN:
198 if (rBox.IsTravelSelect())
199 return false;
200 default:
201 return true;
206 bool ListBoxCellController::IsModified() const
208 return GetListBox().IsValueChangedFromSaved();
212 void ListBoxCellController::ClearModified()
214 GetListBox().SaveValue();
218 void ListBoxCellController::SetModifyHdl(const Link<>& rLink)
220 GetListBox().SetSelectHdl(rLink);
224 //= CheckBoxControl
227 CheckBoxControl::CheckBoxControl(vcl::Window* pParent, WinBits nWinStyle)
228 :Control(pParent, nWinStyle)
230 const Wallpaper& rParentBackground = pParent->GetBackground();
231 if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() )
232 SetBackground( rParentBackground );
233 else
235 SetPaintTransparent( true );
236 SetBackground();
239 EnableChildTransparentMode();
241 pBox = VclPtr<TriStateBox>::Create(this,WB_CENTER|WB_VCENTER);
242 pBox->SetLegacyNoTextAlign( true );
243 pBox->EnableChildTransparentMode();
244 pBox->SetPaintTransparent( true );
245 pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) );
246 pBox->Show();
250 CheckBoxControl::~CheckBoxControl()
252 disposeOnce();
255 void CheckBoxControl::dispose()
257 pBox.disposeAndClear();
258 Control::dispose();
262 IMPL_LINK_NOARG(CheckBoxControl, OnClick)
264 m_aClickLink.Call(pBox);
265 return m_aModifyLink.Call(pBox);
269 void CheckBoxControl::Resize()
271 Control::Resize();
272 pBox->SetPosSizePixel(Point(0,0),GetSizePixel());
276 void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent )
278 if ( _rEvent.GetType() == DataChangedEventType::SETTINGS )
279 pBox->SetSettings( GetSettings() );
283 void CheckBoxControl::StateChanged( StateChangedType nStateChange )
285 Control::StateChanged(nStateChange);
286 if ( nStateChange == StateChangedType::Zoom )
287 pBox->SetZoom(GetZoom());
291 void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
293 pBox->Draw(pDev,rPos,rSize,nFlags);
297 void CheckBoxControl::GetFocus()
299 pBox->GrabFocus();
303 void CheckBoxControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rClientRect)
305 Control::Paint(rRenderContext, rClientRect);
306 if (HasFocus())
307 ShowFocus(aFocusRect);
311 bool CheckBoxControl::PreNotify(NotifyEvent& rEvt)
313 switch (rEvt.GetType())
315 case MouseNotifyEvent::GETFOCUS:
316 ShowFocus(aFocusRect);
317 break;
318 case MouseNotifyEvent::LOSEFOCUS:
319 HideFocus();
320 break;
321 default:
322 break;
324 return Control::PreNotify(rEvt);
328 //= CheckBoxCellController
331 bool CheckBoxCellController::WantMouseEvent() const
333 return true;
337 CheckBox& CheckBoxCellController::GetCheckBox() const
339 return static_cast<CheckBoxControl &>(GetWindow()).GetBox();
343 bool CheckBoxCellController::IsModified() const
345 return GetCheckBox().IsValueChangedFromSaved();
349 void CheckBoxCellController::ClearModified()
351 GetCheckBox().SaveValue();
355 void CheckBoxCellController::SetModifyHdl(const Link<>& rLink)
357 static_cast<CheckBoxControl &>(GetWindow()).SetModifyHdl(rLink);
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 )
387 EditCellController::EditCellController( IEditImplementation* _pImplementation )
388 :CellController( &_pImplementation->GetControl() )
389 ,m_pEditImplementation( _pImplementation )
390 ,m_bOwnImplementation( false )
395 EditCellController::~EditCellController( )
397 if ( m_bOwnImplementation )
398 DELETEZ( m_pEditImplementation );
402 void EditCellController::SetModified()
404 m_pEditImplementation->SetModified();
408 void EditCellController::ClearModified()
410 m_pEditImplementation->ClearModified();
414 bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const
416 bool bResult;
417 switch (rEvt.GetKeyCode().GetCode())
419 case KEY_END:
420 case KEY_RIGHT:
422 Selection aSel = m_pEditImplementation->GetSelection();
423 bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).getLength();
424 } break;
425 case KEY_HOME:
426 case KEY_LEFT:
428 Selection aSel = m_pEditImplementation->GetSelection();
429 bResult = !aSel && aSel.Min() == 0;
430 } break;
431 default:
432 bResult = true;
434 return bResult;
438 bool EditCellController::IsModified() const
440 return m_pEditImplementation->IsModified();
444 void EditCellController::SetModifyHdl(const Link<>& rLink)
446 m_pEditImplementation->SetModifyHdl(rLink);
450 //= SpinCellController
453 SpinCellController::SpinCellController(SpinField* pWin)
454 :CellController(pWin)
459 void SpinCellController::SetModified()
461 GetSpinWindow().SetModifyFlag();
465 void SpinCellController::ClearModified()
467 GetSpinWindow().ClearModifyFlag();
471 bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const
473 bool bResult;
474 switch (rEvt.GetKeyCode().GetCode())
476 case KEY_END:
477 case KEY_RIGHT:
479 Selection aSel = GetSpinWindow().GetSelection();
480 bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().getLength();
481 } break;
482 case KEY_HOME:
483 case KEY_LEFT:
485 Selection aSel = GetSpinWindow().GetSelection();
486 bResult = !aSel && aSel.Min() == 0;
487 } break;
488 default:
489 bResult = true;
491 return bResult;
495 bool SpinCellController::IsModified() const
497 return GetSpinWindow().IsModified();
501 void SpinCellController::SetModifyHdl(const Link<>& rLink)
503 GetSpinWindow().SetModifyHdl(rLink);
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
601 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */