1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
);
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)))
69 SetText(GetEntry(nPos
));
74 return ComboBox::PreNotify(rNEvt
);
77 //= ComboBoxCellController
78 ComboBoxCellController::ComboBoxCellController(ComboBoxControl
* pWin
)
84 bool ComboBoxCellController::MoveAllowed(const KeyEvent
& rEvt
) const
86 ComboBoxControl
& rBox
= GetComboBox();
87 switch (rEvt
.GetKeyCode().GetCode())
92 Selection aSel
= rBox
.GetSelection();
93 return !aSel
&& aSel
.Max() == rBox
.GetText().getLength();
98 Selection aSel
= rBox
.GetSelection();
99 return !aSel
&& aSel
.Min() == 0;
103 if (rBox
.IsInDropDown())
105 if (!rEvt
.GetKeyCode().IsShift() &&
106 rEvt
.GetKeyCode().IsMod1())
108 // drop down the list box
109 else if (rEvt
.GetKeyCode().IsMod2() && rEvt
.GetKeyCode().GetCode() == KEY_DOWN
)
115 if (rBox
.IsInDropDown())
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
);
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)))
163 SelectEntryPos(nPos
);
165 Select(); // for calling Modify
168 else if (GetParent()->PreNotify(rNEvt
))
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())
188 if (!rEvt
.GetKeyCode().IsShift() &&
189 rEvt
.GetKeyCode().IsMod1())
191 // drop down the list box
193 if (rEvt
.GetKeyCode().IsMod2() && rEvt
.GetKeyCode().GetCode() == KEY_DOWN
)
198 if (rBox
.IsTravelSelect())
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
);
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
);
235 SetPaintTransparent( true );
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
) );
250 CheckBoxControl::~CheckBoxControl()
255 void CheckBoxControl::dispose()
257 pBox
.disposeAndClear();
262 IMPL_LINK_NOARG(CheckBoxControl
, OnClick
)
264 m_aClickLink
.Call(pBox
);
265 return m_aModifyLink
.Call(pBox
);
269 void CheckBoxControl::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()
303 void CheckBoxControl::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rClientRect
)
305 Control::Paint(rRenderContext
, rClientRect
);
307 ShowFocus(aFocusRect
);
311 bool CheckBoxControl::PreNotify(NotifyEvent
& rEvt
)
313 switch (rEvt
.GetType())
315 case MouseNotifyEvent::GETFOCUS
:
316 ShowFocus(aFocusRect
);
318 case MouseNotifyEvent::LOSEFOCUS
:
324 return Control::PreNotify(rEvt
);
328 //= CheckBoxCellController
331 bool CheckBoxCellController::WantMouseEvent() const
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
417 switch (rEvt
.GetKeyCode().GetCode())
422 Selection aSel
= m_pEditImplementation
->GetSelection();
423 bResult
= !aSel
&& aSel
.Max() == m_pEditImplementation
->GetText( LINEEND_LF
).getLength();
428 Selection aSel
= m_pEditImplementation
->GetSelection();
429 bResult
= !aSel
&& aSel
.Min() == 0;
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
474 switch (rEvt
.GetKeyCode().GetCode())
479 Selection aSel
= GetSpinWindow().GetSelection();
480 bResult
= !aSel
&& aSel
.Max() == GetSpinWindow().GetText().getLength();
485 Selection aSel
= GetSpinWindow().GetSelection();
486 bResult
= !aSel
&& aSel
.Min() == 0;
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();
539 bool bHandled
= GetTextView()->KeyInput( _rEvent
);
541 bool bIsModified
= IsModified();
542 if ( bWasModified
&& !bIsModified
)
543 // not sure whether this can really happen
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
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
) )
586 if ( ( nCode
!= KEY_TAB
) && ( nCode
!= KEY_RETURN
) ) // everything but tab and enter
588 if ( dispatchKeyEvent( *pKeyEvent
) )
593 return MultiLineEdit::PreNotify( rNEvt
);
601 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */