xref: /trunk/main/svtools/source/brwbox/ebbcontrols.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <svtools/editbrowsebox.hxx>
31 #include <vcl/decoview.hxx>
32 #include <svtools/fmtfield.hxx>
33 #include <svtools/xtextedt.hxx>
34 
35 #include <algorithm>
36 
37 // .......................................................................
38 namespace svt
39 {
40 // .......................................................................
41 
42     TYPEINIT0(CellController);
43     TYPEINIT1(EditCellController, CellController);
44     TYPEINIT1(SpinCellController, CellController);
45     TYPEINIT1(CheckBoxCellController, CellController);
46     TYPEINIT1(ComboBoxCellController, CellController);
47     TYPEINIT1(ListBoxCellController, CellController);
48 
49     TYPEINIT1( FormattedFieldCellController, EditCellController );
50 
51     //==================================================================
52     //= ComboBoxControl
53     //==================================================================
54     ComboBoxControl::ComboBoxControl(Window* pParent, WinBits nWinStyle)
55                    :ComboBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
56     {
57         EnableAutoSize(sal_False);
58         EnableAutocomplete(sal_True);
59         SetDropDownLineCount(5);
60     }
61 
62     //------------------------------------------------------------------
63     long ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
64     {
65         switch (rNEvt.GetType())
66         {
67             case EVENT_KEYINPUT:
68                 if (!IsInDropDown())
69                 {
70                     const KeyEvent *pEvt = rNEvt.GetKeyEvent();
71                     const KeyCode rKey = pEvt->GetKeyCode();
72 
73                     if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
74                         (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
75                     {
76                         // select next resp. previous entry
77                         int nPos = GetEntryPos(GetText());
78                         nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
79                         if (nPos < 0)
80                             nPos = 0;
81                         if (nPos >= GetEntryCount())
82                             nPos = GetEntryCount() - 1;
83                         SetText(GetEntry(sal::static_int_cast< sal_uInt16 >(nPos)));
84                         return 1;
85                     }
86                 }
87                 break;
88         }
89         return ComboBox::PreNotify(rNEvt);
90     }
91 
92     //==================================================================
93     //= ComboBoxCellController
94     //==================================================================
95     //------------------------------------------------------------------
96     ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
97                              :CellController(pWin)
98     {
99     }
100 
101     //------------------------------------------------------------------
102     sal_Bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
103     {
104         ComboBoxControl& rBox = GetComboBox();
105         switch (rEvt.GetKeyCode().GetCode())
106         {
107             case KEY_END:
108             case KEY_RIGHT:
109             {
110                 Selection aSel = rBox.GetSelection();
111                 return !aSel && aSel.Max() == rBox.GetText().Len();
112             }
113             case KEY_HOME:
114             case KEY_LEFT:
115             {
116                 Selection aSel = rBox.GetSelection();
117                 return !aSel && aSel.Min() == 0;
118             }
119             case KEY_UP:
120             case KEY_DOWN:
121                 if (rBox.IsInDropDown())
122                     return sal_False;
123                 if (!rEvt.GetKeyCode().IsShift() &&
124                      rEvt.GetKeyCode().IsMod1())
125                     return sal_False;
126                 // drop down the list box
127                 else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
128                     return sal_False;
129             case KEY_PAGEUP:
130             case KEY_PAGEDOWN:
131             case KEY_RETURN:
132                 if (rBox.IsInDropDown())
133                     return sal_False;
134             default:
135                 return sal_True;
136         }
137     }
138 
139     //------------------------------------------------------------------
140     sal_Bool ComboBoxCellController::IsModified() const
141     {
142         return GetComboBox().GetSavedValue() != GetComboBox().GetText();
143     }
144 
145     //------------------------------------------------------------------
146     void ComboBoxCellController::ClearModified()
147     {
148         GetComboBox().SaveValue();
149     }
150 
151     //------------------------------------------------------------------
152     void ComboBoxCellController::SetModifyHdl(const Link& rLink)
153     {
154         GetComboBox().SetModifyHdl(rLink);
155     }
156 
157     //==================================================================
158     //= ListBoxControl
159     //==================================================================
160     //------------------------------------------------------------------
161     ListBoxControl::ListBoxControl(Window* pParent, WinBits nWinStyle)
162                   :ListBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
163     {
164         EnableAutoSize(sal_False);
165         EnableMultiSelection(sal_False);
166         SetDropDownLineCount(20);
167     }
168 
169     //------------------------------------------------------------------
170     long ListBoxControl::PreNotify( NotifyEvent& rNEvt )
171     {
172         switch (rNEvt.GetType())
173         {
174             case EVENT_KEYINPUT:
175                 if (!IsInDropDown())
176                 {
177                     const KeyEvent *pEvt = rNEvt.GetKeyEvent();
178                     const KeyCode rKey = pEvt->GetKeyCode();
179 
180                     if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
181                         (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
182                     {
183                         // select next resp. previous entry
184                         int nPos = GetSelectEntryPos();
185                         nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
186                         if (nPos < 0)
187                             nPos = 0;
188                         if (nPos >= GetEntryCount())
189                             nPos = GetEntryCount() - 1;
190                         SelectEntryPos(sal::static_int_cast< sal_uInt16 >(nPos));
191                         Select();   // for calling Modify
192                         return 1;
193                     }
194                     else if (GetParent()->PreNotify(rNEvt))
195                         return 1;
196                 }
197                 break;
198         }
199         return ListBox::PreNotify(rNEvt);
200     }
201 
202     //==================================================================
203     //= ListBoxCellController
204     //==================================================================
205     //------------------------------------------------------------------
206     ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
207                              :CellController(pWin)
208     {
209     }
210 
211     //------------------------------------------------------------------
212     sal_Bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
213     {
214         ListBoxControl& rBox = GetListBox();
215         switch (rEvt.GetKeyCode().GetCode())
216         {
217             case KEY_UP:
218             case KEY_DOWN:
219                 if (!rEvt.GetKeyCode().IsShift() &&
220                      rEvt.GetKeyCode().IsMod1())
221                     return sal_False;
222                 // drop down the list box
223                 else
224                     if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
225                         return sal_False;
226             case KEY_PAGEUP:
227             case KEY_PAGEDOWN:
228                 if (rBox.IsTravelSelect())
229                     return sal_False;
230             default:
231                 return sal_True;
232         }
233     }
234 
235     //------------------------------------------------------------------
236     sal_Bool ListBoxCellController::IsModified() const
237     {
238         return GetListBox().GetSelectEntryPos() != GetListBox().GetSavedValue();
239     }
240 
241     //------------------------------------------------------------------
242     void ListBoxCellController::ClearModified()
243     {
244         GetListBox().SaveValue();
245     }
246 
247     //------------------------------------------------------------------
248     void ListBoxCellController::SetModifyHdl(const Link& rLink)
249     {
250         GetListBox().SetSelectHdl(rLink);
251     }
252 
253     //==================================================================
254     //= CheckBoxControl
255     //==================================================================
256     //------------------------------------------------------------------
257     CheckBoxControl::CheckBoxControl(Window* pParent, WinBits nWinStyle)
258                    :Control(pParent, nWinStyle)
259     {
260         const Wallpaper& rParentBackground = pParent->GetBackground();
261         if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() )
262             SetBackground( rParentBackground );
263         else
264         {
265             SetPaintTransparent( sal_True );
266             SetBackground();
267         }
268 
269         EnableChildTransparentMode();
270 
271         pBox = new TriStateBox(this,WB_CENTER|WB_VCENTER);
272         pBox->EnableChildTransparentMode();
273         pBox->SetPaintTransparent( sal_True );
274         pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) );
275         pBox->Show();
276     }
277 
278     //------------------------------------------------------------------
279     CheckBoxControl::~CheckBoxControl()
280     {
281         delete pBox;
282     }
283 
284     //------------------------------------------------------------------
285     IMPL_LINK( CheckBoxControl, OnClick, void*, EMPTYARG )
286     {
287         m_aClickLink.Call(pBox);
288         return m_aModifyLink.Call(pBox);
289     }
290 
291     //------------------------------------------------------------------
292     void CheckBoxControl::Resize()
293     {
294         Control::Resize();
295         pBox->SetPosSizePixel(Point(0,0),GetSizePixel());
296     }
297 
298     //------------------------------------------------------------------------------
299     void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent )
300     {
301         if ( _rEvent.GetType() == DATACHANGED_SETTINGS )
302             pBox->SetSettings( GetSettings() );
303     }
304 
305     //------------------------------------------------------------------------------
306     void CheckBoxControl::StateChanged( StateChangedType nStateChange )
307     {
308         Control::StateChanged(nStateChange);
309         if ( nStateChange == STATE_CHANGE_ZOOM )
310             pBox->SetZoom(GetZoom());
311     }
312 
313     //------------------------------------------------------------------
314     void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
315     {
316         pBox->Draw(pDev,rPos,rSize,nFlags);
317     }
318 
319     //------------------------------------------------------------------
320     void CheckBoxControl::GetFocus()
321     {
322         pBox->GrabFocus();
323     }
324 
325     //------------------------------------------------------------------
326     void CheckBoxControl::Paint(const Rectangle& rClientRect)
327     {
328         Control::Paint(rClientRect);
329         if (HasFocus())
330             ShowFocus(aFocusRect);
331     }
332 
333     //------------------------------------------------------------------
334     long CheckBoxControl::PreNotify(NotifyEvent& rEvt)
335     {
336         switch (rEvt.GetType())
337         {
338             case EVENT_GETFOCUS:
339                 ShowFocus(aFocusRect);
340                 break;
341             case EVENT_LOSEFOCUS:
342                 HideFocus();
343         }
344         return Control::PreNotify(rEvt);
345     }
346 
347     //==================================================================
348     //= CheckBoxCellController
349     //==================================================================
350     //------------------------------------------------------------------
351     sal_Bool CheckBoxCellController::WantMouseEvent() const
352     {
353         return sal_True;
354     }
355 
356     //------------------------------------------------------------------
357     CheckBox& CheckBoxCellController::GetCheckBox() const
358     {
359         return ((CheckBoxControl &)GetWindow()).GetBox();
360     }
361 
362     //------------------------------------------------------------------
363     sal_Bool CheckBoxCellController::IsModified() const
364     {
365         return GetCheckBox().GetSavedValue() != GetCheckBox().GetState();
366     }
367 
368     //------------------------------------------------------------------
369     void CheckBoxCellController::ClearModified()
370     {
371         GetCheckBox().SaveValue();
372     }
373 
374     //------------------------------------------------------------------
375     void CheckBoxCellController::SetModifyHdl(const Link& rLink)
376     {
377         ((CheckBoxControl &)GetWindow()).SetModifyHdl(rLink);
378     }
379 
380     //==================================================================
381     //= MultiLineEditImplementation
382     //==================================================================
383     //------------------------------------------------------------------
384     String MultiLineEditImplementation::GetText( LineEnd aSeparator ) const
385     {
386         return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetText( aSeparator );
387     }
388 
389     //------------------------------------------------------------------
390     String MultiLineEditImplementation::GetSelected( LineEnd aSeparator ) const
391     {
392         return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetSelected( aSeparator );
393     }
394 
395     //==================================================================
396     //= EditCellController
397     //==================================================================
398     //------------------------------------------------------------------
399     EditCellController::EditCellController( Edit* _pEdit )
400         :CellController( _pEdit )
401         ,m_pEditImplementation( new EditImplementation( *_pEdit ) )
402         ,m_bOwnImplementation( sal_True )
403     {
404     }
405 
406     //------------------------------------------------------------------
407     EditCellController::EditCellController( MultiLineTextCell* _pEdit )
408         :CellController( _pEdit )
409         ,m_pEditImplementation( new MultiLineEditImplementation( *_pEdit ) )
410         ,m_bOwnImplementation( sal_True )
411     {
412     }
413 
414     //------------------------------------------------------------------
415     EditCellController::EditCellController( IEditImplementation* _pImplementation )
416         :CellController( &_pImplementation->GetControl() )
417         ,m_pEditImplementation( _pImplementation )
418         ,m_bOwnImplementation( sal_False )
419     {
420     }
421 
422     //-----------------------------------------------------------------------------
423     EditCellController::~EditCellController( )
424     {
425         if ( m_bOwnImplementation )
426             DELETEZ( m_pEditImplementation );
427     }
428 
429     //-----------------------------------------------------------------------------
430     void EditCellController::SetModified()
431     {
432         m_pEditImplementation->SetModified();
433     }
434 
435     //-----------------------------------------------------------------------------
436     void EditCellController::ClearModified()
437     {
438         m_pEditImplementation->ClearModified();
439     }
440 
441     //------------------------------------------------------------------
442     sal_Bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const
443     {
444         sal_Bool bResult;
445         switch (rEvt.GetKeyCode().GetCode())
446         {
447             case KEY_END:
448             case KEY_RIGHT:
449             {
450                 Selection aSel = m_pEditImplementation->GetSelection();
451                 bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).Len();
452             }   break;
453             case KEY_HOME:
454             case KEY_LEFT:
455             {
456                 Selection aSel = m_pEditImplementation->GetSelection();
457                 bResult = !aSel && aSel.Min() == 0;
458             }   break;
459             default:
460                 bResult = sal_True;
461         }
462         return bResult;
463     }
464 
465     //------------------------------------------------------------------
466     sal_Bool EditCellController::IsModified() const
467     {
468         return m_pEditImplementation->IsModified();
469     }
470 
471     //------------------------------------------------------------------
472     void EditCellController::SetModifyHdl(const Link& rLink)
473     {
474         m_pEditImplementation->SetModifyHdl(rLink);
475     }
476 
477     //==================================================================
478     //= SpinCellController
479     //==================================================================
480     //------------------------------------------------------------------
481     SpinCellController::SpinCellController(SpinField* pWin)
482                          :CellController(pWin)
483     {
484     }
485 
486     //-----------------------------------------------------------------------------
487     void SpinCellController::SetModified()
488     {
489         GetSpinWindow().SetModifyFlag();
490     }
491 
492     //-----------------------------------------------------------------------------
493     void SpinCellController::ClearModified()
494     {
495         GetSpinWindow().ClearModifyFlag();
496     }
497 
498     //------------------------------------------------------------------
499     sal_Bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const
500     {
501         sal_Bool bResult;
502         switch (rEvt.GetKeyCode().GetCode())
503         {
504             case KEY_END:
505             case KEY_RIGHT:
506             {
507                 Selection aSel = GetSpinWindow().GetSelection();
508                 bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().Len();
509             }   break;
510             case KEY_HOME:
511             case KEY_LEFT:
512             {
513                 Selection aSel = GetSpinWindow().GetSelection();
514                 bResult = !aSel && aSel.Min() == 0;
515             }   break;
516             default:
517                 bResult = sal_True;
518         }
519         return bResult;
520     }
521 
522     //------------------------------------------------------------------
523     sal_Bool SpinCellController::IsModified() const
524     {
525         return GetSpinWindow().IsModified();
526     }
527 
528     //------------------------------------------------------------------
529     void SpinCellController::SetModifyHdl(const Link& rLink)
530     {
531         GetSpinWindow().SetModifyHdl(rLink);
532     }
533 
534     //==================================================================
535     //= FormattedFieldCellController
536     //==================================================================
537     //------------------------------------------------------------------
538     FormattedFieldCellController::FormattedFieldCellController( FormattedField* _pFormatted )
539         :EditCellController( _pFormatted )
540     {
541     }
542 
543     //------------------------------------------------------------------
544     void FormattedFieldCellController::CommitModifications()
545     {
546         static_cast< FormattedField& >( GetWindow() ).Commit();
547     }
548 
549     //==================================================================
550     //= MultiLineTextCell
551     //==================================================================
552     //------------------------------------------------------------------
553     void MultiLineTextCell::Modify()
554     {
555         GetTextEngine()->SetModified( sal_True );
556         MultiLineEdit::Modify();
557     }
558 
559     //------------------------------------------------------------------
560     sal_Bool MultiLineTextCell::dispatchKeyEvent( const KeyEvent& _rEvent )
561     {
562         Selection aOldSelection( GetSelection() );
563 
564         sal_Bool bWasModified = IsModified();
565         ClearModifyFlag( );
566 
567         sal_Bool bHandled = GetTextView()->KeyInput( _rEvent );
568 
569         sal_Bool bIsModified = IsModified();
570         if ( bWasModified && !bIsModified )
571             // not sure whether this can really happen
572             SetModifyFlag();
573 
574         if ( bHandled ) // the view claimed it handled the key input
575         {
576             // unfortunately, KeyInput also returns <TRUE/> (means "I handled this key input")
577             // when nothing really changed. Let's care for this.
578             Selection aNewSelection( GetSelection() );
579             if  (  aNewSelection != aOldSelection   // selection changed
580                 || bIsModified                      // or some other modification
581                 )
582                 return sal_True;
583         }
584         return sal_False;
585     }
586 
587     //------------------------------------------------------------------
588     long MultiLineTextCell::PreNotify( NotifyEvent& rNEvt )
589     {
590         if ( rNEvt.GetType() == EVENT_KEYINPUT )
591         {
592             if ( IsWindowOrChild( rNEvt.GetWindow() ) )
593             {
594                 // give the text view a chance to handle the keys
595                 // this is necessary since a lot of keys which are normally handled
596                 // by this view (in KeyInput) are intercepted by the EditBrowseBox,
597                 // which uses them for other reasons. An example is the KeyUp key,
598                 // which is used by both the text view and the edit browse box
599 
600                 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
601                 const KeyCode&  rKeyCode  = pKeyEvent->GetKeyCode();
602                 sal_uInt16 nCode = rKeyCode.GetCode();
603 
604                 if ( ( nCode == KEY_RETURN ) && ( rKeyCode.GetModifier() == KEY_MOD1 ) )
605                 {
606                     KeyEvent aEvent( pKeyEvent->GetCharCode(),
607                         KeyCode( KEY_RETURN ),
608                         pKeyEvent->GetRepeat()
609                     );
610                     if ( dispatchKeyEvent( aEvent ) )
611                         return 1;
612                 }
613 
614                 if ( ( nCode != KEY_TAB ) && ( nCode != KEY_RETURN ) )   // everything but tab and enter
615                 {
616                     if ( dispatchKeyEvent( *pKeyEvent ) )
617                         return 1;
618                 }
619             }
620         }
621         return MultiLineEdit::PreNotify( rNEvt );
622     }
623 
624 // .......................................................................
625 }   // namespace svt
626 // .......................................................................
627 
628 
629