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 <vcl/builder.hxx>
21 : #include <vcl/svapp.hxx>
22 : #include <vcl/scrbar.hxx>
23 :
24 : #include "formula/funcutl.hxx"
25 : #include "formula/IControlReferenceHandler.hxx"
26 : #include "ControlHelper.hxx"
27 : #include "ModuleHelper.hxx"
28 : #include "ForResId.hrc"
29 : #include "com/sun/star/accessibility/AccessibleRole.hpp"
30 :
31 :
32 : namespace formula
33 : {
34 :
35 : // class ArgEdit
36 0 : ArgEdit::ArgEdit( vcl::Window* pParent, WinBits nBits )
37 : : RefEdit( pParent, NULL, nBits ),
38 : pEdPrev ( NULL ),
39 : pEdNext ( NULL ),
40 : pSlider ( NULL ),
41 0 : nArgs ( 0 )
42 : {
43 0 : }
44 :
45 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeArgEdit(vcl::Window *pParent, VclBuilder::stringmap &)
46 : {
47 0 : return new ArgEdit(pParent, WB_BORDER);
48 : }
49 :
50 0 : void ArgEdit::Init( ArgEdit* pPrevEdit, ArgEdit* pNextEdit,
51 : ScrollBar& rArgSlider, sal_uInt16 nArgCount )
52 : {
53 0 : pEdPrev = pPrevEdit;
54 0 : pEdNext = pNextEdit;
55 0 : pSlider = &rArgSlider;
56 0 : nArgs = nArgCount;
57 0 : }
58 :
59 : // Cursor control for Edit Fields in Argument Dialog
60 0 : void ArgEdit::KeyInput( const KeyEvent& rKEvt )
61 : {
62 0 : vcl::KeyCode aCode = rKEvt.GetKeyCode();
63 0 : bool bUp = (aCode.GetCode() == KEY_UP);
64 0 : bool bDown = (aCode.GetCode() == KEY_DOWN);
65 :
66 0 : if ( pSlider
67 0 : && ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
68 0 : && ( bUp || bDown ) )
69 : {
70 0 : if ( nArgs > 1 )
71 : {
72 0 : ArgEdit* pEd = NULL;
73 0 : long nThumb = pSlider->GetThumbPos();
74 0 : bool bDoScroll = false;
75 0 : bool bChangeFocus = false;
76 :
77 0 : if ( bDown )
78 : {
79 0 : if ( nArgs > 4 )
80 : {
81 0 : if ( !pEdNext )
82 : {
83 0 : nThumb++;
84 0 : bDoScroll = ( nThumb+3 < (long)nArgs );
85 : }
86 : else
87 : {
88 0 : pEd = pEdNext;
89 0 : bChangeFocus = true;
90 : }
91 : }
92 0 : else if ( pEdNext )
93 : {
94 0 : pEd = pEdNext;
95 0 : bChangeFocus = true;
96 : }
97 : }
98 : else // if ( bUp )
99 : {
100 0 : if ( nArgs > 4 )
101 : {
102 0 : if ( !pEdPrev )
103 : {
104 0 : nThumb--;
105 0 : bDoScroll = ( nThumb >= 0 );
106 : }
107 : else
108 : {
109 0 : pEd = pEdPrev;
110 0 : bChangeFocus = true;
111 : }
112 : }
113 0 : else if ( pEdPrev )
114 : {
115 0 : pEd = pEdPrev;
116 0 : bChangeFocus = true;
117 : }
118 : }
119 :
120 0 : if ( bDoScroll )
121 : {
122 0 : pSlider->SetThumbPos( nThumb );
123 0 : ((Link&)pSlider->GetEndScrollHdl()).Call( pSlider );
124 : }
125 0 : else if ( bChangeFocus )
126 : {
127 0 : pEd->GrabFocus();
128 : }
129 : }
130 : }
131 : else
132 0 : RefEdit::KeyInput( rKEvt );
133 0 : }
134 :
135 : // class ArgInput
136 0 : ArgInput::ArgInput()
137 : {
138 0 : pFtArg=NULL;
139 0 : pBtnFx=NULL;
140 0 : pEdArg=NULL;
141 0 : pRefBtn=NULL;
142 0 : }
143 :
144 0 : void ArgInput::InitArgInput( FixedText* pftArg, PushButton* pbtnFx,
145 : ArgEdit* pedArg, RefButton* prefBtn)
146 : {
147 0 : pFtArg =pftArg;
148 0 : pBtnFx =pbtnFx;
149 0 : pEdArg =pedArg;
150 0 : pRefBtn=prefBtn;
151 :
152 0 : if(pBtnFx!=NULL)
153 : {
154 0 : pBtnFx->SetClickHdl ( LINK( this, ArgInput, FxBtnClickHdl ) );
155 0 : pBtnFx->SetGetFocusHdl( LINK( this, ArgInput, FxBtnFocusHdl ) );
156 : }
157 0 : if(pRefBtn!=NULL)
158 : {
159 0 : pRefBtn->SetClickHdl ( LINK( this, ArgInput, RefBtnClickHdl ) );
160 0 : pRefBtn->SetGetFocusHdl( LINK( this, ArgInput, RefBtnFocusHdl ) );
161 : }
162 0 : if(pEdArg!=NULL)
163 : {
164 0 : pEdArg->SetGetFocusHdl ( LINK( this, ArgInput, EdFocusHdl ) );
165 0 : pEdArg->SetModifyHdl ( LINK( this, ArgInput, EdModifyHdl ) );
166 : }
167 :
168 0 : }
169 :
170 : // Sets the Name for the Argument
171 0 : void ArgInput::SetArgName(const OUString &aArg)
172 : {
173 0 : if(pFtArg !=NULL) pFtArg->SetText(aArg );
174 0 : }
175 :
176 : // Returns the Name for the Argument
177 0 : OUString ArgInput::GetArgName()
178 : {
179 0 : OUString aPrivArgName;
180 0 : if(pFtArg !=NULL)
181 0 : aPrivArgName=pFtArg->GetText();
182 :
183 0 : return aPrivArgName;
184 : }
185 :
186 : //Sets the Name for the Argument
187 0 : void ArgInput::SetArgNameFont (const vcl::Font &aFont)
188 : {
189 0 : if(pFtArg !=NULL) pFtArg->SetFont(aFont);
190 0 : }
191 :
192 : //Sets up the Selection for the EditBox.
193 0 : void ArgInput::SetArgSelection (const Selection& rSel )
194 : {
195 0 : if(pEdArg !=NULL) pEdArg ->SetSelection(rSel );
196 0 : }
197 :
198 : //Sets the Value for the Argument
199 0 : void ArgInput::SetArgVal(const OUString &rVal)
200 : {
201 0 : if(pEdArg !=NULL)
202 : {
203 0 : pEdArg ->SetRefString(rVal);
204 : }
205 0 : }
206 :
207 : //Returns the Value for the Argument
208 0 : OUString ArgInput::GetArgVal()
209 : {
210 0 : OUString aResult;
211 0 : if(pEdArg!=NULL)
212 : {
213 0 : aResult=pEdArg->GetText();
214 : }
215 0 : return aResult;
216 : }
217 :
218 : //Hides the Controls
219 0 : void ArgInput::Hide()
220 : {
221 0 : if ( pFtArg && pBtnFx && pEdArg && pRefBtn)
222 : {
223 0 : pFtArg->Hide();
224 0 : pBtnFx->Hide();
225 0 : pEdArg->Hide();
226 0 : pRefBtn->Hide();
227 : }
228 0 : }
229 :
230 : //Casts the Controls again.
231 0 : void ArgInput::Show()
232 : {
233 0 : if ( pFtArg && pBtnFx && pEdArg && pRefBtn)
234 : {
235 0 : pFtArg->Show();
236 0 : pBtnFx->Show();
237 0 : pEdArg->Show();
238 0 : pRefBtn->Show();
239 : }
240 0 : }
241 :
242 0 : void ArgInput::UpdateAccessibleNames()
243 : {
244 0 : OUString aArgName(":");
245 0 : aArgName += pFtArg->GetText();
246 :
247 0 : OUString aName = pBtnFx->GetQuickHelpText();
248 0 : aName += aArgName;
249 0 : pBtnFx->SetAccessibleName(aName);
250 :
251 0 : aName = pRefBtn->GetQuickHelpText();
252 0 : aName += aArgName;
253 0 : pRefBtn->SetAccessibleName(aName);
254 0 : }
255 :
256 0 : void ArgInput::FxClick()
257 : {
258 0 : aFxClickLink.Call(this);
259 0 : }
260 :
261 0 : void ArgInput::RefClick()
262 : {
263 0 : aRefClickLink.Call(this);
264 0 : }
265 :
266 0 : void ArgInput::FxFocus()
267 : {
268 0 : aFxFocusLink.Call(this);
269 0 : }
270 :
271 0 : void ArgInput::RefFocus()
272 : {
273 0 : aRefFocusLink.Call(this);
274 0 : }
275 :
276 0 : void ArgInput::EdFocus()
277 : {
278 0 : aEdFocusLink.Call(this);
279 0 : }
280 :
281 0 : void ArgInput::EdModify()
282 : {
283 0 : aEdModifyLink.Call(this);
284 0 : }
285 :
286 0 : IMPL_LINK( ArgInput, FxBtnClickHdl, ImageButton*, pBtn )
287 : {
288 0 : if(pBtn == pBtnFx)
289 0 : FxClick();
290 :
291 0 : return 0;
292 : }
293 :
294 0 : IMPL_LINK( ArgInput, RefBtnClickHdl,RefButton*, pBtn )
295 : {
296 0 : if(pRefBtn == pBtn)
297 0 : RefClick();
298 :
299 0 : return 0;
300 : }
301 :
302 0 : IMPL_LINK( ArgInput, FxBtnFocusHdl, ImageButton*, pBtn )
303 : {
304 0 : if(pBtn == pBtnFx)
305 0 : FxFocus();
306 :
307 0 : return 0;
308 : }
309 :
310 0 : IMPL_LINK( ArgInput, RefBtnFocusHdl,RefButton*, pBtn )
311 : {
312 0 : if(pRefBtn == pBtn)
313 0 : RefFocus();
314 :
315 0 : return 0;
316 : }
317 :
318 0 : IMPL_LINK( ArgInput, EdFocusHdl, ArgEdit*, pEd )
319 : {
320 0 : if(pEd == pEdArg)
321 0 : EdFocus();
322 :
323 0 : return 0;
324 : }
325 :
326 0 : IMPL_LINK( ArgInput, EdModifyHdl,ArgEdit*, pEd )
327 : {
328 0 : if(pEd == pEdArg)
329 0 : EdModify();
330 :
331 0 : return 0;
332 : }
333 :
334 : // class EditBox
335 :
336 0 : EditBox::EditBox( vcl::Window* pParent, WinBits nBits )
337 : :Control(pParent,nBits),
338 0 : bMouseFlag(false)
339 : {
340 0 : WinBits nStyle=GetStyle();
341 0 : SetStyle( nStyle| WB_DIALOGCONTROL);
342 :
343 0 : pMEdit=new MultiLineEdit(this,WB_LEFT | WB_VSCROLL | (nStyle & WB_TABSTOP) |
344 0 : WB_NOBORDER | WB_NOHIDESELECTION | WB_IGNORETAB);
345 0 : pMEdit->Show();
346 0 : aOldSel=pMEdit->GetSelection();
347 0 : Resize();
348 0 : WinBits nWinStyle=GetStyle() | WB_DIALOGCONTROL;
349 0 : SetStyle(nWinStyle);
350 :
351 : // #105582# the HelpId from the resource must be set for the MultiLineEdit,
352 : // not for the control that contains it.
353 0 : pMEdit->SetHelpId( GetHelpId() );
354 0 : SetHelpId( "" );
355 0 : }
356 :
357 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeEditBox(vcl::Window *pParent, VclBuilder::stringmap &)
358 : {
359 0 : return new EditBox(pParent, WB_BORDER);
360 : }
361 :
362 0 : EditBox::~EditBox()
363 : {
364 0 : MultiLineEdit* pTheEdit=pMEdit;
365 0 : pMEdit->Disable();
366 0 : pMEdit=NULL;
367 0 : delete pTheEdit;
368 0 : }
369 :
370 : // When the selection is changed this function will be called
371 0 : void EditBox::SelectionChanged()
372 : {
373 0 : aSelChangedLink.Call(this);
374 0 : }
375 :
376 : // When the size is changed, MultiLineEdit must be adapted..
377 0 : void EditBox::Resize()
378 : {
379 0 : Size aSize=GetOutputSizePixel();
380 0 : if(pMEdit!=NULL) pMEdit->SetOutputSizePixel(aSize);
381 0 : }
382 :
383 : // When the Control is activated, the Selection is repealed
384 : // and the Cursor set at the end.
385 0 : void EditBox::GetFocus()
386 : {
387 0 : if(pMEdit!=NULL)
388 : {
389 0 : pMEdit->GrabFocus();
390 : }
391 0 : }
392 :
393 : //When an Event is cleared, this Routine is
394 : //first called and a PostUserEvent is sent.
395 0 : bool EditBox::PreNotify( NotifyEvent& rNEvt )
396 : {
397 0 : bool nResult = true;
398 :
399 0 : if(pMEdit==NULL) return nResult;
400 :
401 0 : sal_uInt16 nSwitch=rNEvt.GetType();
402 0 : if(nSwitch==EVENT_KEYINPUT)// || nSwitch==EVENT_KEYUP)
403 : {
404 0 : const vcl::KeyCode& aKeyCode=rNEvt.GetKeyEvent()->GetKeyCode();
405 0 : sal_uInt16 nKey=aKeyCode.GetCode();
406 0 : if( (nKey==KEY_RETURN && !aKeyCode.IsShift()) || nKey==KEY_TAB )
407 : {
408 0 : nResult = GetParent()->Notify(rNEvt);
409 : }
410 : else
411 : {
412 0 : nResult=Control::PreNotify(rNEvt);
413 0 : Application::PostUserEvent( LINK( this, EditBox, ChangedHdl ) );
414 : }
415 :
416 : }
417 : else
418 : {
419 0 : nResult=Control::PreNotify(rNEvt);
420 :
421 0 : if(nSwitch==EVENT_MOUSEBUTTONDOWN || nSwitch==EVENT_MOUSEBUTTONUP)
422 : {
423 0 : bMouseFlag=true;
424 0 : Application::PostUserEvent( LINK( this, EditBox, ChangedHdl ) );
425 : }
426 : }
427 0 : return nResult;
428 : }
429 :
430 : //When an Event cleared wurde, this routine is
431 : //first called.
432 0 : IMPL_LINK_NOARG(EditBox, ChangedHdl)
433 : {
434 0 : if(pMEdit!=NULL)
435 : {
436 0 : Selection aNewSel=pMEdit->GetSelection();
437 :
438 0 : if(aNewSel.Min()!=aOldSel.Min() || aNewSel.Max()!=aOldSel.Max())
439 : {
440 0 : SelectionChanged();
441 0 : aOldSel=aNewSel;
442 : }
443 : }
444 0 : return 0;
445 : }
446 :
447 0 : void EditBox::UpdateOldSel()
448 : {
449 : // if selection is set for editing a function, store it as aOldSel,
450 : // so SelectionChanged isn't called in the next ChangedHdl call
451 :
452 0 : if (pMEdit)
453 0 : aOldSel = pMEdit->GetSelection();
454 0 : }
455 :
456 : // class RefEdit
457 :
458 : #define SC_ENABLE_TIME 100
459 :
460 0 : RefEdit::RefEdit( vcl::Window* _pParent, vcl::Window* pShrinkModeLabel, WinBits nStyle )
461 : : Edit( _pParent, nStyle )
462 : , pAnyRefDlg( NULL )
463 0 : , pLabelWidget(pShrinkModeLabel)
464 : {
465 0 : aTimer.SetTimeoutHdl( LINK( this, RefEdit, UpdateHdl ) );
466 0 : aTimer.SetTimeout( SC_ENABLE_TIME );
467 0 : }
468 :
469 0 : RefEdit::RefEdit( vcl::Window* _pParent,IControlReferenceHandler* pParent,
470 : vcl::Window* pShrinkModeLabel, const ResId& rResId )
471 : : Edit( _pParent, rResId )
472 : , pAnyRefDlg( pParent )
473 0 : , pLabelWidget(pShrinkModeLabel)
474 : {
475 0 : aTimer.SetTimeoutHdl( LINK( this, RefEdit, UpdateHdl ) );
476 0 : aTimer.SetTimeout( SC_ENABLE_TIME );
477 0 : }
478 :
479 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeRefEdit(vcl::Window *pParent, VclBuilder::stringmap &)
480 : {
481 0 : return new RefEdit(pParent, NULL, WB_BORDER);
482 : }
483 :
484 0 : RefEdit::~RefEdit()
485 : {
486 0 : aTimer.SetTimeoutHdl( Link() );
487 0 : aTimer.Stop();
488 0 : }
489 :
490 0 : void RefEdit::SetRefString( const OUString& rStr )
491 : {
492 0 : Edit::SetText( rStr );
493 0 : }
494 :
495 0 : void RefEdit::SetRefValid(bool bValid)
496 : {
497 0 : if (bValid)
498 : {
499 0 : SetControlForeground();
500 0 : SetControlBackground();
501 : }
502 : else
503 : {
504 0 : SetControlForeground(COL_WHITE);
505 0 : SetControlBackground(0xff6563);
506 : }
507 0 : }
508 :
509 0 : void RefEdit::SetText(const OUString& rStr)
510 : {
511 0 : Edit::SetText( rStr );
512 0 : UpdateHdl( &aTimer );
513 0 : }
514 :
515 0 : void RefEdit::StartUpdateData()
516 : {
517 0 : aTimer.Start();
518 0 : }
519 :
520 0 : void RefEdit::SetReferences( IControlReferenceHandler* pDlg, vcl::Window* pLabel )
521 : {
522 0 : pAnyRefDlg = pDlg;
523 0 : pLabelWidget = pLabel;
524 :
525 0 : if( pDlg )
526 : {
527 0 : aTimer.SetTimeoutHdl( LINK( this, RefEdit, UpdateHdl ) );
528 0 : aTimer.SetTimeout( SC_ENABLE_TIME );
529 : }
530 : else
531 : {
532 0 : aTimer.SetTimeoutHdl( Link() );
533 0 : aTimer.Stop();
534 : }
535 0 : }
536 :
537 0 : void RefEdit::Modify()
538 : {
539 0 : Edit::Modify();
540 0 : if( pAnyRefDlg )
541 0 : pAnyRefDlg->HideReference();
542 0 : }
543 :
544 0 : void RefEdit::KeyInput( const KeyEvent& rKEvt )
545 : {
546 0 : const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
547 0 : if( pAnyRefDlg && !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
548 0 : pAnyRefDlg->ReleaseFocus( this );
549 : else
550 0 : Edit::KeyInput( rKEvt );
551 0 : }
552 :
553 0 : void RefEdit::GetFocus()
554 : {
555 0 : Edit::GetFocus();
556 0 : StartUpdateData();
557 0 : }
558 :
559 0 : void RefEdit::LoseFocus()
560 : {
561 0 : Edit::LoseFocus();
562 0 : if( pAnyRefDlg )
563 0 : pAnyRefDlg->HideReference();
564 0 : }
565 :
566 0 : IMPL_LINK_NOARG(RefEdit, UpdateHdl)
567 : {
568 0 : if( pAnyRefDlg )
569 0 : pAnyRefDlg->ShowReference( GetText() );
570 0 : return 0;
571 : }
572 :
573 : //class RefButton
574 0 : RefButton::RefButton( vcl::Window* _pParent, WinBits nStyle ) :
575 : ImageButton( _pParent, nStyle ),
576 : aImgRefStart( ModuleRes( RID_BMP_REFBTN1 ) ),
577 : aImgRefDone( ModuleRes( RID_BMP_REFBTN2 ) ),
578 : aShrinkQuickHelp( ModuleRes( RID_STR_SHRINK ).toString() ),
579 : aExpandQuickHelp( ModuleRes( RID_STR_EXPAND ).toString() ),
580 : pAnyRefDlg( NULL ),
581 0 : pRefEdit( NULL )
582 : {
583 0 : SetStartImage();
584 0 : }
585 :
586 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeRefButton(vcl::Window *pParent, VclBuilder::stringmap &)
587 : {
588 0 : return new RefButton(pParent, 0);
589 : }
590 :
591 0 : void RefButton::SetStartImage()
592 : {
593 0 : SetModeImage( aImgRefStart );
594 0 : SetQuickHelpText( aShrinkQuickHelp );
595 0 : }
596 :
597 0 : void RefButton::SetEndImage()
598 : {
599 0 : SetModeImage( aImgRefDone );
600 0 : SetQuickHelpText( aExpandQuickHelp );
601 0 : }
602 :
603 0 : void RefButton::SetReferences( IControlReferenceHandler* pDlg, RefEdit* pEdit )
604 : {
605 0 : pAnyRefDlg = pDlg;
606 0 : pRefEdit = pEdit;
607 0 : }
608 :
609 0 : void RefButton::Click()
610 : {
611 0 : if( pAnyRefDlg )
612 0 : pAnyRefDlg->ToggleCollapsed( pRefEdit, this );
613 0 : }
614 :
615 0 : void RefButton::KeyInput( const KeyEvent& rKEvt )
616 : {
617 0 : const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
618 0 : if( pAnyRefDlg && !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
619 0 : pAnyRefDlg->ReleaseFocus( pRefEdit );
620 : else
621 0 : ImageButton::KeyInput( rKEvt );
622 0 : }
623 :
624 0 : void RefButton::GetFocus()
625 : {
626 0 : ImageButton::GetFocus();
627 0 : if( pRefEdit )
628 0 : pRefEdit->StartUpdateData();
629 0 : }
630 :
631 0 : void RefButton::LoseFocus()
632 : {
633 0 : ImageButton::LoseFocus();
634 0 : if( pRefEdit )
635 0 : pRefEdit->Modify();
636 0 : }
637 :
638 276 : } // formula
639 :
640 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|