1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include "scitems.hxx"
24 #include <editeng/eeitem.hxx>
26 #include <sfx2/app.hxx>
27 #include <editeng/adjustitem.hxx>
28 #include <editeng/editview.hxx>
29 #include <editeng/editstat.hxx>
30 #include <editeng/frmdiritem.hxx>
31 #include <editeng/lspcitem.hxx>
32 #include <sfx2/bindings.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/event.hxx>
36 #include <sfx2/imgmgr.hxx>
38 #include <editeng/scriptspaceitem.hxx>
39 #include <editeng/scripttypeitem.hxx>
40 #include <vcl/cursor.hxx>
41 #include <vcl/help.hxx>
42 #include <svl/stritem.hxx>
45 #include "inputwin.hxx"
47 #include "uiitems.hxx"
49 #include "scresid.hxx"
51 #include "globstr.hrc"
52 #include "reffact.hxx"
53 #include "editutil.hxx"
54 #include "inputhdl.hxx"
55 #include "tabvwsh.hxx"
56 #include "document.hxx"
58 #include "appoptio.hxx"
59 #include "rangenam.hxx"
60 #include <formula/compiler.hrc>
62 #include "rangeutl.hxx"
63 #include "docfunc.hxx"
64 #include "funcdesc.hxx"
65 #include "markdata.hxx"
66 #include <editeng/fontitem.hxx>
67 #include <com/sun/star/accessibility/XAccessible.hpp>
68 #include "AccessibleEditObject.hxx"
69 #include "AccessibleText.hxx"
70 #include <svtools/miscopt.hxx>
71 #include <comphelper/string.hxx>
72 #include <com/sun/star/frame/XLayoutManager.hpp>
73 #include <com/sun/star/frame/XModel.hpp>
74 #include <com/sun/star/frame/XController.hpp>
76 #define THESIZE 1000000 //!!! langt... :-)
77 #define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich?
79 #define INPUTWIN_MULTILINES 6
80 const long BUTTON_OFFSET
= 2; ///< space between input line and the button to expand / collapse
81 const long ADDITIONAL_BORDER
= 1; ///< height of the line at the bottom
82 const long ADDITIONAL_SPACE
= 4; ///< additional vertical space when the multiline edit has more lines
84 using com::sun::star::uno::Reference
;
85 using com::sun::star::uno::UNO_QUERY
;
87 using com::sun::star::frame::XLayoutManager
;
88 using com::sun::star::frame::XModel
;
89 using com::sun::star::frame::XFrame
;
90 using com::sun::star::frame::XController
;
91 using com::sun::star::beans::XPropertySet
;
98 SC_NAME_INPUT_NAMEDRANGE
,
99 SC_NAME_INPUT_DATABASE
,
102 SC_NAME_INPUT_DEFINE
,
103 SC_NAME_INPUT_BAD_NAME
,
104 SC_NAME_INPUT_BAD_SELECTION
,
109 ScTextWndBase::ScTextWndBase( Window
* pParent
, WinBits nStyle
)
110 : Window ( pParent
, nStyle
)
112 if ( IsNativeControlSupported( CTRL_EDITBOX
, PART_ENTIRE_CONTROL
) )
114 SetType( WINDOW_CALCINPUTLINE
);
115 SetBorderStyle( WINDOW_BORDER_NWF
);
119 //==================================================================
120 // class ScInputWindowWrapper
121 //==================================================================
123 SFX_IMPL_CHILDWINDOW_WITHID(ScInputWindowWrapper
,FID_INPUTLINE_STATUS
)
125 ScInputWindowWrapper::ScInputWindowWrapper( Window
* pParentP
,
127 SfxBindings
* pBindings
,
128 SfxChildWinInfo
* /* pInfo */ )
129 : SfxChildWindow( pParentP
, nId
)
131 ScInputWindow
* pWin
=new ScInputWindow( pParentP
, pBindings
);
136 pWin
->SetSizePixel( pWin
->CalcWindowSizePixel() );
138 eChildAlignment
= SFX_ALIGN_LOWESTTOP
;
139 pBindings
->Invalidate( FID_TOGGLEINPUTLINE
);
142 // GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!
144 SfxChildWinInfo
ScInputWindowWrapper::GetInfo() const
146 SfxChildWinInfo aInfo
= SfxChildWindow::GetInfo();
150 //==================================================================
152 #define IMAGE(id) pImgMgr->SeekImage(id)
153 static bool lcl_isExperimentalMode()
155 // make inputbar feature on by default, leave the switch for the
156 // moment in case we need to back it out easily
160 //==================================================================
161 // class ScInputWindow
162 //==================================================================
164 static ScTextWndBase
* lcl_chooseRuntimeImpl( Window
* pParent
, SfxBindings
* pBind
)
166 ScTabViewShell
* pViewSh
= NULL
;
167 SfxDispatcher
* pDisp
= pBind
->GetDispatcher();
170 SfxViewFrame
* pViewFrm
= pDisp
->GetFrame();
172 pViewSh
= PTR_CAST( ScTabViewShell
, pViewFrm
->GetViewShell() );
175 if ( !lcl_isExperimentalMode() )
176 return new ScTextWnd( pParent
, pViewSh
);
177 return new ScInputBarGroup( pParent
, pViewSh
);
180 ScInputWindow::ScInputWindow( Window
* pParent
, SfxBindings
* pBind
) :
181 // mit WB_CLIPCHILDREN, sonst Flicker
182 ToolBox ( pParent
, WinBits(WB_CLIPCHILDREN
) ),
184 pRuntimeWindow ( lcl_chooseRuntimeImpl( this, pBind
) ),
185 aTextWindow ( *pRuntimeWindow
),
187 aTextOk ( ScResId( SCSTR_QHELP_BTNOK
) ), // nicht immer neu aus Resource
188 aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL
) ),
189 aTextSum ( ScResId( SCSTR_QHELP_BTNSUM
) ),
190 aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL
) ),
192 bIsOkCancelMode ( false ),
194 mbIsMultiLine ( lcl_isExperimentalMode() )
196 ScModule
* pScMod
= SC_MOD();
197 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
199 // #i73615# don't rely on SfxViewShell::Current while constructing the input line
200 // (also for GetInputHdl below)
201 ScTabViewShell
* pViewSh
= NULL
;
202 SfxDispatcher
* pDisp
= pBind
->GetDispatcher();
205 SfxViewFrame
* pViewFrm
= pDisp
->GetFrame();
207 pViewSh
= PTR_CAST( ScTabViewShell
, pViewFrm
->GetViewShell() );
209 OSL_ENSURE( pViewSh
, "no view shell for input window" );
211 // Position window, 3 buttons, input window
212 InsertWindow ( 1, &aWndPos
, 0, 0 );
213 InsertSeparator ( 1 );
214 InsertItem ( SID_INPUT_FUNCTION
, IMAGE( SID_INPUT_FUNCTION
), 0, 2 );
215 InsertItem ( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
), 0, 3 );
216 InsertItem ( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
), 0, 4 );
217 InsertSeparator ( 5 );
218 InsertWindow ( 7, &aTextWindow
, 0, 6 );
220 aWndPos
.SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND
) );
221 aWndPos
.SetHelpId ( HID_INSWIN_POS
);
222 aTextWindow
.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND
) );
223 aTextWindow
.SetHelpId ( HID_INSWIN_INPUT
);
225 // kein SetHelpText, die Hilfetexte kommen aus der Hilfe
227 SetItemText ( SID_INPUT_FUNCTION
, ScResId( SCSTR_QHELP_BTNCALC
) );
228 SetHelpId ( SID_INPUT_FUNCTION
, HID_INSWIN_CALC
);
230 SetItemText ( SID_INPUT_SUM
, aTextSum
);
231 SetHelpId ( SID_INPUT_SUM
, HID_INSWIN_SUMME
);
233 SetItemText ( SID_INPUT_EQUAL
, aTextEqual
);
234 SetHelpId ( SID_INPUT_EQUAL
, HID_INSWIN_FUNC
);
236 SetHelpId( HID_SC_INPUTWIN
); // fuer die ganze Eingabezeile
241 pInputHdl
= SC_MOD()->GetInputHdl( pViewSh
, false ); // use own handler even if ref-handler is set
243 pInputHdl
->SetInputWindow( this );
245 if (pInputHdl
&& !pInputHdl
->GetFormString().isEmpty())
247 // Umschalten waehrend der Funktionsautopilot aktiv ist
248 // -> Inhalt des Funktionsautopiloten wieder anzeigen
249 //! auch Selektion (am InputHdl gemerkt) wieder anzeigen
251 aTextWindow
.SetTextString( pInputHdl
->GetFormString() );
253 else if ( pInputHdl
&& pInputHdl
->IsInputMode() )
255 // wenn waehrend des Editierens die Eingabezeile weg war
256 // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
257 // wieder den gerade editierten Text aus dem InputHandler anzeigen
259 aTextWindow
.SetTextString( pInputHdl
->GetEditString() ); // Text anzeigen
260 if ( pInputHdl
->IsTopMode() )
261 pInputHdl
->SetMode( SC_INPUT_TABLE
); // Focus kommt eh nach unten
264 pViewSh
->UpdateInputHandler( sal_True
); // unbedingtes Update
266 pImgMgr
->RegisterToolBox( this );
267 SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA
));
270 ScInputWindow::~ScInputWindow()
272 sal_Bool bDown
= ( ScGlobal::pSysLocale
== NULL
); // after Clear?
274 // if any view's input handler has a pointer to this input window, reset it
275 // (may be several ones, #74522#)
276 // member pInputHdl is not used here
280 TypeId aScType
= TYPE(ScTabViewShell
);
281 SfxViewShell
* pSh
= SfxViewShell::GetFirst( &aScType
);
284 ScInputHandler
* pHdl
= ((ScTabViewShell
*)pSh
)->GetInputHandler();
285 if ( pHdl
&& pHdl
->GetInputWindow() == this )
287 pHdl
->SetInputWindow( NULL
);
288 pHdl
->StopInputWinEngine( false ); // reset pTopView pointer
290 pSh
= SfxViewShell::GetNext( *pSh
, &aScType
);
294 SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
297 void ScInputWindow::SetInputHandler( ScInputHandler
* pNew
)
299 // wird im Activate der View gerufen...
301 if ( pNew
!= pInputHdl
)
303 // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
304 // geloeschten ViewShell, darum hier auf keinen Fall anfassen!
308 pInputHdl
->SetInputWindow( this );
312 bool ScInputWindow::UseSubTotal(ScRangeList
* pRangeList
) const
314 bool bSubTotal
= false;
315 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
318 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
319 size_t nRangeCount (pRangeList
->size());
320 size_t nRangeIndex (0);
321 while (!bSubTotal
&& nRangeIndex
< nRangeCount
)
323 const ScRange
* pRange
= (*pRangeList
)[nRangeIndex
];
326 SCTAB
nTabEnd(pRange
->aEnd
.Tab());
327 SCTAB
nTab(pRange
->aStart
.Tab());
328 while (!bSubTotal
&& nTab
<= nTabEnd
)
330 SCROW
nRowEnd(pRange
->aEnd
.Row());
331 SCROW
nRow(pRange
->aStart
.Row());
332 while (!bSubTotal
&& nRow
<= nRowEnd
)
334 if (pDoc
->RowFiltered(nRow
, nTab
))
345 const ScDBCollection::NamedDBs
& rDBs
= pDoc
->GetDBCollection()->getNamedDBs();
346 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
347 for (; !bSubTotal
&& itr
!= itrEnd
; ++itr
)
349 const ScDBData
& rDB
= *itr
;
350 if (!rDB
.HasAutoFilter())
354 while (!bSubTotal
&& nRangeIndex
< nRangeCount
)
356 const ScRange
* pRange
= (*pRangeList
)[nRangeIndex
];
360 rDB
.GetArea(aDBArea
);
361 if (aDBArea
.Intersects(*pRange
))
371 void ScInputWindow::Select()
373 ScModule
* pScMod
= SC_MOD();
376 switch ( GetCurItemId() )
378 case SID_INPUT_FUNCTION
:
380 //! new method at ScModule to query if function autopilot is open
381 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
382 if ( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) )
384 pViewFrm
->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION
,
385 SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
);
387 // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
388 // zu werden, egal ob's geklappt hat oder nicht
389 // SetOkCancelMode();
394 case SID_INPUT_CANCEL
:
395 pScMod
->InputCancelHandler();
400 pScMod
->InputEnterHandler();
402 aTextWindow
.Invalidate(); // sonst bleibt Selektion stehen
407 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
410 const ScMarkData
& rMark
= pViewSh
->GetViewData()->GetMarkData();
411 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
413 ScRangeList aMarkRangeList
;
414 rMark
.FillRangeListWithMarks( &aMarkRangeList
, false );
415 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
417 // check if one of the marked ranges is empty
419 const size_t nCount
= aMarkRangeList
.size();
420 for ( size_t i
= 0; i
< nCount
; ++i
)
422 const ScRange
aRange( *aMarkRangeList
[i
] );
423 if ( pDoc
->IsBlockEmpty( aRange
.aStart
.Tab(),
424 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
425 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() ) )
434 ScRangeList aRangeList
;
435 const sal_Bool bDataFound
= pViewSh
->GetAutoSumArea( aRangeList
);
438 ScAddress aAddr
= aRangeList
.back()->aEnd
;
440 const sal_Bool
bSubTotal( UseSubTotal( &aRangeList
) );
441 pViewSh
->EnterAutoSum( aRangeList
, bSubTotal
, aAddr
);
446 const sal_Bool
bSubTotal( UseSubTotal( &aMarkRangeList
) );
447 for ( size_t i
= 0; i
< nCount
; ++i
)
449 const ScRange
aRange( *aMarkRangeList
[i
] );
450 const bool bSetCursor
= ( i
== nCount
- 1 ? true : false );
451 const bool bContinue
= ( i
!= 0 ? true : false );
452 if ( !pViewSh
->AutoSum( aRange
, bSubTotal
, bSetCursor
, bContinue
) )
454 pViewSh
->MarkRange( aRange
, false, false );
455 pViewSh
->SetCursor( aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
456 const ScRangeList aRangeList
;
457 ScAddress aAddr
= aRange
.aEnd
;
459 const OUString aFormula
= pViewSh
->GetAutoSumFormula(
460 aRangeList
, bSubTotal
, aAddr
);
461 SetFuncString( aFormula
);
467 else // nur in Eingabezeile einfuegen
469 ScRangeList aRangeList
;
470 const sal_Bool bDataFound
= pViewSh
->GetAutoSumArea( aRangeList
);
471 const sal_Bool
bSubTotal( UseSubTotal( &aRangeList
) );
472 ScAddress aAddr
= pViewSh
->GetViewData()->GetCurPos();
473 const OUString aFormula
= pViewSh
->GetAutoSumFormula( aRangeList
, bSubTotal
, aAddr
);
474 SetFuncString( aFormula
);
476 if ( bDataFound
&& pScMod
->IsEditMode() )
478 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
481 pHdl
->InitRangeFinder( aFormula
);
483 //! SetSelection am InputHandler ???
484 //! bSelIsRef setzen ???
485 const sal_Int32 nOpen
= aFormula
.indexOf('(');
486 const xub_StrLen nLen
= aFormula
.getLength();
487 if ( nOpen
!= -1 && nLen
> nOpen
)
492 ESelection
aSel(0,nOpen
+nAdd
,0,nLen
-1);
493 EditView
* pTableView
= pHdl
->GetTableView();
495 pTableView
->SetSelection(aSel
);
496 EditView
* pTopView
= pHdl
->GetTopView();
498 pTopView
->SetSelection(aSel
);
507 case SID_INPUT_EQUAL
:
509 aTextWindow
.StartEditEngine();
510 if ( pScMod
->IsEditMode() ) // nicht, wenn z.B. geschuetzt
512 aTextWindow
.StartEditEngine();
513 aTextWindow
.SetTextString(OUString('='));
515 EditView
* pView
= aTextWindow
.GetEditView();
518 pView
->SetSelection( ESelection(0,1, 0,1) );
519 pScMod
->InputChanged(pView
);
521 pView
->SetEditEngineUpdateMode(sal_True
);
529 void ScInputWindow::Paint( const Rectangle
& rRect
)
531 ToolBox::Paint( rRect
);
533 // draw a line at the bottom to distinguish that from the grid
534 // (we have space for that thanks to ADDITIONAL_BORDER)
535 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
536 SetLineColor( rStyleSettings
.GetShadowColor() );
538 Size aSize
= GetSizePixel();
539 DrawLine( Point( 0, aSize
.Height() - 1 ), Point( aSize
.Width() - 1, aSize
.Height() - 1 ) );
542 void ScInputWindow::Resize()
547 aTextWindow
.Resize();
548 Size aSize
= GetSizePixel();
549 aSize
.Height() = CalcWindowSizePixel().Height() + ADDITIONAL_BORDER
;
550 ScInputBarGroup
* pGroupBar
= dynamic_cast< ScInputBarGroup
* > ( pRuntimeWindow
.get() );
553 // To ensure smooth display and prevent the items in the toolbar being
554 // repositioned ( vertically ) we lock the vertical positioning of the toolbox
555 // items when we are displaying > 1 line.
556 // So, we need to adjust the height of the toolbox accordingly. If we don't
557 // then the largest item ( e.g. the GroupBar window ) will actually be
558 // positioned such that the toolbar will cut off the bottom of that item
559 if ( pGroupBar
->GetNumLines() > 1 )
560 aSize
.Height() += pGroupBar
->GetVertOffset() + ADDITIONAL_SPACE
;
567 long nWidth
= GetSizePixel().Width();
568 long nLeft
= aTextWindow
.GetPosPixel().X();
569 Size aSize
= aTextWindow
.GetSizePixel();
571 aSize
.Width() = std::max( ((long)(nWidth
- nLeft
- 5)), (long)0 );
573 aTextWindow
.SetSizePixel( aSize
);
574 aTextWindow
.Invalidate();
578 void ScInputWindow::SetFuncString( const OUString
& rString
, sal_Bool bDoEdit
)
580 //! new method at ScModule to query if function autopilot is open
581 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
582 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
583 aTextWindow
.StartEditEngine();
585 ScModule
* pScMod
= SC_MOD();
586 if ( pScMod
->IsEditMode() )
589 aTextWindow
.GrabFocus();
590 aTextWindow
.SetTextString( rString
);
591 EditView
* pView
= aTextWindow
.GetEditView();
594 sal_Int32 nLen
= rString
.getLength();
599 pView
->SetSelection( ESelection( 0, nLen
, 0, nLen
) );
602 pScMod
->InputChanged(pView
);
604 SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel
606 pView
->SetEditEngineUpdateMode(sal_True
);
611 void ScInputWindow::SetPosString( const OUString
& rStr
)
613 aWndPos
.SetPos( rStr
);
616 void ScInputWindow::SetTextString( const OUString
& rString
)
618 if (rString
.getLength() <= 32767)
619 aTextWindow
.SetTextString(rString
);
621 aTextWindow
.SetTextString(rString
.copy(0, 32767));
624 void ScInputWindow::SetOkCancelMode()
626 //! new method at ScModule to query if function autopilot is open
627 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
628 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
630 ScModule
* pScMod
= SC_MOD();
631 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
632 if (!bIsOkCancelMode
)
634 RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
636 InsertItem( SID_INPUT_CANCEL
, IMAGE( SID_INPUT_CANCEL
), 0, 3 );
637 InsertItem( SID_INPUT_OK
, IMAGE( SID_INPUT_OK
), 0, 4 );
638 SetItemText ( SID_INPUT_CANCEL
, aTextCancel
);
639 SetHelpId ( SID_INPUT_CANCEL
, HID_INSWIN_CANCEL
);
640 SetItemText ( SID_INPUT_OK
, aTextOk
);
641 SetHelpId ( SID_INPUT_OK
, HID_INSWIN_OK
);
642 bIsOkCancelMode
= sal_True
;
646 void ScInputWindow::SetSumAssignMode()
648 //! new method at ScModule to query if function autopilot is open
649 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
650 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
652 ScModule
* pScMod
= SC_MOD();
653 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
656 // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
659 InsertItem( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
), 0, 3 );
660 InsertItem( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
), 0, 4 );
661 SetItemText ( SID_INPUT_SUM
, aTextSum
);
662 SetHelpId ( SID_INPUT_SUM
, HID_INSWIN_SUMME
);
663 SetItemText ( SID_INPUT_EQUAL
, aTextEqual
);
664 SetHelpId ( SID_INPUT_EQUAL
, HID_INSWIN_FUNC
);
665 bIsOkCancelMode
= false;
667 SetFormulaMode(false); // kein editieren -> keine Formel
671 void ScInputWindow::SetFormulaMode( sal_Bool bSet
)
673 aWndPos
.SetFormulaMode(bSet
);
674 aTextWindow
.SetFormulaMode(bSet
);
677 void ScInputWindow::SetText( const OUString
& rString
)
679 ToolBox::SetText(rString
);
682 OUString
ScInputWindow::GetText() const
684 return ToolBox::GetText();
687 sal_Bool
ScInputWindow::IsInputActive()
689 return aTextWindow
.IsInputActive();
692 EditView
* ScInputWindow::GetEditView()
694 return aTextWindow
.GetEditView();
697 void ScInputWindow::MakeDialogEditView()
699 aTextWindow
.MakeDialogEditView();
702 void ScInputWindow::StopEditEngine( sal_Bool bAll
)
704 aTextWindow
.StopEditEngine( bAll
);
707 void ScInputWindow::TextGrabFocus()
709 aTextWindow
.TextGrabFocus();
712 void ScInputWindow::TextInvalidate()
714 aTextWindow
.Invalidate();
717 void ScInputWindow::SwitchToTextWin()
719 // used for shift-ctrl-F2
721 aTextWindow
.StartEditEngine();
722 if ( SC_MOD()->IsEditMode() )
724 aTextWindow
.TextGrabFocus();
725 EditView
* pView
= aTextWindow
.GetEditView();
728 sal_Int32 nPara
= pView
->GetEditEngine()->GetParagraphCount() ? ( pView
->GetEditEngine()->GetParagraphCount() - 1 ) : 0;
729 xub_StrLen nLen
= pView
->GetEditEngine()->GetTextLen( nPara
);
730 ESelection
aSel( nPara
, nLen
, nPara
, nLen
);
731 pView
->SetSelection( aSel
); // set cursor to end of text
736 void ScInputWindow::PosGrabFocus()
741 void ScInputWindow::EnableButtons( sal_Bool bEnable
)
743 // when enabling buttons, always also enable the input window itself
744 if ( bEnable
&& !IsEnabled() )
747 EnableItem( SID_INPUT_FUNCTION
, bEnable
);
748 EnableItem( bIsOkCancelMode
? SID_INPUT_CANCEL
: SID_INPUT_SUM
, bEnable
);
749 EnableItem( bIsOkCancelMode
? SID_INPUT_OK
: SID_INPUT_EQUAL
, bEnable
);
753 void ScInputWindow::StateChanged( StateChangedType nType
)
755 ToolBox::StateChanged( nType
);
757 if ( nType
== STATE_CHANGE_INITSHOW
) Resize();
760 void ScInputWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
762 if ( rDCEvt
.GetType() == DATACHANGED_SETTINGS
&& (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
764 // update item images
765 ScModule
* pScMod
= SC_MOD();
766 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
767 // IMAGE macro uses pScMod, pImgMg
769 SetItemImage( SID_INPUT_FUNCTION
, IMAGE( SID_INPUT_FUNCTION
) );
770 if ( bIsOkCancelMode
)
772 SetItemImage( SID_INPUT_CANCEL
, IMAGE( SID_INPUT_CANCEL
) );
773 SetItemImage( SID_INPUT_OK
, IMAGE( SID_INPUT_OK
) );
777 SetItemImage( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
) );
778 SetItemImage( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
) );
782 ToolBox::DataChanged( rDCEvt
);
785 bool ScInputWindow::IsPointerAtResizePos()
787 if ( GetOutputSizePixel().Height() - GetPointerPosPixel().Y() <= 4 )
793 void ScInputWindow::MouseMove( const MouseEvent
& rMEvt
)
797 Point aPosPixel
= GetPointerPosPixel();
799 ScInputBarGroup
* pGroupBar
= dynamic_cast< ScInputBarGroup
* > ( pRuntimeWindow
.get() );
801 if ( bInResize
|| IsPointerAtResizePos() )
802 SetPointer( Pointer( POINTER_WINDOW_SSIZE
) );
804 SetPointer( Pointer( POINTER_ARROW
) );
809 long nResizeThreshold
= ( (long)TBX_WINDOW_HEIGHT
* 0.7 );
810 bool bResetPointerPos
= false;
812 // Detect attempt to expand toolbar too much
813 if ( aPosPixel
.Y() >= mnMaxY
)
815 bResetPointerPos
= true;
816 aPosPixel
.Y() = mnMaxY
;
817 } // or expanding down
818 else if ( GetOutputSizePixel().Height() - aPosPixel
.Y() < -nResizeThreshold
)
820 pGroupBar
->IncrementVerticalSize();
821 bResetPointerPos
= true;
823 else if ( ( GetOutputSizePixel().Height() - aPosPixel
.Y() ) > nResizeThreshold
)
825 bResetPointerPos
= true;
826 pGroupBar
->DecrementVerticalSize();
829 if ( bResetPointerPos
)
831 aPosPixel
.Y() = GetOutputSizePixel().Height();
832 SetPointerPosPixel( aPosPixel
);
836 ToolBox::MouseMove( rMEvt
);
839 void ScInputWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
843 if ( rMEvt
.IsLeft() )
845 if ( IsPointerAtResizePos() )
847 // Don't leave the mouse pointer leave *this* window
850 // find the height of the gridwin, we don't wan't to be
851 // able to expand the toolbar too far so we need to
852 // caculate an upper limit
853 // I'd prefer to leave at least a single column header and a
854 // row but I don't know how to get that value in pixels.
855 // Use TBX_WINDOW_HEIGHT for the moment
856 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
857 mnMaxY
= GetOutputSizePixel().Height() + ( pViewSh
->GetGridHeight(SC_SPLIT_TOP
) + pViewSh
->GetGridHeight(SC_SPLIT_BOTTOM
) ) - TBX_WINDOW_HEIGHT
;
861 ToolBox::MouseButtonDown( rMEvt
);
863 void ScInputWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
868 if ( rMEvt
.IsLeft() )
874 ToolBox::MouseButtonUp( rMEvt
);
878 //========================================================================
880 //========================================================================
882 ScInputBarGroup::ScInputBarGroup(Window
* pParent
, ScTabViewShell
* pViewSh
)
883 : ScTextWndBase ( pParent
, WinBits(WB_HIDE
| WB_TABSTOP
) ),
884 aMultiTextWnd ( this, pViewSh
),
885 aButton ( this, WB_TABSTOP
| WB_RECTSTYLE
| WB_SMALLSTYLE
),
886 aScrollBar ( this, WB_TABSTOP
| WB_VERT
| WB_DRAG
),
889 aMultiTextWnd
.Show();
890 aMultiTextWnd
.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND
) );
891 aMultiTextWnd
.SetHelpId( HID_INSWIN_INPUT
);
893 Size
aSize( GetSettings().GetStyleSettings().GetScrollBarSize(), aMultiTextWnd
.GetPixelHeightForLines(1) );
895 aButton
.SetClickHdl( LINK( this, ScInputBarGroup
, ClickHdl
) );
896 aButton
.SetSizePixel( aSize
);
898 aButton
.SetSymbol( SYMBOL_SPIN_DOWN
);
899 aButton
.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA
) );
902 aScrollBar
.SetSizePixel( aSize
);
903 aScrollBar
.SetScrollHdl( LINK( this, ScInputBarGroup
, Impl_ScrollHdl
) );
906 ScInputBarGroup::~ScInputBarGroup()
912 ScInputBarGroup::InsertAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
914 aMultiTextWnd
.InsertAccessibleTextData( rTextData
);
918 ScInputBarGroup::RemoveAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
920 aMultiTextWnd
.RemoveAccessibleTextData( rTextData
);
924 ScInputBarGroup::GetTextString() const
926 return aMultiTextWnd
.GetTextString();
929 void ScInputBarGroup::SetTextString( const OUString
& rString
)
931 aMultiTextWnd
.SetTextString(rString
);
934 void ScInputBarGroup::Resize()
936 Window
*w
=GetParent();
937 ScInputWindow
*pParent
;
938 pParent
=dynamic_cast<ScInputWindow
*>(w
);
942 OSL_FAIL("The parent window pointer pParent is null");
946 long nWidth
= pParent
->GetSizePixel().Width();
947 long nLeft
= GetPosPixel().X();
949 Size aSize
= GetSizePixel();
950 aSize
.Width() = std::max( ((long)(nWidth
- nLeft
- LEFT_OFFSET
)), (long)0 );
952 aScrollBar
.SetPosPixel(Point( aSize
.Width() - aButton
.GetSizePixel().Width(), aButton
.GetSizePixel().Height() ) );
954 Size
aTmpSize( aSize
);
955 aTmpSize
.Width() = aTmpSize
.Width() - aButton
.GetSizePixel().Width() - BUTTON_OFFSET
;
956 aMultiTextWnd
.SetSizePixel(aTmpSize
);
958 aMultiTextWnd
.Resize();
960 aSize
.Height() = aMultiTextWnd
.GetSizePixel().Height();
964 if( aMultiTextWnd
.GetNumLines() > 1 )
966 aButton
.SetSymbol( SYMBOL_SPIN_UP
);
967 aButton
.SetQuickHelpText( ScResId( SCSTR_QHELP_COLLAPSE_FORMULA
) );
968 Size scrollSize
= aButton
.GetSizePixel();
969 scrollSize
.Height() = aMultiTextWnd
.GetSizePixel().Height() - aButton
.GetSizePixel().Height();
970 aScrollBar
.SetSizePixel( scrollSize
);
972 Size aOutSz
= aMultiTextWnd
.GetOutputSize();
974 aScrollBar
.SetVisibleSize( aOutSz
.Height() );
975 aScrollBar
.SetPageSize( aOutSz
.Height() );
976 aScrollBar
.SetLineSize( aMultiTextWnd
.GetTextHeight() );
977 aScrollBar
.SetRange( Range( 0, aMultiTextWnd
.GetEditEngTxtHeight() ) );
984 aButton
.SetSymbol( SYMBOL_SPIN_DOWN
);
985 aButton
.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA
) );
989 aButton
.SetPosPixel(Point(aSize
.Width() - aButton
.GetSizePixel().Width(), 0));
994 void ScInputBarGroup::StopEditEngine( sal_Bool bAll
)
996 aMultiTextWnd
.StopEditEngine( bAll
);
999 void ScInputBarGroup::StartEditEngine()
1001 aMultiTextWnd
.StartEditEngine();
1005 void ScInputBarGroup::MakeDialogEditView()
1007 aMultiTextWnd
.MakeDialogEditView();
1011 EditView
* ScInputBarGroup::GetEditView()
1013 return aMultiTextWnd
.GetEditView();
1016 sal_Bool
ScInputBarGroup::IsInputActive()
1018 return aMultiTextWnd
.IsInputActive();
1021 void ScInputBarGroup::SetFormulaMode(sal_Bool bSet
)
1023 aMultiTextWnd
.SetFormulaMode(bSet
);
1026 void ScInputBarGroup::IncrementVerticalSize()
1028 aMultiTextWnd
.SetNumLines( aMultiTextWnd
.GetNumLines() + 1 );
1029 TriggerToolboxLayout();
1032 void ScInputBarGroup::DecrementVerticalSize()
1034 if ( aMultiTextWnd
.GetNumLines() > 1 )
1036 aMultiTextWnd
.SetNumLines( aMultiTextWnd
.GetNumLines() - 1 );
1037 TriggerToolboxLayout();
1041 IMPL_LINK_NOARG(ScInputBarGroup
, ClickHdl
)
1043 Window
*w
=GetParent();
1044 ScInputWindow
*pParent
;
1045 pParent
=dynamic_cast<ScInputWindow
*>(w
);
1049 OSL_FAIL("The parent window pointer pParent is null");
1052 if( aMultiTextWnd
.GetNumLines() > 1 )
1054 aMultiTextWnd
.SetNumLines( 1 );
1058 aMultiTextWnd
.SetNumLines( aMultiTextWnd
.GetLastNumExpandedLines() );
1060 TriggerToolboxLayout();
1061 // Restore focus to input line(s) if necessary
1062 if ( SC_MOD()->GetInputHdl()->IsTopMode() )
1063 aMultiTextWnd
.GrabFocus();
1067 void ScInputBarGroup::TriggerToolboxLayout()
1069 Window
*w
=GetParent();
1070 ScInputWindow
*pParent
;
1071 pParent
=dynamic_cast<ScInputWindow
*>(w
);
1072 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1074 // Capture the vertical position of this window in the toolbar, when we increase
1075 // the size of the toolbar to accomadate expanded line input we need to take this
1078 nVertOffset
= pParent
->GetItemPosRect( pParent
->GetItemCount() - 1 ).Top();
1082 Reference
< com::sun::star::beans::XPropertySet
> xPropSet( pViewFrm
->GetFrame().GetFrameInterface(), UNO_QUERY
);
1083 Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1085 if ( xPropSet
.is() )
1087 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1088 aValue
>>= xLayoutManager
;
1091 if ( xLayoutManager
.is() )
1093 if ( aMultiTextWnd
.GetNumLines() > 1)
1094 pParent
->SetToolbarLayoutMode( TBX_LAYOUT_LOCKVERT
);
1096 pParent
->SetToolbarLayoutMode( TBX_LAYOUT_NORMAL
);
1097 xLayoutManager
->lock();
1098 DataChangedEvent
aFakeUpdate( DATACHANGED_SETTINGS
, NULL
, SETTINGS_STYLE
);
1099 // this basically will trigger the reposititioning of the
1100 // items in the toolbar from ImplFormat ( which is controlled by
1101 // mnWinHeight ) which in turn is updated in ImplCalcItem which is
1102 // controlled by mbCalc. Additionally the ImplFormat above is
1103 // controlled via mbFormat. It seems the easiest way to get these
1104 // booleans set is to send in the fake event below.
1105 pParent
->DataChanged( aFakeUpdate
);
1106 // highest item in toolbar will have been calculated via the
1107 // event above. Call resize on InputBar to pick up the height
1110 // unlock relayouts the toolbars in the 4 quadrants
1111 xLayoutManager
->unlock();
1116 IMPL_LINK_NOARG(ScInputBarGroup
, Impl_ScrollHdl
)
1118 aMultiTextWnd
.DoScroll();
1122 void ScInputBarGroup::TextGrabFocus()
1124 aMultiTextWnd
.TextGrabFocus();
1127 //========================================================================
1129 //========================================================================
1131 ScMultiTextWnd::ScMultiTextWnd( ScInputBarGroup
* pParen
, ScTabViewShell
* pViewSh
)
1133 ScTextWnd( pParen
, pViewSh
),
1134 mrGroupBar(* pParen
),
1136 mnLastExpandedLines( INPUTWIN_MULTILINES
),
1137 mbInvalidate( false )
1140 aBorder
= CalcWindowSize( aBorder
);
1141 mnBorderHeight
= aBorder
.Height();
1144 ScMultiTextWnd::~ScMultiTextWnd()
1148 void ScMultiTextWnd::Paint( const Rectangle
& rRect
)
1150 EditView
* pView
= GetEditView();
1155 pView
->Invalidate();
1156 mbInvalidate
= false;
1158 pEditView
->Paint( rRect
);
1162 EditView
* ScMultiTextWnd::GetEditView()
1169 long ScMultiTextWnd::GetPixelHeightForLines( long nLines
)
1171 // add padding ( for the borders of the window )
1172 return ( nLines
* LogicToPixel( Size( 0, GetTextHeight() ) ).Height() ) + mnBorderHeight
;
1175 void ScMultiTextWnd::SetNumLines( long nLines
)
1180 mnLastExpandedLines
= nLines
;
1185 void ScMultiTextWnd::Resize()
1187 // Only Height is recalculated here, Width is applied from
1188 // parent/container window
1189 Size aTextBoxSize
= GetSizePixel();
1191 aTextBoxSize
.Height() = GetPixelHeightForLines( mnLines
);
1192 SetSizePixel( aTextBoxSize
);
1196 Size aOutputSize
= GetOutputSizePixel();
1197 Rectangle aOutputArea
= PixelToLogic( Rectangle( Point(), aOutputSize
));
1198 pEditView
->SetOutputArea( aOutputArea
);
1200 // Don't leave an empty area at the bottom if we can move the text down.
1201 long nMaxVisAreaTop
= pEditEngine
->GetTextHeight() - aOutputArea
.GetHeight();
1202 if (pEditView
->GetVisArea().Top() > nMaxVisAreaTop
)
1204 pEditView
->Scroll(0, pEditView
->GetVisArea().Top() - nMaxVisAreaTop
);
1207 pEditEngine
->SetPaperSize( PixelToLogic( Size( aOutputSize
.Width(), 10000 ) ) );
1210 SetScrollBarRange();
1213 IMPL_LINK(ScMultiTextWnd
, ModifyHdl
, EENotify
*, pNotify
)
1215 ScTextWnd::NotifyHdl( pNotify
);
1219 IMPL_LINK(ScMultiTextWnd
, NotifyHdl
, EENotify
*, pNotify
)
1221 // need to process EE_NOTIFY_TEXTVIEWSCROLLED here
1222 // sometimes we don't seem to get EE_NOTIFY_TEXTVIEWSCROLLED e.g. when
1223 // we insert text at the beginning of the text so the cursor never moves
1224 // down to generate a scroll event
1226 if ( pNotify
&& ( pNotify
->eNotificationType
== EE_NOTIFY_TEXTVIEWSCROLLED
1227 || pNotify
->eNotificationType
== EE_NOTIFY_TEXTHEIGHTCHANGED
) )
1228 SetScrollBarRange();
1232 long ScMultiTextWnd::GetEditEngTxtHeight()
1234 return pEditView
? pEditView
->GetEditEngine()->GetTextHeight() : 0;
1237 void ScMultiTextWnd::SetScrollBarRange()
1241 ScrollBar
& rVBar
= mrGroupBar
.GetScrollBar();
1242 rVBar
.SetRange( Range( 0, GetEditEngTxtHeight() ) );
1243 long currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1244 rVBar
.SetThumbPos( currentDocPos
);
1249 ScMultiTextWnd::DoScroll()
1253 ScrollBar
& rVBar
= mrGroupBar
.GetScrollBar();
1254 long currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1255 long nDiff
= currentDocPos
- rVBar
.GetThumbPos();
1256 pEditView
->Scroll( 0, nDiff
);
1257 currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1258 rVBar
.SetThumbPos( currentDocPos
);
1262 void ScMultiTextWnd::StartEditEngine()
1264 // Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1265 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1266 if ( pObjSh
&& pObjSh
->IsInModalMode() )
1269 if ( !pEditView
|| !pEditEngine
)
1274 SC_MOD()->SetInputMode( SC_INPUT_TOP
);
1276 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1278 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1281 static void lcl_ExtendEditFontAttribs( SfxItemSet
& rSet
)
1283 const SfxPoolItem
& rFontItem
= rSet
.Get( EE_CHAR_FONTINFO
);
1284 rSet
.Put( rFontItem
, EE_CHAR_FONTINFO_CJK
);
1285 rSet
.Put( rFontItem
, EE_CHAR_FONTINFO_CTL
);
1286 const SfxPoolItem
& rHeightItem
= rSet
.Get( EE_CHAR_FONTHEIGHT
);
1287 rSet
.Put( rHeightItem
, EE_CHAR_FONTHEIGHT_CJK
);
1288 rSet
.Put( rHeightItem
, EE_CHAR_FONTHEIGHT_CTL
);
1289 const SfxPoolItem
& rWeightItem
= rSet
.Get( EE_CHAR_WEIGHT
);
1290 rSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CJK
);
1291 rSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CTL
);
1292 const SfxPoolItem
& rItalicItem
= rSet
.Get( EE_CHAR_ITALIC
);
1293 rSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CJK
);
1294 rSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CTL
);
1295 const SfxPoolItem
& rLangItem
= rSet
.Get( EE_CHAR_LANGUAGE
);
1296 rSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CJK
);
1297 rSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CTL
);
1300 static void lcl_ModifyRTLDefaults( SfxItemSet
& rSet
)
1302 rSet
.Put( SvxAdjustItem( SVX_ADJUST_RIGHT
, EE_PARA_JUST
) );
1304 // always using rtl writing direction would break formulas
1305 //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1307 // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
1308 // sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be
1309 // increased to not see the beginning of the next line.
1310 SvxLineSpacingItem
aItem( SVX_LINESPACE_TWO_LINES
, EE_PARA_SBL
);
1311 aItem
.SetPropLineSpace( 200 );
1315 static void lcl_ModifyRTLVisArea( EditView
* pEditView
)
1317 Rectangle aVisArea
= pEditView
->GetVisArea();
1318 Size aPaper
= pEditView
->GetEditEngine()->GetPaperSize();
1319 long nDiff
= aPaper
.Width() - aVisArea
.Right();
1320 aVisArea
.Left() += nDiff
;
1321 aVisArea
.Right() += nDiff
;
1322 pEditView
->SetVisArea(aVisArea
);
1326 void ScMultiTextWnd::InitEditEngine()
1328 ScFieldEditEngine
* pNew
;
1329 ScTabViewShell
* pViewSh
= GetViewShell();
1330 ScDocShell
* pDocSh
= NULL
;
1333 pDocSh
= pViewSh
->GetViewData()->GetDocShell();
1334 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
1335 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1338 pNew
= new ScFieldEditEngine(NULL
, EditEngine::CreatePool(), NULL
, true);
1339 pNew
->SetExecuteURL( false );
1342 Size barSize
=GetSizePixel();
1343 pEditEngine
->SetUpdateMode( false );
1344 pEditEngine
->SetPaperSize( PixelToLogic(Size(barSize
.Width(),10000)) );
1345 pEditEngine
->SetWordDelimiters(
1346 ScEditUtil::ModifyDelimiters( pEditEngine
->GetWordDelimiters() ) );
1348 UpdateAutoCorrFlag();
1351 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1352 pEditEngine
->SetFontInfoInItemSet( *pSet
, aTextFont
);
1353 lcl_ExtendEditFontAttribs( *pSet
);
1354 // turn off script spacing to match DrawText output
1355 pSet
->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING
) );
1357 lcl_ModifyRTLDefaults( *pSet
);
1358 pEditEngine
->SetDefaults( pSet
);
1361 // Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1362 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1364 sal_Bool bFilled
= false;
1365 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1366 if ( pHdl
) //! Testen, ob's der richtige InputHdl ist?
1367 bFilled
= pHdl
->GetTextAndFields( *pEditEngine
);
1369 pEditEngine
->SetUpdateMode( sal_True
);
1371 // aString ist die Wahrheit...
1372 if (bFilled
&& pEditEngine
->GetText() == aString
)
1373 Invalidate(); // Repaint fuer (hinterlegte) Felder
1375 pEditEngine
->SetText(aString
); // dann wenigstens den richtigen Text
1377 pEditView
= new EditView( pEditEngine
, this );
1378 pEditView
->SetInsertMode(bIsInsertMode
);
1380 // Text aus Clipboard wird als ASCII einzeilig uebernommen
1381 sal_uLong n
= pEditView
->GetControlWord();
1382 pEditView
->SetControlWord( n
| EV_CNTRL_SINGLELINEPASTE
);
1384 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1389 lcl_ModifyRTLVisArea( pEditView
);
1391 pEditEngine
->SetModifyHdl(LINK(this, ScMultiTextWnd
, ModifyHdl
));
1392 pEditEngine
->SetNotifyHdl(LINK(this, ScMultiTextWnd
, NotifyHdl
));
1394 if (!maAccTextDatas
.empty())
1395 maAccTextDatas
.back()->StartEdit();
1397 // as long as EditEngine and DrawText sometimes differ for CTL text,
1398 // repaint now to have the EditEngine's version visible
1401 ScDocument
* pDoc
= pDocSh
->GetDocument(); // any document
1402 sal_uInt8 nScript
= pDoc
->GetStringScriptType( aString
);
1403 if ( nScript
& SCRIPTTYPE_COMPLEX
)
1408 void ScMultiTextWnd::StopEditEngine( sal_Bool bAll
)
1411 pEditEngine
->SetNotifyHdl(Link());
1412 ScTextWnd::StopEditEngine( bAll
);
1415 void ScMultiTextWnd::SetTextString( const OUString
& rNewString
)
1417 // Ideally it would be best to create on demand the EditEngine/EditView here, but... for
1418 // the initialisation scenario where a cell is first clicked on we end up with the text in the
1419 // inputbar window scrolled to the bottom if we do that here ( because the tableview and topview
1420 // are synced I guess ).
1421 // should fix that I suppose :-/ need to look a bit further into that
1422 mbInvalidate
= true; // ensure next Paint ( that uses editengine ) call will call Invalidate first
1423 ScTextWnd::SetTextString( rNewString
);
1424 SetScrollBarRange();
1427 //========================================================================
1429 //========================================================================
1431 ScTextWnd::ScTextWnd( Window
* pParent
, ScTabViewShell
* pViewSh
)
1432 : ScTextWndBase ( pParent
, WinBits(WB_HIDE
| WB_BORDER
) ),
1433 DragSourceHelper( this ),
1434 pEditEngine ( NULL
),
1436 bIsInsertMode( sal_True
),
1437 bFormulaMode ( false ),
1438 bInputMode ( false ),
1439 mpViewShell(pViewSh
)
1441 EnableRTL( false ); // EditEngine can't be used with VCL EnableRTL
1443 bIsRTL
= GetSettings().GetLayoutRTL();
1445 // always use application font, so a font with cjk chars can be installed
1446 Font aAppFont
= GetFont();
1447 aTextFont
= aAppFont
;
1448 aTextFont
.SetSize( PixelToLogic( aAppFont
.GetSize(), MAP_TWIP
) ); // AppFont ist in Pixeln
1450 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1452 Color aBgColor
= rStyleSettings
.GetWindowColor();
1453 Color aTxtColor
= rStyleSettings
.GetWindowTextColor();
1455 aTextFont
.SetTransparent ( sal_True
);
1456 aTextFont
.SetFillColor ( aBgColor
);
1457 //aTextFont.SetColor ( COL_FIELDTEXT );
1458 aTextFont
.SetColor (aTxtColor
);
1459 aTextFont
.SetWeight ( WEIGHT_NORMAL
);
1461 Size
aSize(1,TBX_WINDOW_HEIGHT
);
1462 Size
aMinEditSize( Edit::GetMinimumEditSize() );
1463 if( aMinEditSize
.Height() > aSize
.Height() )
1464 aSize
.Height() = aMinEditSize
.Height();
1465 SetSizePixel ( aSize
);
1466 SetBackground ( aBgColor
);
1467 SetLineColor ( COL_BLACK
);
1468 SetMapMode ( MAP_TWIP
);
1469 SetPointer ( POINTER_TEXT
);
1470 SetFont( aTextFont
);
1473 ScTextWnd::~ScTextWnd()
1475 while (!maAccTextDatas
.empty()) {
1476 maAccTextDatas
.back()->Dispose();
1482 void ScTextWnd::Paint( const Rectangle
& rRect
)
1485 pEditView
->Paint( rRect
);
1488 SetFont( aTextFont
);
1490 long nDiff
= GetOutputSizePixel().Height()
1491 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
1492 // if (nDiff<2) nDiff=2; // mind. 1 Pixel
1498 nStartPos
+= GetOutputSizePixel().Width() -
1499 LogicToPixel( Size( GetTextWidth( aString
), 0 ) ).Width();
1501 // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem
1504 DrawText( PixelToLogic( Point( nStartPos
, nDiff
/2 ) ), aString
);
1508 void ScTextWnd::Resize()
1512 Size aSize
= GetOutputSizePixel();
1513 long nDiff
= aSize
.Height()
1514 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
1516 pEditView
->SetOutputArea(
1517 PixelToLogic( Rectangle( Point( 0, (nDiff
> 0) ? nDiff
/2 : 1 ),
1522 void ScTextWnd::MouseMove( const MouseEvent
& rMEvt
)
1525 pEditView
->MouseMove( rMEvt
);
1528 void ScTextWnd::MouseButtonDown( const MouseEvent
& rMEvt
)
1533 if ( SC_MOD()->IsEditMode() )
1539 pEditView
->SetEditEngineUpdateMode( sal_True
);
1540 pEditView
->MouseButtonDown( rMEvt
);
1544 void ScTextWnd::MouseButtonUp( const MouseEvent
& rMEvt
)
1547 if (pEditView
->MouseButtonUp( rMEvt
))
1549 if ( rMEvt
.IsMiddle() &&
1550 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1552 // EditView may have pasted from selection
1553 SC_MOD()->InputChanged( pEditView
);
1556 SC_MOD()->InputSelection( pEditView
);
1560 void ScTextWnd::Command( const CommandEvent
& rCEvt
)
1562 bInputMode
= sal_True
;
1563 sal_uInt16 nCommand
= rCEvt
.GetCommand();
1564 if ( pEditView
/* && nCommand == COMMAND_STARTDRAG */ )
1566 ScModule
* pScMod
= SC_MOD();
1567 ScTabViewShell
* pStartViewSh
= ScTabViewShell::GetActiveViewShell();
1569 // don't modify the font defaults here - the right defaults are
1570 // already set in StartEditEngine when the EditEngine is created
1572 // verhindern, dass die EditView beim View-Umschalten wegkommt
1573 pScMod
->SetInEditCommand( true );
1574 pEditView
->Command( rCEvt
);
1575 pScMod
->SetInEditCommand( false );
1577 // COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
1578 // darum in dem Fall kein InputChanged
1579 //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten
1581 if ( nCommand
== COMMAND_STARTDRAG
)
1583 // ist auf eine andere View gedraggt worden?
1584 ScTabViewShell
* pEndViewSh
= ScTabViewShell::GetActiveViewShell();
1585 if ( pEndViewSh
!= pStartViewSh
&& pStartViewSh
!= NULL
)
1587 ScViewData
* pViewData
= pStartViewSh
->GetViewData();
1588 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pStartViewSh
);
1589 if ( pHdl
&& pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1591 pHdl
->CancelHandler();
1592 pViewData
->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv
1596 else if ( nCommand
== COMMAND_CURSORPOS
)
1598 // don't call InputChanged for COMMAND_CURSORPOS
1600 else if ( nCommand
== COMMAND_INPUTLANGUAGECHANGE
)
1602 // #i55929# Font and font size state depends on input language if nothing is selected,
1603 // so the slots have to be invalidated when the input language is changed.
1605 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1608 SfxBindings
& rBindings
= pViewFrm
->GetBindings();
1609 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
1610 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
1613 else if ( nCommand
== COMMAND_WHEEL
)
1615 //don't call InputChanged for COMMAND_WHEEL
1618 SC_MOD()->InputChanged( pEditView
);
1621 Window::Command(rCEvt
); // sonst soll sich die Basisklasse drum kuemmern...
1626 void ScTextWnd::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
1630 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, sal_True
);
1631 pEditView
->Command( aDragEvent
);
1633 // handling of d&d to different view (CancelHandler) can't be done here,
1634 // because the call returns before d&d is complete.
1638 void ScTextWnd::KeyInput(const KeyEvent
& rKEvt
)
1640 bInputMode
= sal_True
;
1641 if (!SC_MOD()->InputKeyEvent( rKEvt
))
1643 sal_Bool bUsed
= false;
1644 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1646 bUsed
= pViewSh
->SfxKeyInput(rKEvt
); // nur Acceleratoren, keine Eingabe
1648 Window::KeyInput( rKEvt
);
1653 void ScTextWnd::GetFocus()
1655 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1657 pViewSh
->SetFormShellAtTop( false ); // focus in input line -> FormShell no longer on top
1660 void ScTextWnd::LoseFocus()
1664 OUString
ScTextWnd::GetText() const
1666 // ueberladen, um per Testtool an den Text heranzukommen
1669 return pEditEngine
->GetText();
1671 return GetTextString();
1674 void ScTextWnd::SetFormulaMode( sal_Bool bSet
)
1676 if ( bSet
!= bFormulaMode
)
1678 bFormulaMode
= bSet
;
1679 UpdateAutoCorrFlag();
1683 void ScTextWnd::UpdateAutoCorrFlag()
1687 sal_uLong nControl
= pEditEngine
->GetControlWord();
1688 sal_uLong nOld
= nControl
;
1690 nControl
&= ~EE_CNTRL_AUTOCORRECT
; // keine Autokorrektur in Formeln
1692 nControl
|= EE_CNTRL_AUTOCORRECT
; // sonst schon
1693 if ( nControl
!= nOld
)
1694 pEditEngine
->SetControlWord( nControl
);
1698 ScTabViewShell
* ScTextWnd::GetViewShell()
1703 void ScTextWnd::StartEditEngine()
1705 // Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1706 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1707 if ( pObjSh
&& pObjSh
->IsInModalMode() )
1710 if ( !pEditView
|| !pEditEngine
)
1712 ScFieldEditEngine
* pNew
;
1713 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1716 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
1717 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1720 pNew
= new ScFieldEditEngine(NULL
, EditEngine::CreatePool(), NULL
, true);
1721 pNew
->SetExecuteURL( false );
1724 pEditEngine
->SetUpdateMode( false );
1725 pEditEngine
->SetPaperSize( Size( bIsRTL
? USHRT_MAX
: THESIZE
, 300 ) );
1726 pEditEngine
->SetWordDelimiters(
1727 ScEditUtil::ModifyDelimiters( pEditEngine
->GetWordDelimiters() ) );
1729 UpdateAutoCorrFlag();
1732 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1733 pEditEngine
->SetFontInfoInItemSet( *pSet
, aTextFont
);
1734 lcl_ExtendEditFontAttribs( *pSet
);
1735 // turn off script spacing to match DrawText output
1736 pSet
->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING
) );
1738 lcl_ModifyRTLDefaults( *pSet
);
1739 pEditEngine
->SetDefaults( pSet
);
1742 // Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1743 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1745 sal_Bool bFilled
= false;
1746 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1747 if ( pHdl
) //! Testen, ob's der richtige InputHdl ist?
1748 bFilled
= pHdl
->GetTextAndFields( *pEditEngine
);
1750 pEditEngine
->SetUpdateMode( sal_True
);
1752 // aString ist die Wahrheit...
1753 if (bFilled
&& pEditEngine
->GetText() == aString
)
1754 Invalidate(); // Repaint fuer (hinterlegte) Felder
1756 pEditEngine
->SetText(aString
); // dann wenigstens den richtigen Text
1758 pEditView
= new EditView( pEditEngine
, this );
1759 pEditView
->SetInsertMode(bIsInsertMode
);
1761 // Text aus Clipboard wird als ASCII einzeilig uebernommen
1762 sal_uLong n
= pEditView
->GetControlWord();
1763 pEditView
->SetControlWord( n
| EV_CNTRL_SINGLELINEPASTE
);
1765 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1770 lcl_ModifyRTLVisArea( pEditView
);
1772 pEditEngine
->SetModifyHdl(LINK(this, ScTextWnd
, NotifyHdl
));
1774 if (!maAccTextDatas
.empty())
1775 maAccTextDatas
.back()->StartEdit();
1777 // as long as EditEngine and DrawText sometimes differ for CTL text,
1778 // repaint now to have the EditEngine's version visible
1779 // SfxObjectShell* pObjSh = SfxObjectShell::Current();
1780 if ( pObjSh
&& pObjSh
->ISA(ScDocShell
) )
1782 ScDocument
* pDoc
= ((ScDocShell
*)pObjSh
)->GetDocument(); // any document
1783 sal_uInt8 nScript
= pDoc
->GetStringScriptType( aString
);
1784 if ( nScript
& SCRIPTTYPE_COMPLEX
)
1789 SC_MOD()->SetInputMode( SC_INPUT_TOP
);
1791 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1793 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1796 IMPL_LINK_NOARG(ScTextWnd
, NotifyHdl
)
1798 if (pEditView
&& !bInputMode
)
1800 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1802 // Use the InputHandler's InOwnChange flag to prevent calling InputChanged
1803 // while an InputHandler method is modifying the EditEngine content
1805 if ( pHdl
&& !pHdl
->IsInOwnChange() )
1806 pHdl
->InputChanged( pEditView
, sal_True
); // #i20282# InputChanged must know if called from modify handler
1812 void ScTextWnd::StopEditEngine( sal_Bool bAll
)
1816 if (!maAccTextDatas
.empty())
1817 maAccTextDatas
.back()->EndEdit();
1819 ScModule
* pScMod
= SC_MOD();
1822 pScMod
->InputSelection( pEditView
);
1823 aString
= pEditEngine
->GetText();
1824 bIsInsertMode
= pEditView
->IsInsertMode();
1825 sal_Bool bSelection
= pEditView
->HasSelection();
1826 pEditEngine
->SetModifyHdl(Link());
1828 DELETEZ(pEditEngine
);
1830 if ( pScMod
->IsEditMode() && !bAll
)
1831 pScMod
->SetInputMode(SC_INPUT_TABLE
);
1833 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1835 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1838 Invalidate(); // damit Selektion nicht stehenbleibt
1842 static sal_Int32
findFirstNonMatchingChar(const OUString
& rStr1
, const OUString rStr2
)
1844 // Search the string for unmatching chars
1845 const sal_Unicode
* pStr1
= rStr1
.getStr();
1846 const sal_Unicode
* pStr2
= rStr2
.getStr();
1848 while ( i
< rStr1
.getLength() )
1850 // Abort on the first unmatching char
1851 if ( *pStr1
!= *pStr2
)
1861 void ScTextWnd::SetTextString( const OUString
& rNewString
)
1863 if ( rNewString
!= aString
)
1865 bInputMode
= sal_True
;
1867 // Position der Aenderung suchen, nur Rest painten
1873 bPaintAll
= sal_True
;
1876 // test if CTL script type is involved
1877 sal_uInt8 nOldScript
= 0;
1878 sal_uInt8 nNewScript
= 0;
1879 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1880 if ( pObjSh
&& pObjSh
->ISA(ScDocShell
) )
1882 // any document can be used (used only for its break iterator)
1883 ScDocument
* pDoc
= ((ScDocShell
*)pObjSh
)->GetDocument();
1884 nOldScript
= pDoc
->GetStringScriptType( aString
);
1885 nNewScript
= pDoc
->GetStringScriptType( rNewString
);
1887 bPaintAll
= ( nOldScript
& SCRIPTTYPE_COMPLEX
) || ( nNewScript
& SCRIPTTYPE_COMPLEX
);
1892 // if CTL is involved, the whole text has to be redrawn
1899 if (rNewString
.getLength() > aString
.getLength())
1900 nDifPos
= findFirstNonMatchingChar(rNewString
, aString
);
1902 nDifPos
= findFirstNonMatchingChar(aString
, rNewString
);
1904 long nSize1
= GetTextWidth(aString
);
1905 long nSize2
= GetTextWidth(rNewString
);
1906 if ( nSize1
>0 && nSize2
>0 )
1907 nTextSize
= std::max( nSize1
, nSize2
);
1909 nTextSize
= GetOutputSize().Width(); // Ueberlauf
1911 Point aLogicStart
= PixelToLogic(Point(0,0));
1912 long nStartPos
= aLogicStart
.X();
1913 long nInvPos
= nStartPos
;
1915 nInvPos
+= GetTextWidth(aString
,0,nDifPos
);
1917 sal_uInt16 nFlags
= 0;
1918 if ( nDifPos
== aString
.getLength() ) // only new characters appended
1919 nFlags
= INVALIDATE_NOERASE
; // then background is already clear
1920 Invalidate( Rectangle( nInvPos
, 0,
1921 nStartPos
+nTextSize
, GetOutputSize().Height()-1 ),
1927 pEditEngine
->SetText(rNewString
);
1930 aString
= rNewString
;
1932 if (!maAccTextDatas
.empty())
1933 maAccTextDatas
.back()->TextChanged();
1939 const OUString
& ScTextWnd::GetTextString() const
1944 sal_Bool
ScTextWnd::IsInputActive()
1949 EditView
* ScTextWnd::GetEditView()
1954 void ScTextWnd::MakeDialogEditView()
1956 if ( pEditView
) return;
1958 ScFieldEditEngine
* pNew
;
1959 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1962 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
1963 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1966 pNew
= new ScFieldEditEngine(NULL
, EditEngine::CreatePool(), NULL
, true);
1967 pNew
->SetExecuteURL( false );
1970 pEditEngine
->SetUpdateMode( false );
1971 pEditEngine
->SetWordDelimiters( pEditEngine
->GetWordDelimiters() + "=" );
1972 pEditEngine
->SetPaperSize( Size( bIsRTL
? USHRT_MAX
: THESIZE
, 300 ) );
1974 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1975 pEditEngine
->SetFontInfoInItemSet( *pSet
, aTextFont
);
1976 lcl_ExtendEditFontAttribs( *pSet
);
1978 lcl_ModifyRTLDefaults( *pSet
);
1979 pEditEngine
->SetDefaults( pSet
);
1980 pEditEngine
->SetUpdateMode( sal_True
);
1982 pEditView
= new EditView( pEditEngine
, this );
1983 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1988 lcl_ModifyRTLVisArea( pEditView
);
1990 if (!maAccTextDatas
.empty())
1991 maAccTextDatas
.back()->StartEdit();
1994 void ScTextWnd::ImplInitSettings()
1996 bIsRTL
= GetSettings().GetLayoutRTL();
1998 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2000 Color aBgColor
= rStyleSettings
.GetWindowColor();
2001 Color aTxtColor
= rStyleSettings
.GetWindowTextColor();
2003 aTextFont
.SetFillColor ( aBgColor
);
2004 aTextFont
.SetColor (aTxtColor
);
2005 SetBackground ( aBgColor
);
2009 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> ScTextWnd::CreateAccessible()
2011 return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL
, this,
2012 OUString(ScResId(STR_ACC_EDITLINE_NAME
)),
2013 OUString(ScResId(STR_ACC_EDITLINE_DESCR
)), ScAccessibleEditObject::EditLine
);
2016 void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
2018 OSL_ENSURE( ::std::find( maAccTextDatas
.begin(), maAccTextDatas
.end(), &rTextData
) == maAccTextDatas
.end(),
2019 "ScTextWnd::InsertAccessibleTextData - passed object already registered" );
2020 maAccTextDatas
.push_back( &rTextData
);
2023 void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
2025 AccTextDataVector::iterator aEnd
= maAccTextDatas
.end();
2026 AccTextDataVector::iterator aIt
= ::std::find( maAccTextDatas
.begin(), aEnd
, &rTextData
);
2027 OSL_ENSURE( aIt
!= aEnd
, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
2029 maAccTextDatas
.erase( aIt
);
2032 // -----------------------------------------------------------------------
2034 void ScTextWnd::DataChanged( const DataChangedEvent
& rDCEvt
)
2036 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
2037 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
2043 Window::DataChanged( rDCEvt
);
2046 void ScTextWnd::TextGrabFocus()
2051 //========================================================================
2053 //========================================================================
2055 ScPosWnd::ScPosWnd( Window
* pParent
) :
2056 ComboBox ( pParent
, WinBits(WB_HIDE
| WB_DROPDOWN
) ),
2059 bFormulaMode( false )
2061 Size
aSize( GetTextWidth( OUString("GW99999:GW99999") ),
2063 aSize
.Width() += 25; // ??
2064 aSize
.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..."
2065 SetSizePixel( aSize
);
2069 StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates
2072 ScPosWnd::~ScPosWnd()
2074 EndListening( *SFX_APP() );
2081 void ScPosWnd::SetFormulaMode( sal_Bool bSet
)
2083 if ( bSet
!= bFormulaMode
)
2085 bFormulaMode
= bSet
;
2096 void ScPosWnd::SetPos( const OUString
& rPosStr
)
2098 if ( aPosStr
!= rPosStr
)
2107 OUString
createLocalRangeName(const OUString
& rName
, const OUString
& rTableName
)
2109 OUStringBuffer
aString (rName
);
2110 aString
.append(OUString(" ("));
2111 aString
.append(rTableName
);
2112 aString
.append(OUString(")"));
2113 return aString
.makeStringAndClear();
2118 void ScPosWnd::FillRangeNames()
2122 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
2123 if ( pObjSh
&& pObjSh
->ISA(ScDocShell
) )
2125 ScDocument
* pDoc
= ((ScDocShell
*)pObjSh
)->GetDocument();
2127 InsertEntry(ScGlobal::GetRscString( STR_MANAGE_NAMES
));
2131 std::set
<OUString
> aSet
;
2132 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
2133 if (!pRangeNames
->empty())
2135 ScRangeName::const_iterator itrBeg
= pRangeNames
->begin(), itrEnd
= pRangeNames
->end();
2136 for (ScRangeName::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
2138 if (itr
->second
->IsValidReference(aDummy
))
2139 aSet
.insert(itr
->second
->GetName());
2142 for (SCTAB i
= 0; i
< pDoc
->GetTableCount(); ++i
)
2144 ScRangeName
* pLocalRangeName
= pDoc
->GetRangeName(i
);
2145 if (pLocalRangeName
&& !pLocalRangeName
->empty())
2147 OUString aTableName
;
2148 pDoc
->GetName(i
, aTableName
);
2149 for (ScRangeName::const_iterator itr
= pLocalRangeName
->begin(); itr
!= pLocalRangeName
->end(); ++itr
)
2151 if (itr
->second
->IsValidReference(aDummy
))
2152 aSet
.insert(createLocalRangeName(itr
->second
->GetName(), aTableName
));
2159 for (std::set
<OUString
>::iterator itr
= aSet
.begin();
2160 itr
!= aSet
.end(); ++itr
)
2169 void ScPosWnd::FillFunctions()
2173 OUString aFirstName
;
2174 const ScAppOptions
& rOpt
= SC_MOD()->GetAppOptions();
2175 sal_uInt16 nMRUCount
= rOpt
.GetLRUFuncListCount();
2176 const sal_uInt16
* pMRUList
= rOpt
.GetLRUFuncList();
2179 const ScFunctionList
* pFuncList
= ScGlobal::GetStarCalcFunctionList();
2180 sal_uLong nListCount
= pFuncList
->GetCount();
2181 for (sal_uInt16 i
=0; i
<nMRUCount
; i
++)
2183 sal_uInt16 nId
= pMRUList
[i
];
2184 for (sal_uLong j
=0; j
<nListCount
; j
++)
2186 const ScFuncDesc
* pDesc
= pFuncList
->GetFunction( j
);
2187 if ( pDesc
->nFIndex
== nId
&& pDesc
->pFuncName
)
2189 InsertEntry( *pDesc
->pFuncName
);
2190 if (aFirstName
.isEmpty())
2191 aFirstName
= *pDesc
->pFuncName
;
2192 break; // nicht weitersuchen
2198 //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
2199 //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!
2201 // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
2203 SetText(aFirstName
);
2206 void ScPosWnd::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
2208 if ( !bFormulaMode
)
2210 // muss die Liste der Bereichsnamen updgedated werden?
2212 if ( rHint
.ISA(SfxSimpleHint
) )
2214 sal_uLong nHintId
= ((SfxSimpleHint
&)rHint
).GetId();
2215 if ( nHintId
== SC_HINT_AREAS_CHANGED
|| nHintId
== SC_HINT_NAVIGATOR_UPDATEALL
)
2218 else if ( rHint
.ISA(SfxEventHint
) )
2220 sal_uLong nEventId
= ((SfxEventHint
&)rHint
).GetEventId();
2221 if ( nEventId
== SFX_EVENT_ACTIVATEDOC
)
2227 void ScPosWnd::HideTip()
2231 Help::HideTip( nTipVisible
);
2236 static ScNameInputType
lcl_GetInputType( const OUString
& rText
)
2238 ScNameInputType eRet
= SC_NAME_INPUT_BAD_NAME
; // the more general error
2240 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2243 ScViewData
* pViewData
= pViewSh
->GetViewData();
2244 ScDocument
* pDoc
= pViewData
->GetDocument();
2245 SCTAB nTab
= pViewData
->GetTabNo();
2246 formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
2248 // test in same order as in SID_CURRENTCELL execute
2252 ScRangeUtil aRangeUtil
;
2256 if (rText
== ScGlobal::GetRscString(STR_MANAGE_NAMES
))
2257 eRet
= SC_MANAGE_NAMES
;
2258 else if ( aRange
.Parse( rText
, pDoc
, eConv
) & SCA_VALID
)
2259 eRet
= SC_NAME_INPUT_RANGE
;
2260 else if ( aAddress
.Parse( rText
, pDoc
, eConv
) & SCA_VALID
)
2261 eRet
= SC_NAME_INPUT_CELL
;
2262 else if ( aRangeUtil
.MakeRangeFromName( rText
, pDoc
, nTab
, aRange
, RUTL_NAMES
, eConv
) )
2263 eRet
= SC_NAME_INPUT_NAMEDRANGE
;
2264 else if ( aRangeUtil
.MakeRangeFromName( rText
, pDoc
, nTab
, aRange
, RUTL_DBASE
, eConv
) )
2265 eRet
= SC_NAME_INPUT_DATABASE
;
2266 else if ( comphelper::string::isdigitAsciiString( rText
) &&
2267 ( nNumeric
= rText
.toInt32() ) > 0 && nNumeric
<= MAXROW
+1 )
2268 eRet
= SC_NAME_INPUT_ROW
;
2269 else if ( pDoc
->GetTable( rText
, nNameTab
) )
2270 eRet
= SC_NAME_INPUT_SHEET
;
2271 else if ( ScRangeData::IsNameValid( rText
, pDoc
) ) // nothing found, create new range?
2273 if ( pViewData
->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
2274 eRet
= SC_NAME_INPUT_DEFINE
;
2276 eRet
= SC_NAME_INPUT_BAD_SELECTION
;
2279 eRet
= SC_NAME_INPUT_BAD_NAME
;
2285 void ScPosWnd::Modify()
2291 if ( !IsTravelSelect() && !bFormulaMode
)
2293 // determine the action that would be taken for the current input
2295 ScNameInputType eType
= lcl_GetInputType( GetText() ); // uses current view
2296 sal_uInt16 nStrId
= 0;
2299 case SC_NAME_INPUT_CELL
:
2300 nStrId
= STR_NAME_INPUT_CELL
;
2302 case SC_NAME_INPUT_RANGE
:
2303 case SC_NAME_INPUT_NAMEDRANGE
:
2304 nStrId
= STR_NAME_INPUT_RANGE
; // named range or range reference
2306 case SC_NAME_INPUT_DATABASE
:
2307 nStrId
= STR_NAME_INPUT_DBRANGE
;
2309 case SC_NAME_INPUT_ROW
:
2310 nStrId
= STR_NAME_INPUT_ROW
;
2312 case SC_NAME_INPUT_SHEET
:
2313 nStrId
= STR_NAME_INPUT_SHEET
;
2315 case SC_NAME_INPUT_DEFINE
:
2316 nStrId
= STR_NAME_INPUT_DEFINE
;
2319 // other cases (error): no tip help
2325 // show the help tip at the text cursor position
2327 Window
* pWin
= GetSubEdit();
2331 Cursor
* pCur
= pWin
->GetCursor();
2333 aPos
= pWin
->LogicToPixel( pCur
->GetPos() );
2334 aPos
= pWin
->OutputToScreenPixel( aPos
);
2335 Rectangle
aRect( aPos
, aPos
);
2337 OUString aText
= ScGlobal::GetRscString( nStrId
);
2338 sal_uInt16 nAlign
= QUICKHELP_LEFT
|QUICKHELP_BOTTOM
;
2339 nTipVisible
= Help::ShowTip(pWin
, aRect
, aText
, nAlign
);
2344 void ScPosWnd::Select()
2346 ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag
2350 if (!IsTravelSelect())
2354 void ScPosWnd::DoEnter()
2356 OUString aText
= GetText();
2357 if ( !aText
.isEmpty() )
2361 ScModule
* pScMod
= SC_MOD();
2362 if ( aText
== ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE
) )
2364 // Funktions-Autopilot
2365 //! mit dem bisher eingegebenen Text weiterarbeiten !!!
2367 //! new method at ScModule to query if function autopilot is open
2368 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
2369 if ( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) )
2370 pViewFrm
->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION
,
2371 SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
);
2375 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
2376 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
2378 pHdl
->InsertFunction( aText
);
2383 // depending on the input, select something or create a new named range
2385 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2388 ScViewData
* pViewData
= pViewSh
->GetViewData();
2389 ScDocShell
* pDocShell
= pViewData
->GetDocShell();
2390 ScDocument
* pDoc
= pDocShell
->GetDocument();
2392 ScNameInputType eType
= lcl_GetInputType( aText
);
2393 if ( eType
== SC_NAME_INPUT_BAD_NAME
|| eType
== SC_NAME_INPUT_BAD_SELECTION
)
2395 sal_uInt16 nId
= ( eType
== SC_NAME_INPUT_BAD_NAME
) ? STR_NAME_ERROR_NAME
: STR_NAME_ERROR_SELECTION
;
2396 pViewSh
->ErrorMessage( nId
);
2398 else if ( eType
== SC_NAME_INPUT_DEFINE
)
2400 ScRangeName
* pNames
= pDoc
->GetRangeName();
2402 if ( pNames
&& !pNames
->findByUpperName(ScGlobal::pCharClass
->uppercase(aText
)) &&
2403 (pViewData
->GetSimpleArea( aSelection
) == SC_MARK_SIMPLE
) )
2405 ScRangeName
aNewRanges( *pNames
);
2406 ScAddress
aCursor( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
2407 OUString
aContent(aSelection
.Format(SCR_ABS_3D
, pDoc
, pDoc
->GetAddressConvention()));
2408 ScRangeData
* pNew
= new ScRangeData( pDoc
, aText
, aContent
, aCursor
);
2409 if ( aNewRanges
.insert(pNew
) )
2411 pDocShell
->GetDocFunc().ModifyRangeNames( aNewRanges
);
2412 pViewSh
->UpdateInputHandler(true);
2416 else if (eType
== SC_MANAGE_NAMES
)
2418 sal_uInt16 nId
= ScNameDlgWrapper::GetChildWindowId();
2419 SfxViewFrame
* pViewFrm
= pViewSh
->GetViewFrame();
2420 SfxChildWindow
* pWnd
= pViewFrm
->GetChildWindow( nId
);
2422 SC_MOD()->SetRefDialog( nId
, pWnd
? false : sal_True
);
2426 // for all selection types, excecute the SID_CURRENTCELL slot.
2427 if (eType
== SC_NAME_INPUT_CELL
|| eType
== SC_NAME_INPUT_RANGE
)
2429 // Note that SID_CURRENTCELL always expects address to
2430 // be in Calc A1 format. Convert the text.
2431 ScRange
aRange(0,0,pViewData
->GetTabNo());
2432 aRange
.ParseAny(aText
, pDoc
, pDoc
->GetAddressConvention());
2433 aText
= aRange
.Format(SCR_ABS_3D
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
);
2436 SfxStringItem
aPosItem( SID_CURRENTCELL
, aText
);
2437 SfxBoolItem
aUnmarkItem( FN_PARAM_1
, sal_True
); // remove existing selection
2439 pViewSh
->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL
,
2440 SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
,
2441 &aPosItem
, &aUnmarkItem
, 0L );
2449 ReleaseFocus_Impl();
2452 long ScPosWnd::Notify( NotifyEvent
& rNEvt
)
2456 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
2458 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
2460 switch ( pKEvt
->GetKeyCode().GetCode() )
2470 // escape when the tip help is shown: only hide the tip
2477 ReleaseFocus_Impl();
2485 nHandled
= ComboBox::Notify( rNEvt
);
2487 if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
2493 void ScPosWnd::ReleaseFocus_Impl()
2497 SfxViewShell
* pCurSh
= SfxViewShell::Current();
2498 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell
, pCurSh
) );
2499 if ( pHdl
&& pHdl
->IsTopMode() )
2501 // Focus wieder in die Eingabezeile?
2503 ScInputWindow
* pInputWin
= pHdl
->GetInputWindow();
2506 pInputWin
->TextGrabFocus();
2511 // Focus auf die aktive View
2515 Window
* pShellWnd
= pCurSh
->GetWindow();
2518 pShellWnd
->GrabFocus();
2527 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */