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