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