merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / brwbox / ebbcontrols.cxx
blobccc85ed7b757fd43d7051de40318091326af69cf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ebbcontrols.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <svtools/editbrowsebox.hxx>
34 #include <vcl/decoview.hxx>
35 #include <svtools/fmtfield.hxx>
36 #include <svtools/xtextedt.hxx>
38 #include <algorithm>
40 // .......................................................................
41 namespace svt
43 // .......................................................................
45 TYPEINIT0(CellController);
46 TYPEINIT1(EditCellController, CellController);
47 TYPEINIT1(SpinCellController, CellController);
48 TYPEINIT1(CheckBoxCellController, CellController);
49 TYPEINIT1(ComboBoxCellController, CellController);
50 TYPEINIT1(ListBoxCellController, CellController);
52 TYPEINIT1( FormattedFieldCellController, EditCellController );
54 //==================================================================
55 //= ComboBoxControl
56 //==================================================================
57 ComboBoxControl::ComboBoxControl(Window* pParent, WinBits nWinStyle)
58 :ComboBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
60 EnableAutoSize(sal_False);
61 EnableAutocomplete(sal_True);
62 SetDropDownLineCount(5);
65 //------------------------------------------------------------------
66 long ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
68 switch (rNEvt.GetType())
70 case EVENT_KEYINPUT:
71 if (!IsInDropDown())
73 const KeyEvent *pEvt = rNEvt.GetKeyEvent();
74 const KeyCode rKey = pEvt->GetKeyCode();
76 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
77 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
79 // select next resp. previous entry
80 int nPos = GetEntryPos(GetText());
81 nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
82 if (nPos < 0)
83 nPos = 0;
84 if (nPos >= GetEntryCount())
85 nPos = GetEntryCount() - 1;
86 SetText(GetEntry(sal::static_int_cast< USHORT >(nPos)));
87 return 1;
90 break;
92 return ComboBox::PreNotify(rNEvt);
95 //==================================================================
96 //= ComboBoxCellController
97 //==================================================================
98 //------------------------------------------------------------------
99 ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
100 :CellController(pWin)
104 //------------------------------------------------------------------
105 sal_Bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
107 ComboBoxControl& rBox = GetComboBox();
108 switch (rEvt.GetKeyCode().GetCode())
110 case KEY_END:
111 case KEY_RIGHT:
113 Selection aSel = rBox.GetSelection();
114 return !aSel && aSel.Max() == rBox.GetText().Len();
116 case KEY_HOME:
117 case KEY_LEFT:
119 Selection aSel = rBox.GetSelection();
120 return !aSel && aSel.Min() == 0;
122 case KEY_UP:
123 case KEY_DOWN:
124 if (rBox.IsInDropDown())
125 return sal_False;
126 if (!rEvt.GetKeyCode().IsShift() &&
127 rEvt.GetKeyCode().IsMod1())
128 return sal_False;
129 // drop down the list box
130 else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
131 return sal_False;
132 case KEY_PAGEUP:
133 case KEY_PAGEDOWN:
134 case KEY_RETURN:
135 if (rBox.IsInDropDown())
136 return sal_False;
137 default:
138 return sal_True;
142 //------------------------------------------------------------------
143 sal_Bool ComboBoxCellController::IsModified() const
145 return GetComboBox().GetSavedValue() != GetComboBox().GetText();
148 //------------------------------------------------------------------
149 void ComboBoxCellController::ClearModified()
151 GetComboBox().SaveValue();
154 //------------------------------------------------------------------
155 void ComboBoxCellController::SetModifyHdl(const Link& rLink)
157 GetComboBox().SetModifyHdl(rLink);
160 //==================================================================
161 //= ListBoxControl
162 //==================================================================
163 //------------------------------------------------------------------
164 ListBoxControl::ListBoxControl(Window* pParent, WinBits nWinStyle)
165 :ListBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
167 EnableAutoSize(sal_False);
168 EnableMultiSelection(sal_False);
169 SetDropDownLineCount(20);
172 //------------------------------------------------------------------
173 long ListBoxControl::PreNotify( NotifyEvent& rNEvt )
175 switch (rNEvt.GetType())
177 case EVENT_KEYINPUT:
178 if (!IsInDropDown())
180 const KeyEvent *pEvt = rNEvt.GetKeyEvent();
181 const KeyCode rKey = pEvt->GetKeyCode();
183 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
184 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
186 // select next resp. previous entry
187 int nPos = GetSelectEntryPos();
188 nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
189 if (nPos < 0)
190 nPos = 0;
191 if (nPos >= GetEntryCount())
192 nPos = GetEntryCount() - 1;
193 SelectEntryPos(sal::static_int_cast< USHORT >(nPos));
194 Select(); // for calling Modify
195 return 1;
197 else if (GetParent()->PreNotify(rNEvt))
198 return 1;
200 break;
202 return ListBox::PreNotify(rNEvt);
205 //==================================================================
206 //= ListBoxCellController
207 //==================================================================
208 //------------------------------------------------------------------
209 ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
210 :CellController(pWin)
214 //------------------------------------------------------------------
215 sal_Bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
217 ListBoxControl& rBox = GetListBox();
218 switch (rEvt.GetKeyCode().GetCode())
220 case KEY_UP:
221 case KEY_DOWN:
222 if (!rEvt.GetKeyCode().IsShift() &&
223 rEvt.GetKeyCode().IsMod1())
224 return sal_False;
225 // drop down the list box
226 else
227 if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
228 return sal_False;
229 case KEY_PAGEUP:
230 case KEY_PAGEDOWN:
231 if (rBox.IsTravelSelect())
232 return sal_False;
233 default:
234 return sal_True;
238 //------------------------------------------------------------------
239 sal_Bool ListBoxCellController::IsModified() const
241 return GetListBox().GetSelectEntryPos() != GetListBox().GetSavedValue();
244 //------------------------------------------------------------------
245 void ListBoxCellController::ClearModified()
247 GetListBox().SaveValue();
250 //------------------------------------------------------------------
251 void ListBoxCellController::SetModifyHdl(const Link& rLink)
253 GetListBox().SetSelectHdl(rLink);
256 //==================================================================
257 //= CheckBoxControl
258 //==================================================================
259 //------------------------------------------------------------------
260 CheckBoxControl::CheckBoxControl(Window* pParent, WinBits nWinStyle)
261 :Control(pParent, nWinStyle)
263 const Wallpaper& rParentBackground = pParent->GetBackground();
264 if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() )
265 SetBackground( rParentBackground );
266 else
268 SetPaintTransparent( sal_True );
269 SetBackground();
272 EnableChildTransparentMode();
274 pBox = new TriStateBox(this,WB_CENTER|WB_VCENTER);
275 pBox->EnableChildTransparentMode();
276 pBox->SetPaintTransparent( sal_True );
277 pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) );
278 pBox->Show();
281 //------------------------------------------------------------------
282 CheckBoxControl::~CheckBoxControl()
284 delete pBox;
287 //------------------------------------------------------------------
288 IMPL_LINK( CheckBoxControl, OnClick, void*, EMPTYARG )
290 m_aClickLink.Call(pBox);
291 return m_aModifyLink.Call(pBox);
294 //------------------------------------------------------------------
295 void CheckBoxControl::Resize()
297 Control::Resize();
298 pBox->SetPosSizePixel(Point(0,0),GetSizePixel());
301 //------------------------------------------------------------------------------
302 void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent )
304 if ( _rEvent.GetType() == DATACHANGED_SETTINGS )
305 pBox->SetSettings( GetSettings() );
308 //------------------------------------------------------------------------------
309 void CheckBoxControl::StateChanged( StateChangedType nStateChange )
311 Control::StateChanged(nStateChange);
312 if ( nStateChange == STATE_CHANGE_ZOOM )
313 pBox->SetZoom(GetZoom());
316 //------------------------------------------------------------------
317 void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
319 pBox->Draw(pDev,rPos,rSize,nFlags);
322 //------------------------------------------------------------------
323 void CheckBoxControl::GetFocus()
325 pBox->GrabFocus();
328 //------------------------------------------------------------------
329 void CheckBoxControl::Paint(const Rectangle& rClientRect)
331 Control::Paint(rClientRect);
332 if (HasFocus())
333 ShowFocus(aFocusRect);
336 //------------------------------------------------------------------
337 long CheckBoxControl::PreNotify(NotifyEvent& rEvt)
339 switch (rEvt.GetType())
341 case EVENT_GETFOCUS:
342 ShowFocus(aFocusRect);
343 break;
344 case EVENT_LOSEFOCUS:
345 HideFocus();
347 return Control::PreNotify(rEvt);
350 //==================================================================
351 //= CheckBoxCellController
352 //==================================================================
353 //------------------------------------------------------------------
354 sal_Bool CheckBoxCellController::WantMouseEvent() const
356 return sal_True;
359 //------------------------------------------------------------------
360 CheckBox& CheckBoxCellController::GetCheckBox() const
362 return ((CheckBoxControl &)GetWindow()).GetBox();
365 //------------------------------------------------------------------
366 sal_Bool CheckBoxCellController::IsModified() const
368 return GetCheckBox().GetSavedValue() != GetCheckBox().GetState();
371 //------------------------------------------------------------------
372 void CheckBoxCellController::ClearModified()
374 GetCheckBox().SaveValue();
377 //------------------------------------------------------------------
378 void CheckBoxCellController::SetModifyHdl(const Link& rLink)
380 ((CheckBoxControl &)GetWindow()).SetModifyHdl(rLink);
383 //==================================================================
384 //= MultiLineEditImplementation
385 //==================================================================
386 //------------------------------------------------------------------
387 String MultiLineEditImplementation::GetText( LineEnd aSeparator ) const
389 return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetText( aSeparator );
392 //------------------------------------------------------------------
393 String MultiLineEditImplementation::GetSelected( LineEnd aSeparator ) const
395 return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetSelected( aSeparator );
398 //==================================================================
399 //= EditCellController
400 //==================================================================
401 //------------------------------------------------------------------
402 EditCellController::EditCellController( Edit* _pEdit )
403 :CellController( _pEdit )
404 ,m_pEditImplementation( new EditImplementation( *_pEdit ) )
405 ,m_bOwnImplementation( TRUE )
409 //------------------------------------------------------------------
410 EditCellController::EditCellController( MultiLineTextCell* _pEdit )
411 :CellController( _pEdit )
412 ,m_pEditImplementation( new MultiLineEditImplementation( *_pEdit ) )
413 ,m_bOwnImplementation( TRUE )
417 //------------------------------------------------------------------
418 EditCellController::EditCellController( IEditImplementation* _pImplementation )
419 :CellController( &_pImplementation->GetControl() )
420 ,m_pEditImplementation( _pImplementation )
421 ,m_bOwnImplementation( FALSE )
425 //-----------------------------------------------------------------------------
426 EditCellController::~EditCellController( )
428 if ( m_bOwnImplementation )
429 DELETEZ( m_pEditImplementation );
432 //-----------------------------------------------------------------------------
433 void EditCellController::SetModified()
435 m_pEditImplementation->SetModified();
438 //-----------------------------------------------------------------------------
439 void EditCellController::ClearModified()
441 m_pEditImplementation->ClearModified();
444 //------------------------------------------------------------------
445 sal_Bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const
447 sal_Bool bResult;
448 switch (rEvt.GetKeyCode().GetCode())
450 case KEY_END:
451 case KEY_RIGHT:
453 Selection aSel = m_pEditImplementation->GetSelection();
454 bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).Len();
455 } break;
456 case KEY_HOME:
457 case KEY_LEFT:
459 Selection aSel = m_pEditImplementation->GetSelection();
460 bResult = !aSel && aSel.Min() == 0;
461 } break;
462 default:
463 bResult = sal_True;
465 return bResult;
468 //------------------------------------------------------------------
469 sal_Bool EditCellController::IsModified() const
471 return m_pEditImplementation->IsModified();
474 //------------------------------------------------------------------
475 void EditCellController::SetModifyHdl(const Link& rLink)
477 m_pEditImplementation->SetModifyHdl(rLink);
480 //==================================================================
481 //= SpinCellController
482 //==================================================================
483 //------------------------------------------------------------------
484 SpinCellController::SpinCellController(SpinField* pWin)
485 :CellController(pWin)
489 //-----------------------------------------------------------------------------
490 void SpinCellController::SetModified()
492 GetSpinWindow().SetModifyFlag();
495 //-----------------------------------------------------------------------------
496 void SpinCellController::ClearModified()
498 GetSpinWindow().ClearModifyFlag();
501 //------------------------------------------------------------------
502 sal_Bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const
504 sal_Bool bResult;
505 switch (rEvt.GetKeyCode().GetCode())
507 case KEY_END:
508 case KEY_RIGHT:
510 Selection aSel = GetSpinWindow().GetSelection();
511 bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().Len();
512 } break;
513 case KEY_HOME:
514 case KEY_LEFT:
516 Selection aSel = GetSpinWindow().GetSelection();
517 bResult = !aSel && aSel.Min() == 0;
518 } break;
519 default:
520 bResult = sal_True;
522 return bResult;
525 //------------------------------------------------------------------
526 sal_Bool SpinCellController::IsModified() const
528 return GetSpinWindow().IsModified();
531 //------------------------------------------------------------------
532 void SpinCellController::SetModifyHdl(const Link& rLink)
534 GetSpinWindow().SetModifyHdl(rLink);
537 //==================================================================
538 //= FormattedFieldCellController
539 //==================================================================
540 //------------------------------------------------------------------
541 FormattedFieldCellController::FormattedFieldCellController( FormattedField* _pFormatted )
542 :EditCellController( _pFormatted )
546 //------------------------------------------------------------------
547 void FormattedFieldCellController::CommitModifications()
549 static_cast< FormattedField& >( GetWindow() ).Commit();
552 //==================================================================
553 //= MultiLineTextCell
554 //==================================================================
555 //------------------------------------------------------------------
556 void MultiLineTextCell::Modify()
558 GetTextEngine()->SetModified( TRUE );
559 MultiLineEdit::Modify();
562 //------------------------------------------------------------------
563 BOOL MultiLineTextCell::dispatchKeyEvent( const KeyEvent& _rEvent )
565 Selection aOldSelection( GetSelection() );
567 BOOL bWasModified = IsModified();
568 ClearModifyFlag( );
570 BOOL bHandled = GetTextView()->KeyInput( _rEvent );
572 BOOL bIsModified = IsModified();
573 if ( bWasModified && !bIsModified )
574 // not sure whether this can really happen
575 SetModifyFlag();
577 if ( bHandled ) // the view claimed it handled the key input
579 // unfortunately, KeyInput also returns <TRUE/> (means "I handled this key input")
580 // when nothing really changed. Let's care for this.
581 Selection aNewSelection( GetSelection() );
582 if ( aNewSelection != aOldSelection // selection changed
583 || bIsModified // or some other modification
585 return TRUE;
587 return FALSE;
590 //------------------------------------------------------------------
591 long MultiLineTextCell::PreNotify( NotifyEvent& rNEvt )
593 if ( rNEvt.GetType() == EVENT_KEYINPUT )
595 if ( IsWindowOrChild( rNEvt.GetWindow() ) )
597 // give the text view a chance to handle the keys
598 // this is necessary since a lot of keys which are normally handled
599 // by this view (in KeyInput) are intercepted by the EditBrowseBox,
600 // which uses them for other reasons. An example is the KeyUp key,
601 // which is used by both the text view and the edit browse box
603 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
604 const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
605 USHORT nCode = rKeyCode.GetCode();
607 if ( ( nCode == KEY_RETURN ) && ( rKeyCode.GetModifier() == KEY_MOD1 ) )
609 KeyEvent aEvent( pKeyEvent->GetCharCode(),
610 KeyCode( KEY_RETURN ),
611 pKeyEvent->GetRepeat()
613 if ( dispatchKeyEvent( aEvent ) )
614 return 1;
617 if ( ( nCode != KEY_TAB ) && ( nCode != KEY_RETURN ) ) // everything but tab and enter
619 if ( dispatchKeyEvent( *pKeyEvent ) )
620 return 1;
624 return MultiLineEdit::PreNotify( rNEvt );
627 // .......................................................................
628 } // namespace svt
629 // .......................................................................