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 <vcl/settings.hxx>
43 #include <svl/stritem.hxx>
46 #include "inputwin.hxx"
48 #include "uiitems.hxx"
50 #include "scresid.hxx"
52 #include "globstr.hrc"
53 #include "reffact.hxx"
54 #include "editutil.hxx"
55 #include "inputhdl.hxx"
56 #include "tabvwsh.hxx"
57 #include "document.hxx"
59 #include "appoptio.hxx"
60 #include "rangenam.hxx"
61 #include <formula/compiler.hrc>
63 #include "rangeutl.hxx"
64 #include "docfunc.hxx"
65 #include "funcdesc.hxx"
66 #include "markdata.hxx"
67 #include <editeng/fontitem.hxx>
68 #include <com/sun/star/accessibility/XAccessible.hpp>
69 #include "AccessibleEditObject.hxx"
70 #include "AccessibleText.hxx"
71 #include <svtools/miscopt.hxx>
72 #include <comphelper/string.hxx>
73 #include <com/sun/star/frame/XLayoutManager.hpp>
74 #include <com/sun/star/frame/XModel.hpp>
75 #include <com/sun/star/frame/XController.hpp>
77 #define THESIZE 1000000 //!!! langt... :-)
78 #define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich?
80 #define INPUTWIN_MULTILINES 6
81 const long BUTTON_OFFSET
= 2; ///< space between input line and the button to expand / collapse
82 const long ADDITIONAL_BORDER
= 1; ///< height of the line at the bottom
83 const long ADDITIONAL_SPACE
= 4; ///< additional vertical space when the multiline edit has more lines
85 using com::sun::star::uno::Reference
;
86 using com::sun::star::uno::UNO_QUERY
;
88 using com::sun::star::frame::XLayoutManager
;
89 using com::sun::star::frame::XModel
;
90 using com::sun::star::frame::XFrame
;
91 using com::sun::star::frame::XController
;
92 using com::sun::star::beans::XPropertySet
;
99 SC_NAME_INPUT_NAMEDRANGE
,
100 SC_NAME_INPUT_DATABASE
,
103 SC_NAME_INPUT_DEFINE
,
104 SC_NAME_INPUT_BAD_NAME
,
105 SC_NAME_INPUT_BAD_SELECTION
,
110 ScTextWndBase::ScTextWndBase( Window
* pParent
, WinBits nStyle
)
111 : Window ( pParent
, nStyle
)
113 if ( IsNativeControlSupported( CTRL_EDITBOX
, PART_ENTIRE_CONTROL
) )
115 SetType( WINDOW_CALCINPUTLINE
);
116 SetBorderStyle( WINDOW_BORDER_NWF
);
121 // class ScInputWindowWrapper
124 SFX_IMPL_CHILDWINDOW_WITHID(ScInputWindowWrapper
,FID_INPUTLINE_STATUS
)
126 ScInputWindowWrapper::ScInputWindowWrapper( Window
* pParentP
,
128 SfxBindings
* pBindings
,
129 SfxChildWinInfo
* /* pInfo */ )
130 : SfxChildWindow( pParentP
, nId
)
132 ScInputWindow
* pWin
=new ScInputWindow( pParentP
, pBindings
);
137 pWin
->SetSizePixel( pWin
->CalcWindowSizePixel() );
139 eChildAlignment
= SFX_ALIGN_LOWESTTOP
;
140 pBindings
->Invalidate( FID_TOGGLEINPUTLINE
);
143 // GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!
145 SfxChildWinInfo
ScInputWindowWrapper::GetInfo() const
147 SfxChildWinInfo aInfo
= SfxChildWindow::GetInfo();
151 #define IMAGE(id) pImgMgr->SeekImage(id)
152 static bool lcl_isExperimentalMode()
154 // make inputbar feature on by default, leave the switch for the
155 // moment in case we need to back it out easily
160 // class ScInputWindow
163 static ScTextWndBase
* lcl_chooseRuntimeImpl( Window
* pParent
, SfxBindings
* pBind
)
165 ScTabViewShell
* pViewSh
= NULL
;
166 SfxDispatcher
* pDisp
= pBind
->GetDispatcher();
169 SfxViewFrame
* pViewFrm
= pDisp
->GetFrame();
171 pViewSh
= PTR_CAST( ScTabViewShell
, pViewFrm
->GetViewShell() );
174 if ( !lcl_isExperimentalMode() )
175 return new ScTextWnd( pParent
, pViewSh
);
176 return new ScInputBarGroup( pParent
, pViewSh
);
179 ScInputWindow::ScInputWindow( Window
* pParent
, SfxBindings
* pBind
) :
180 // mit WB_CLIPCHILDREN, sonst Flicker
181 ToolBox ( pParent
, WinBits(WB_CLIPCHILDREN
) ),
183 pRuntimeWindow ( lcl_chooseRuntimeImpl( this, pBind
) ),
184 aTextWindow ( *pRuntimeWindow
),
186 aTextOk ( ScResId( SCSTR_QHELP_BTNOK
) ), // nicht immer neu aus Resource
187 aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL
) ),
188 aTextSum ( ScResId( SCSTR_QHELP_BTNSUM
) ),
189 aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL
) ),
191 bIsOkCancelMode ( false ),
193 mbIsMultiLine ( lcl_isExperimentalMode() )
195 ScModule
* pScMod
= SC_MOD();
196 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
198 // #i73615# don't rely on SfxViewShell::Current while constructing the input line
199 // (also for GetInputHdl below)
200 ScTabViewShell
* pViewSh
= NULL
;
201 SfxDispatcher
* pDisp
= pBind
->GetDispatcher();
204 SfxViewFrame
* pViewFrm
= pDisp
->GetFrame();
206 pViewSh
= PTR_CAST( ScTabViewShell
, pViewFrm
->GetViewShell() );
208 OSL_ENSURE( pViewSh
, "no view shell for input window" );
210 // Position window, 3 buttons, input window
211 InsertWindow ( 1, &aWndPos
, 0, 0 );
212 InsertSeparator ( 1 );
213 InsertItem ( SID_INPUT_FUNCTION
, IMAGE( SID_INPUT_FUNCTION
), 0, 2 );
214 InsertItem ( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
), 0, 3 );
215 InsertItem ( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
), 0, 4 );
216 InsertSeparator ( 5 );
217 InsertWindow ( 7, &aTextWindow
, 0, 6 );
219 aWndPos
.SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND
) );
220 aWndPos
.SetHelpId ( HID_INSWIN_POS
);
221 aTextWindow
.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND
) );
222 aTextWindow
.SetHelpId ( HID_INSWIN_INPUT
);
224 // kein SetHelpText, die Hilfetexte kommen aus der Hilfe
226 SetItemText ( SID_INPUT_FUNCTION
, ScResId( SCSTR_QHELP_BTNCALC
) );
227 SetHelpId ( SID_INPUT_FUNCTION
, HID_INSWIN_CALC
);
229 SetItemText ( SID_INPUT_SUM
, aTextSum
);
230 SetHelpId ( SID_INPUT_SUM
, HID_INSWIN_SUMME
);
232 SetItemText ( SID_INPUT_EQUAL
, aTextEqual
);
233 SetHelpId ( SID_INPUT_EQUAL
, HID_INSWIN_FUNC
);
235 SetHelpId( HID_SC_INPUTWIN
); // fuer die ganze Eingabezeile
240 pInputHdl
= SC_MOD()->GetInputHdl( pViewSh
, false ); // use own handler even if ref-handler is set
242 pInputHdl
->SetInputWindow( this );
244 if (pInputHdl
&& !pInputHdl
->GetFormString().isEmpty())
246 // Umschalten waehrend der Funktionsautopilot aktiv ist
247 // -> Inhalt des Funktionsautopiloten wieder anzeigen
248 //! auch Selektion (am InputHdl gemerkt) wieder anzeigen
250 aTextWindow
.SetTextString( pInputHdl
->GetFormString() );
252 else if ( pInputHdl
&& pInputHdl
->IsInputMode() )
254 // wenn waehrend des Editierens die Eingabezeile weg war
255 // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
256 // wieder den gerade editierten Text aus dem InputHandler anzeigen
258 aTextWindow
.SetTextString( pInputHdl
->GetEditString() ); // Text anzeigen
259 if ( pInputHdl
->IsTopMode() )
260 pInputHdl
->SetMode( SC_INPUT_TABLE
); // Focus kommt eh nach unten
263 pViewSh
->UpdateInputHandler( true ); // unbedingtes Update
265 pImgMgr
->RegisterToolBox( this );
266 SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA
));
269 ScInputWindow::~ScInputWindow()
271 bool bDown
= ( ScGlobal::pSysLocale
== NULL
); // after Clear?
273 // if any view's input handler has a pointer to this input window, reset it
274 // (may be several ones, #74522#)
275 // member pInputHdl is not used here
279 TypeId aScType
= TYPE(ScTabViewShell
);
280 SfxViewShell
* pSh
= SfxViewShell::GetFirst( &aScType
);
283 ScInputHandler
* pHdl
= ((ScTabViewShell
*)pSh
)->GetInputHandler();
284 if ( pHdl
&& pHdl
->GetInputWindow() == this )
286 pHdl
->SetInputWindow( NULL
);
287 pHdl
->StopInputWinEngine( false ); // reset pTopView pointer
289 pSh
= SfxViewShell::GetNext( *pSh
, &aScType
);
293 SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
296 void ScInputWindow::SetInputHandler( ScInputHandler
* pNew
)
298 // wird im Activate der View gerufen...
300 if ( pNew
!= pInputHdl
)
302 // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
303 // geloeschten ViewShell, darum hier auf keinen Fall anfassen!
307 pInputHdl
->SetInputWindow( this );
311 bool ScInputWindow::UseSubTotal(ScRangeList
* pRangeList
) const
313 bool bSubTotal
= false;
314 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
317 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
318 size_t nRangeCount (pRangeList
->size());
319 size_t nRangeIndex (0);
320 while (!bSubTotal
&& nRangeIndex
< nRangeCount
)
322 const ScRange
* pRange
= (*pRangeList
)[nRangeIndex
];
325 SCTAB
nTabEnd(pRange
->aEnd
.Tab());
326 SCTAB
nTab(pRange
->aStart
.Tab());
327 while (!bSubTotal
&& nTab
<= nTabEnd
)
329 SCROW
nRowEnd(pRange
->aEnd
.Row());
330 SCROW
nRow(pRange
->aStart
.Row());
331 while (!bSubTotal
&& nRow
<= nRowEnd
)
333 if (pDoc
->RowFiltered(nRow
, nTab
))
344 const ScDBCollection::NamedDBs
& rDBs
= pDoc
->GetDBCollection()->getNamedDBs();
345 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
346 for (; !bSubTotal
&& itr
!= itrEnd
; ++itr
)
348 const ScDBData
& rDB
= *itr
;
349 if (!rDB
.HasAutoFilter())
353 while (!bSubTotal
&& nRangeIndex
< nRangeCount
)
355 const ScRange
* pRange
= (*pRangeList
)[nRangeIndex
];
359 rDB
.GetArea(aDBArea
);
360 if (aDBArea
.Intersects(*pRange
))
370 void ScInputWindow::Select()
372 ScModule
* pScMod
= SC_MOD();
375 switch ( GetCurItemId() )
377 case SID_INPUT_FUNCTION
:
379 //! new method at ScModule to query if function autopilot is open
380 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
381 if ( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) )
383 pViewFrm
->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION
,
384 SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
);
386 // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
387 // zu werden, egal ob's geklappt hat oder nicht
388 // SetOkCancelMode();
393 case SID_INPUT_CANCEL
:
394 pScMod
->InputCancelHandler();
399 pScMod
->InputEnterHandler();
401 aTextWindow
.Invalidate(); // sonst bleibt Selektion stehen
406 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
409 const ScMarkData
& rMark
= pViewSh
->GetViewData()->GetMarkData();
410 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
412 ScRangeList aMarkRangeList
;
413 rMark
.FillRangeListWithMarks( &aMarkRangeList
, false );
414 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
416 // check if one of the marked ranges is empty
418 const size_t nCount
= aMarkRangeList
.size();
419 for ( size_t i
= 0; i
< nCount
; ++i
)
421 const ScRange
aRange( *aMarkRangeList
[i
] );
422 if ( pDoc
->IsBlockEmpty( aRange
.aStart
.Tab(),
423 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
424 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() ) )
433 ScRangeList aRangeList
;
434 const bool bDataFound
= pViewSh
->GetAutoSumArea( aRangeList
);
437 ScAddress aAddr
= aRangeList
.back()->aEnd
;
439 const bool bSubTotal( UseSubTotal( &aRangeList
) );
440 pViewSh
->EnterAutoSum( aRangeList
, bSubTotal
, aAddr
);
445 const bool bSubTotal( UseSubTotal( &aMarkRangeList
) );
446 for ( size_t i
= 0; i
< nCount
; ++i
)
448 const ScRange
aRange( *aMarkRangeList
[i
] );
449 const bool bSetCursor
= ( i
== nCount
- 1 );
450 const bool bContinue
= ( i
!= 0 );
451 if ( !pViewSh
->AutoSum( aRange
, bSubTotal
, bSetCursor
, bContinue
) )
453 pViewSh
->MarkRange( aRange
, false, false );
454 pViewSh
->SetCursor( aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
455 const ScRangeList aRangeList
;
456 ScAddress aAddr
= aRange
.aEnd
;
458 const OUString aFormula
= pViewSh
->GetAutoSumFormula(
459 aRangeList
, bSubTotal
, aAddr
);
460 SetFuncString( aFormula
);
466 else // nur in Eingabezeile einfuegen
468 ScRangeList aRangeList
;
469 const bool bDataFound
= pViewSh
->GetAutoSumArea( aRangeList
);
470 const bool bSubTotal( UseSubTotal( &aRangeList
) );
471 ScAddress aAddr
= pViewSh
->GetViewData()->GetCurPos();
472 const OUString aFormula
= pViewSh
->GetAutoSumFormula( aRangeList
, bSubTotal
, aAddr
);
473 SetFuncString( aFormula
);
475 if ( bDataFound
&& pScMod
->IsEditMode() )
477 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
480 pHdl
->InitRangeFinder( aFormula
);
482 //! SetSelection am InputHandler ???
483 //! bSelIsRef setzen ???
484 const sal_Int32 nOpen
= aFormula
.indexOf('(');
485 const sal_Int32 nLen
= aFormula
.getLength();
486 if ( nOpen
!= -1 && nLen
> nOpen
)
491 ESelection
aSel(0,nOpen
+nAdd
,0,nLen
-1);
492 EditView
* pTableView
= pHdl
->GetTableView();
494 pTableView
->SetSelection(aSel
);
495 EditView
* pTopView
= pHdl
->GetTopView();
497 pTopView
->SetSelection(aSel
);
506 case SID_INPUT_EQUAL
:
508 aTextWindow
.StartEditEngine();
509 if ( pScMod
->IsEditMode() ) // nicht, wenn z.B. geschuetzt
511 aTextWindow
.StartEditEngine();
513 sal_Int32 nStartPos
= 1;
514 sal_Int32 nEndPos
= 1;
516 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
519 const OUString
& rString
= aTextWindow
.GetTextString();
520 const sal_Int32 nLen
= rString
.getLength();
522 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
523 CellType eCellType
= pDoc
->GetCellType( pViewSh
->GetViewData()->GetCurPos() );
529 aTextWindow
.SetTextString("=" + rString
);
532 case CELLTYPE_STRING
:
537 case CELLTYPE_FORMULA
:
541 aTextWindow
.SetTextString("=");
546 EditView
* pView
= aTextWindow
.GetEditView();
549 pView
->SetSelection( ESelection(0, nStartPos
, 0, nEndPos
) );
550 pScMod
->InputChanged(pView
);
552 pView
->SetEditEngineUpdateMode(true);
560 void ScInputWindow::Paint( const Rectangle
& rRect
)
562 ToolBox::Paint( rRect
);
564 // draw a line at the bottom to distinguish that from the grid
565 // (we have space for that thanks to ADDITIONAL_BORDER)
566 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
567 SetLineColor( rStyleSettings
.GetShadowColor() );
569 Size aSize
= GetSizePixel();
570 DrawLine( Point( 0, aSize
.Height() - 1 ), Point( aSize
.Width() - 1, aSize
.Height() - 1 ) );
573 void ScInputWindow::Resize()
578 aTextWindow
.Resize();
579 Size aSize
= GetSizePixel();
580 aSize
.Height() = CalcWindowSizePixel().Height() + ADDITIONAL_BORDER
;
581 ScInputBarGroup
* pGroupBar
= dynamic_cast< ScInputBarGroup
* > ( pRuntimeWindow
.get() );
584 // To ensure smooth display and prevent the items in the toolbar being
585 // repositioned ( vertically ) we lock the vertical positioning of the toolbox
586 // items when we are displaying > 1 line.
587 // So, we need to adjust the height of the toolbox accordingly. If we don't
588 // then the largest item ( e.g. the GroupBar window ) will actually be
589 // positioned such that the toolbar will cut off the bottom of that item
590 if ( pGroupBar
->GetNumLines() > 1 )
591 aSize
.Height() += pGroupBar
->GetVertOffset() + ADDITIONAL_SPACE
;
598 long nWidth
= GetSizePixel().Width();
599 long nLeft
= aTextWindow
.GetPosPixel().X();
600 Size aSize
= aTextWindow
.GetSizePixel();
602 aSize
.Width() = std::max( ((long)(nWidth
- nLeft
- 5)), (long)0 );
604 aTextWindow
.SetSizePixel( aSize
);
605 aTextWindow
.Invalidate();
609 void ScInputWindow::SetFuncString( const OUString
& rString
, bool bDoEdit
)
611 //! new method at ScModule to query if function autopilot is open
612 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
613 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
614 aTextWindow
.StartEditEngine();
616 ScModule
* pScMod
= SC_MOD();
617 if ( pScMod
->IsEditMode() )
620 aTextWindow
.GrabFocus();
621 aTextWindow
.SetTextString( rString
);
622 EditView
* pView
= aTextWindow
.GetEditView();
625 sal_Int32 nLen
= rString
.getLength();
630 pView
->SetSelection( ESelection( 0, nLen
, 0, nLen
) );
633 pScMod
->InputChanged(pView
);
635 SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel
637 pView
->SetEditEngineUpdateMode(true);
642 void ScInputWindow::SetPosString( const OUString
& rStr
)
644 aWndPos
.SetPos( rStr
);
647 void ScInputWindow::SetTextString( const OUString
& rString
)
649 if (rString
.getLength() <= 32767)
650 aTextWindow
.SetTextString(rString
);
652 aTextWindow
.SetTextString(rString
.copy(0, 32767));
655 void ScInputWindow::SetOkCancelMode()
657 //! new method at ScModule to query if function autopilot is open
658 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
659 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
661 ScModule
* pScMod
= SC_MOD();
662 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
663 if (!bIsOkCancelMode
)
665 RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
667 InsertItem( SID_INPUT_CANCEL
, IMAGE( SID_INPUT_CANCEL
), 0, 3 );
668 InsertItem( SID_INPUT_OK
, IMAGE( SID_INPUT_OK
), 0, 4 );
669 SetItemText ( SID_INPUT_CANCEL
, aTextCancel
);
670 SetHelpId ( SID_INPUT_CANCEL
, HID_INSWIN_CANCEL
);
671 SetItemText ( SID_INPUT_OK
, aTextOk
);
672 SetHelpId ( SID_INPUT_OK
, HID_INSWIN_OK
);
673 bIsOkCancelMode
= true;
677 void ScInputWindow::SetSumAssignMode()
679 //! new method at ScModule to query if function autopilot is open
680 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
681 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
683 ScModule
* pScMod
= SC_MOD();
684 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
687 // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
690 InsertItem( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
), 0, 3 );
691 InsertItem( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
), 0, 4 );
692 SetItemText ( SID_INPUT_SUM
, aTextSum
);
693 SetHelpId ( SID_INPUT_SUM
, HID_INSWIN_SUMME
);
694 SetItemText ( SID_INPUT_EQUAL
, aTextEqual
);
695 SetHelpId ( SID_INPUT_EQUAL
, HID_INSWIN_FUNC
);
696 bIsOkCancelMode
= false;
698 SetFormulaMode(false); // kein editieren -> keine Formel
702 void ScInputWindow::SetFormulaMode( bool bSet
)
704 aWndPos
.SetFormulaMode(bSet
);
705 aTextWindow
.SetFormulaMode(bSet
);
708 void ScInputWindow::SetText( const OUString
& rString
)
710 ToolBox::SetText(rString
);
713 OUString
ScInputWindow::GetText() const
715 return ToolBox::GetText();
718 bool ScInputWindow::IsInputActive()
720 return aTextWindow
.IsInputActive();
723 EditView
* ScInputWindow::GetEditView()
725 return aTextWindow
.GetEditView();
728 void ScInputWindow::MakeDialogEditView()
730 aTextWindow
.MakeDialogEditView();
733 void ScInputWindow::StopEditEngine( bool bAll
)
735 aTextWindow
.StopEditEngine( bAll
);
738 void ScInputWindow::TextGrabFocus()
740 aTextWindow
.TextGrabFocus();
743 void ScInputWindow::TextInvalidate()
745 aTextWindow
.Invalidate();
748 void ScInputWindow::SwitchToTextWin()
750 // used for shift-ctrl-F2
752 aTextWindow
.StartEditEngine();
753 if ( SC_MOD()->IsEditMode() )
755 aTextWindow
.TextGrabFocus();
756 EditView
* pView
= aTextWindow
.GetEditView();
759 sal_Int32 nPara
= pView
->GetEditEngine()->GetParagraphCount() ? ( pView
->GetEditEngine()->GetParagraphCount() - 1 ) : 0;
760 sal_Int32 nLen
= pView
->GetEditEngine()->GetTextLen( nPara
);
761 ESelection
aSel( nPara
, nLen
, nPara
, nLen
);
762 pView
->SetSelection( aSel
); // set cursor to end of text
767 void ScInputWindow::PosGrabFocus()
772 void ScInputWindow::EnableButtons( bool bEnable
)
774 // when enabling buttons, always also enable the input window itself
775 if ( bEnable
&& !IsEnabled() )
778 EnableItem( SID_INPUT_FUNCTION
, bEnable
);
779 EnableItem( bIsOkCancelMode
? SID_INPUT_CANCEL
: SID_INPUT_SUM
, bEnable
);
780 EnableItem( bIsOkCancelMode
? SID_INPUT_OK
: SID_INPUT_EQUAL
, bEnable
);
784 void ScInputWindow::StateChanged( StateChangedType nType
)
786 ToolBox::StateChanged( nType
);
788 if ( nType
== STATE_CHANGE_INITSHOW
) Resize();
791 void ScInputWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
793 if ( rDCEvt
.GetType() == DATACHANGED_SETTINGS
&& (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
795 // update item images
796 ScModule
* pScMod
= SC_MOD();
797 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager( pScMod
);
798 // IMAGE macro uses pScMod, pImgMg
800 SetItemImage( SID_INPUT_FUNCTION
, IMAGE( SID_INPUT_FUNCTION
) );
801 if ( bIsOkCancelMode
)
803 SetItemImage( SID_INPUT_CANCEL
, IMAGE( SID_INPUT_CANCEL
) );
804 SetItemImage( SID_INPUT_OK
, IMAGE( SID_INPUT_OK
) );
808 SetItemImage( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
) );
809 SetItemImage( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
) );
813 ToolBox::DataChanged( rDCEvt
);
816 bool ScInputWindow::IsPointerAtResizePos()
818 if ( GetOutputSizePixel().Height() - GetPointerPosPixel().Y() <= 4 )
824 void ScInputWindow::MouseMove( const MouseEvent
& rMEvt
)
828 Point aPosPixel
= GetPointerPosPixel();
830 ScInputBarGroup
* pGroupBar
= dynamic_cast< ScInputBarGroup
* > ( pRuntimeWindow
.get() );
832 if ( bInResize
|| IsPointerAtResizePos() )
833 SetPointer( Pointer( POINTER_WINDOW_SSIZE
) );
835 SetPointer( Pointer( POINTER_ARROW
) );
840 long nResizeThreshold
= ( (long)TBX_WINDOW_HEIGHT
* 0.7 );
841 bool bResetPointerPos
= false;
843 // Detect attempt to expand toolbar too much
844 if ( aPosPixel
.Y() >= mnMaxY
)
846 bResetPointerPos
= true;
847 aPosPixel
.Y() = mnMaxY
;
848 } // or expanding down
849 else if ( GetOutputSizePixel().Height() - aPosPixel
.Y() < -nResizeThreshold
)
851 pGroupBar
->IncrementVerticalSize();
852 bResetPointerPos
= true;
854 else if ( ( GetOutputSizePixel().Height() - aPosPixel
.Y() ) > nResizeThreshold
)
856 bResetPointerPos
= true;
857 pGroupBar
->DecrementVerticalSize();
860 if ( bResetPointerPos
)
862 aPosPixel
.Y() = GetOutputSizePixel().Height();
863 SetPointerPosPixel( aPosPixel
);
867 ToolBox::MouseMove( rMEvt
);
870 void ScInputWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
874 if ( rMEvt
.IsLeft() )
876 if ( IsPointerAtResizePos() )
878 // Don't leave the mouse pointer leave *this* window
881 // find the height of the gridwin, we don't wan't to be
882 // able to expand the toolbar too far so we need to
883 // caculate an upper limit
884 // I'd prefer to leave at least a single column header and a
885 // row but I don't know how to get that value in pixels.
886 // Use TBX_WINDOW_HEIGHT for the moment
887 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
888 mnMaxY
= GetOutputSizePixel().Height() + ( pViewSh
->GetGridHeight(SC_SPLIT_TOP
) + pViewSh
->GetGridHeight(SC_SPLIT_BOTTOM
) ) - TBX_WINDOW_HEIGHT
;
892 ToolBox::MouseButtonDown( rMEvt
);
894 void ScInputWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
899 if ( rMEvt
.IsLeft() )
905 ToolBox::MouseButtonUp( rMEvt
);
911 ScInputBarGroup::ScInputBarGroup(Window
* pParent
, ScTabViewShell
* pViewSh
)
912 : ScTextWndBase ( pParent
, WinBits(WB_HIDE
| WB_TABSTOP
) ),
913 aMultiTextWnd ( this, pViewSh
),
914 aButton ( this, WB_TABSTOP
| WB_RECTSTYLE
| WB_SMALLSTYLE
),
915 aScrollBar ( this, WB_TABSTOP
| WB_VERT
| WB_DRAG
),
918 aMultiTextWnd
.Show();
919 aMultiTextWnd
.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND
) );
920 aMultiTextWnd
.SetHelpId( HID_INSWIN_INPUT
);
922 Size
aSize( GetSettings().GetStyleSettings().GetScrollBarSize(), aMultiTextWnd
.GetPixelHeightForLines(1) );
924 aButton
.SetClickHdl( LINK( this, ScInputBarGroup
, ClickHdl
) );
925 aButton
.SetSizePixel( aSize
);
927 aButton
.SetSymbol( SYMBOL_SPIN_DOWN
);
928 aButton
.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA
) );
931 aScrollBar
.SetSizePixel( aSize
);
932 aScrollBar
.SetScrollHdl( LINK( this, ScInputBarGroup
, Impl_ScrollHdl
) );
935 ScInputBarGroup::~ScInputBarGroup()
941 ScInputBarGroup::InsertAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
943 aMultiTextWnd
.InsertAccessibleTextData( rTextData
);
947 ScInputBarGroup::RemoveAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
949 aMultiTextWnd
.RemoveAccessibleTextData( rTextData
);
953 ScInputBarGroup::GetTextString() const
955 return aMultiTextWnd
.GetTextString();
958 void ScInputBarGroup::SetTextString( const OUString
& rString
)
960 aMultiTextWnd
.SetTextString(rString
);
963 void ScInputBarGroup::Resize()
965 Window
*w
=GetParent();
966 ScInputWindow
*pParent
;
967 pParent
=dynamic_cast<ScInputWindow
*>(w
);
971 OSL_FAIL("The parent window pointer pParent is null");
975 long nWidth
= pParent
->GetSizePixel().Width();
976 long nLeft
= GetPosPixel().X();
978 Size aSize
= GetSizePixel();
979 aSize
.Width() = std::max( ((long)(nWidth
- nLeft
- LEFT_OFFSET
)), (long)0 );
981 aScrollBar
.SetPosPixel(Point( aSize
.Width() - aButton
.GetSizePixel().Width(), aButton
.GetSizePixel().Height() ) );
983 Size
aTmpSize( aSize
);
984 aTmpSize
.Width() = aTmpSize
.Width() - aButton
.GetSizePixel().Width() - BUTTON_OFFSET
;
985 aMultiTextWnd
.SetSizePixel(aTmpSize
);
987 aMultiTextWnd
.Resize();
989 aSize
.Height() = aMultiTextWnd
.GetSizePixel().Height();
993 if( aMultiTextWnd
.GetNumLines() > 1 )
995 aButton
.SetSymbol( SYMBOL_SPIN_UP
);
996 aButton
.SetQuickHelpText( ScResId( SCSTR_QHELP_COLLAPSE_FORMULA
) );
997 Size scrollSize
= aButton
.GetSizePixel();
998 scrollSize
.Height() = aMultiTextWnd
.GetSizePixel().Height() - aButton
.GetSizePixel().Height();
999 aScrollBar
.SetSizePixel( scrollSize
);
1001 Size aOutSz
= aMultiTextWnd
.GetOutputSize();
1003 aScrollBar
.SetVisibleSize( aOutSz
.Height() );
1004 aScrollBar
.SetPageSize( aOutSz
.Height() );
1005 aScrollBar
.SetLineSize( aMultiTextWnd
.GetTextHeight() );
1006 aScrollBar
.SetRange( Range( 0, aMultiTextWnd
.GetEditEngTxtHeight() ) );
1008 aScrollBar
.Resize();
1013 aButton
.SetSymbol( SYMBOL_SPIN_DOWN
);
1014 aButton
.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA
) );
1018 aButton
.SetPosPixel(Point(aSize
.Width() - aButton
.GetSizePixel().Width(), 0));
1023 void ScInputBarGroup::StopEditEngine( bool bAll
)
1025 aMultiTextWnd
.StopEditEngine( bAll
);
1028 void ScInputBarGroup::StartEditEngine()
1030 aMultiTextWnd
.StartEditEngine();
1034 void ScInputBarGroup::MakeDialogEditView()
1036 aMultiTextWnd
.MakeDialogEditView();
1040 EditView
* ScInputBarGroup::GetEditView()
1042 return aMultiTextWnd
.GetEditView();
1045 bool ScInputBarGroup::IsInputActive()
1047 return aMultiTextWnd
.IsInputActive();
1050 void ScInputBarGroup::SetFormulaMode(bool bSet
)
1052 aMultiTextWnd
.SetFormulaMode(bSet
);
1055 void ScInputBarGroup::IncrementVerticalSize()
1057 aMultiTextWnd
.SetNumLines( aMultiTextWnd
.GetNumLines() + 1 );
1058 TriggerToolboxLayout();
1061 void ScInputBarGroup::DecrementVerticalSize()
1063 if ( aMultiTextWnd
.GetNumLines() > 1 )
1065 aMultiTextWnd
.SetNumLines( aMultiTextWnd
.GetNumLines() - 1 );
1066 TriggerToolboxLayout();
1070 IMPL_LINK_NOARG(ScInputBarGroup
, ClickHdl
)
1072 Window
*w
=GetParent();
1073 ScInputWindow
*pParent
;
1074 pParent
=dynamic_cast<ScInputWindow
*>(w
);
1078 OSL_FAIL("The parent window pointer pParent is null");
1081 if( aMultiTextWnd
.GetNumLines() > 1 )
1083 aMultiTextWnd
.SetNumLines( 1 );
1087 aMultiTextWnd
.SetNumLines( aMultiTextWnd
.GetLastNumExpandedLines() );
1089 TriggerToolboxLayout();
1090 // Restore focus to input line(s) if necessary
1091 if ( SC_MOD()->GetInputHdl()->IsTopMode() )
1092 aMultiTextWnd
.GrabFocus();
1096 void ScInputBarGroup::TriggerToolboxLayout()
1098 Window
*w
=GetParent();
1099 ScInputWindow
*pParent
;
1100 pParent
=dynamic_cast<ScInputWindow
*>(w
);
1101 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1103 // Capture the vertical position of this window in the toolbar, when we increase
1104 // the size of the toolbar to accomadate expanded line input we need to take this
1107 nVertOffset
= pParent
->GetItemPosRect( pParent
->GetItemCount() - 1 ).Top();
1111 Reference
< com::sun::star::beans::XPropertySet
> xPropSet( pViewFrm
->GetFrame().GetFrameInterface(), UNO_QUERY
);
1112 Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1114 if ( xPropSet
.is() )
1116 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1117 aValue
>>= xLayoutManager
;
1120 if ( xLayoutManager
.is() )
1122 if ( aMultiTextWnd
.GetNumLines() > 1)
1123 pParent
->SetToolbarLayoutMode( TBX_LAYOUT_LOCKVERT
);
1125 pParent
->SetToolbarLayoutMode( TBX_LAYOUT_NORMAL
);
1126 xLayoutManager
->lock();
1127 DataChangedEvent
aFakeUpdate( DATACHANGED_SETTINGS
, NULL
, SETTINGS_STYLE
);
1128 // this basically will trigger the reposititioning of the
1129 // items in the toolbar from ImplFormat ( which is controlled by
1130 // mnWinHeight ) which in turn is updated in ImplCalcItem which is
1131 // controlled by mbCalc. Additionally the ImplFormat above is
1132 // controlled via mbFormat. It seems the easiest way to get these
1133 // booleans set is to send in the fake event below.
1134 pParent
->DataChanged( aFakeUpdate
);
1135 // highest item in toolbar will have been calculated via the
1136 // event above. Call resize on InputBar to pick up the height
1139 // unlock relayouts the toolbars in the 4 quadrants
1140 xLayoutManager
->unlock();
1145 IMPL_LINK_NOARG(ScInputBarGroup
, Impl_ScrollHdl
)
1147 aMultiTextWnd
.DoScroll();
1151 void ScInputBarGroup::TextGrabFocus()
1153 aMultiTextWnd
.TextGrabFocus();
1160 ScMultiTextWnd::ScMultiTextWnd( ScInputBarGroup
* pParen
, ScTabViewShell
* pViewSh
)
1162 ScTextWnd( pParen
, pViewSh
),
1163 mrGroupBar(* pParen
),
1165 mnLastExpandedLines( INPUTWIN_MULTILINES
),
1166 mbInvalidate( false )
1169 aBorder
= CalcWindowSize( aBorder
);
1170 mnBorderHeight
= aBorder
.Height();
1173 ScMultiTextWnd::~ScMultiTextWnd()
1177 void ScMultiTextWnd::Paint( const Rectangle
& rRect
)
1179 EditView
* pView
= GetEditView();
1184 pView
->Invalidate();
1185 mbInvalidate
= false;
1187 pEditView
->Paint( rRect
);
1191 EditView
* ScMultiTextWnd::GetEditView()
1198 long ScMultiTextWnd::GetPixelHeightForLines( long nLines
)
1200 // add padding ( for the borders of the window )
1201 return ( nLines
* LogicToPixel( Size( 0, GetTextHeight() ) ).Height() ) + mnBorderHeight
;
1204 void ScMultiTextWnd::SetNumLines( long nLines
)
1209 mnLastExpandedLines
= nLines
;
1214 void ScMultiTextWnd::Resize()
1216 // Only Height is recalculated here, Width is applied from
1217 // parent/container window
1218 Size aTextBoxSize
= GetSizePixel();
1220 aTextBoxSize
.Height() = GetPixelHeightForLines( mnLines
);
1221 SetSizePixel( aTextBoxSize
);
1225 Size aOutputSize
= GetOutputSizePixel();
1226 Rectangle aOutputArea
= PixelToLogic( Rectangle( Point(), aOutputSize
));
1227 pEditView
->SetOutputArea( aOutputArea
);
1229 // Don't leave an empty area at the bottom if we can move the text down.
1230 long nMaxVisAreaTop
= pEditEngine
->GetTextHeight() - aOutputArea
.GetHeight();
1231 if (pEditView
->GetVisArea().Top() > nMaxVisAreaTop
)
1233 pEditView
->Scroll(0, pEditView
->GetVisArea().Top() - nMaxVisAreaTop
);
1236 pEditEngine
->SetPaperSize( PixelToLogic( Size( aOutputSize
.Width(), 10000 ) ) );
1239 SetScrollBarRange();
1242 IMPL_LINK(ScMultiTextWnd
, ModifyHdl
, EENotify
*, pNotify
)
1244 ScTextWnd::NotifyHdl( pNotify
);
1248 IMPL_LINK(ScMultiTextWnd
, NotifyHdl
, EENotify
*, pNotify
)
1250 // need to process EE_NOTIFY_TEXTVIEWSCROLLED here
1251 // sometimes we don't seem to get EE_NOTIFY_TEXTVIEWSCROLLED e.g. when
1252 // we insert text at the beginning of the text so the cursor never moves
1253 // down to generate a scroll event
1255 if ( pNotify
&& ( pNotify
->eNotificationType
== EE_NOTIFY_TEXTVIEWSCROLLED
1256 || pNotify
->eNotificationType
== EE_NOTIFY_TEXTHEIGHTCHANGED
) )
1257 SetScrollBarRange();
1261 long ScMultiTextWnd::GetEditEngTxtHeight()
1263 return pEditView
? pEditView
->GetEditEngine()->GetTextHeight() : 0;
1266 void ScMultiTextWnd::SetScrollBarRange()
1270 ScrollBar
& rVBar
= mrGroupBar
.GetScrollBar();
1271 rVBar
.SetRange( Range( 0, GetEditEngTxtHeight() ) );
1272 long currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1273 rVBar
.SetThumbPos( currentDocPos
);
1278 ScMultiTextWnd::DoScroll()
1282 ScrollBar
& rVBar
= mrGroupBar
.GetScrollBar();
1283 long currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1284 long nDiff
= currentDocPos
- rVBar
.GetThumbPos();
1285 pEditView
->Scroll( 0, nDiff
);
1286 currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1287 rVBar
.SetThumbPos( currentDocPos
);
1291 void ScMultiTextWnd::StartEditEngine()
1293 // Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1294 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1295 if ( pObjSh
&& pObjSh
->IsInModalMode() )
1298 if ( !pEditView
|| !pEditEngine
)
1303 SC_MOD()->SetInputMode( SC_INPUT_TOP
);
1305 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1307 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1310 static void lcl_ExtendEditFontAttribs( SfxItemSet
& rSet
)
1312 const SfxPoolItem
& rFontItem
= rSet
.Get( EE_CHAR_FONTINFO
);
1313 rSet
.Put( rFontItem
, EE_CHAR_FONTINFO_CJK
);
1314 rSet
.Put( rFontItem
, EE_CHAR_FONTINFO_CTL
);
1315 const SfxPoolItem
& rHeightItem
= rSet
.Get( EE_CHAR_FONTHEIGHT
);
1316 rSet
.Put( rHeightItem
, EE_CHAR_FONTHEIGHT_CJK
);
1317 rSet
.Put( rHeightItem
, EE_CHAR_FONTHEIGHT_CTL
);
1318 const SfxPoolItem
& rWeightItem
= rSet
.Get( EE_CHAR_WEIGHT
);
1319 rSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CJK
);
1320 rSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CTL
);
1321 const SfxPoolItem
& rItalicItem
= rSet
.Get( EE_CHAR_ITALIC
);
1322 rSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CJK
);
1323 rSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CTL
);
1324 const SfxPoolItem
& rLangItem
= rSet
.Get( EE_CHAR_LANGUAGE
);
1325 rSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CJK
);
1326 rSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CTL
);
1329 static void lcl_ModifyRTLDefaults( SfxItemSet
& rSet
)
1331 rSet
.Put( SvxAdjustItem( SVX_ADJUST_RIGHT
, EE_PARA_JUST
) );
1333 // always using rtl writing direction would break formulas
1334 //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1336 // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
1337 // sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be
1338 // increased to not see the beginning of the next line.
1339 SvxLineSpacingItem
aItem( SVX_LINESPACE_TWO_LINES
, EE_PARA_SBL
);
1340 aItem
.SetPropLineSpace( 200 );
1344 static void lcl_ModifyRTLVisArea( EditView
* pEditView
)
1346 Rectangle aVisArea
= pEditView
->GetVisArea();
1347 Size aPaper
= pEditView
->GetEditEngine()->GetPaperSize();
1348 long nDiff
= aPaper
.Width() - aVisArea
.Right();
1349 aVisArea
.Left() += nDiff
;
1350 aVisArea
.Right() += nDiff
;
1351 pEditView
->SetVisArea(aVisArea
);
1355 void ScMultiTextWnd::InitEditEngine()
1357 ScFieldEditEngine
* pNew
;
1358 ScTabViewShell
* pViewSh
= GetViewShell();
1359 ScDocShell
* pDocSh
= NULL
;
1362 pDocSh
= pViewSh
->GetViewData()->GetDocShell();
1363 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
1364 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1367 pNew
= new ScFieldEditEngine(NULL
, EditEngine::CreatePool(), NULL
, true);
1368 pNew
->SetExecuteURL( false );
1371 Size barSize
=GetSizePixel();
1372 pEditEngine
->SetUpdateMode( false );
1373 pEditEngine
->SetPaperSize( PixelToLogic(Size(barSize
.Width(),10000)) );
1374 pEditEngine
->SetWordDelimiters(
1375 ScEditUtil::ModifyDelimiters( pEditEngine
->GetWordDelimiters() ) );
1377 UpdateAutoCorrFlag();
1380 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1381 pEditEngine
->SetFontInfoInItemSet( *pSet
, aTextFont
);
1382 lcl_ExtendEditFontAttribs( *pSet
);
1383 // turn off script spacing to match DrawText output
1384 pSet
->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING
) );
1386 lcl_ModifyRTLDefaults( *pSet
);
1387 pEditEngine
->SetDefaults( pSet
);
1390 // Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1391 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1393 bool bFilled
= false;
1394 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1395 if ( pHdl
) //! Testen, ob's der richtige InputHdl ist?
1396 bFilled
= pHdl
->GetTextAndFields( *pEditEngine
);
1398 pEditEngine
->SetUpdateMode( true );
1400 // aString ist die Wahrheit...
1401 if (bFilled
&& pEditEngine
->GetText() == aString
)
1402 Invalidate(); // Repaint fuer (hinterlegte) Felder
1404 pEditEngine
->SetText(aString
); // dann wenigstens den richtigen Text
1406 pEditView
= new EditView( pEditEngine
, this );
1407 pEditView
->SetInsertMode(bIsInsertMode
);
1409 // Text aus Clipboard wird als ASCII einzeilig uebernommen
1410 sal_uLong n
= pEditView
->GetControlWord();
1411 pEditView
->SetControlWord( n
| EV_CNTRL_SINGLELINEPASTE
);
1413 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1418 lcl_ModifyRTLVisArea( pEditView
);
1420 pEditEngine
->SetModifyHdl(LINK(this, ScMultiTextWnd
, ModifyHdl
));
1421 pEditEngine
->SetNotifyHdl(LINK(this, ScMultiTextWnd
, NotifyHdl
));
1423 if (!maAccTextDatas
.empty())
1424 maAccTextDatas
.back()->StartEdit();
1426 // as long as EditEngine and DrawText sometimes differ for CTL text,
1427 // repaint now to have the EditEngine's version visible
1430 ScDocument
* pDoc
= pDocSh
->GetDocument(); // any document
1431 sal_uInt8 nScript
= pDoc
->GetStringScriptType( aString
);
1432 if ( nScript
& SCRIPTTYPE_COMPLEX
)
1437 void ScMultiTextWnd::StopEditEngine( bool bAll
)
1440 pEditEngine
->SetNotifyHdl(Link());
1441 ScTextWnd::StopEditEngine( bAll
);
1444 void ScMultiTextWnd::SetTextString( const OUString
& rNewString
)
1446 // Ideally it would be best to create on demand the EditEngine/EditView here, but... for
1447 // the initialisation scenario where a cell is first clicked on we end up with the text in the
1448 // inputbar window scrolled to the bottom if we do that here ( because the tableview and topview
1449 // are synced I guess ).
1450 // should fix that I suppose :-/ need to look a bit further into that
1451 mbInvalidate
= true; // ensure next Paint ( that uses editengine ) call will call Invalidate first
1452 ScTextWnd::SetTextString( rNewString
);
1453 SetScrollBarRange();
1460 ScTextWnd::ScTextWnd( Window
* pParent
, ScTabViewShell
* pViewSh
)
1461 : ScTextWndBase ( pParent
, WinBits(WB_HIDE
| WB_BORDER
) ),
1462 DragSourceHelper( this ),
1463 pEditEngine ( NULL
),
1465 bIsInsertMode( true ),
1466 bFormulaMode ( false ),
1467 bInputMode ( false ),
1468 mpViewShell(pViewSh
)
1470 EnableRTL( false ); // EditEngine can't be used with VCL EnableRTL
1472 bIsRTL
= GetSettings().GetLayoutRTL();
1474 // always use application font, so a font with cjk chars can be installed
1475 Font aAppFont
= GetFont();
1476 aTextFont
= aAppFont
;
1477 aTextFont
.SetSize( PixelToLogic( aAppFont
.GetSize(), MAP_TWIP
) ); // AppFont ist in Pixeln
1479 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1481 Color aBgColor
= rStyleSettings
.GetWindowColor();
1482 Color aTxtColor
= rStyleSettings
.GetWindowTextColor();
1484 aTextFont
.SetTransparent ( true );
1485 aTextFont
.SetFillColor ( aBgColor
);
1486 //aTextFont.SetColor ( COL_FIELDTEXT );
1487 aTextFont
.SetColor (aTxtColor
);
1488 aTextFont
.SetWeight ( WEIGHT_NORMAL
);
1490 Size
aSize(1,TBX_WINDOW_HEIGHT
);
1491 Size
aMinEditSize( Edit::GetMinimumEditSize() );
1492 if( aMinEditSize
.Height() > aSize
.Height() )
1493 aSize
.Height() = aMinEditSize
.Height();
1494 SetSizePixel ( aSize
);
1495 SetBackground ( aBgColor
);
1496 SetLineColor ( COL_BLACK
);
1497 SetMapMode ( MAP_TWIP
);
1498 SetPointer ( POINTER_TEXT
);
1499 SetFont( aTextFont
);
1502 ScTextWnd::~ScTextWnd()
1504 while (!maAccTextDatas
.empty()) {
1505 maAccTextDatas
.back()->Dispose();
1511 void ScTextWnd::Paint( const Rectangle
& rRect
)
1514 pEditView
->Paint( rRect
);
1517 SetFont( aTextFont
);
1519 long nDiff
= GetOutputSizePixel().Height()
1520 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
1521 // if (nDiff<2) nDiff=2; // mind. 1 Pixel
1527 nStartPos
+= GetOutputSizePixel().Width() -
1528 LogicToPixel( Size( GetTextWidth( aString
), 0 ) ).Width();
1530 // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem
1533 DrawText( PixelToLogic( Point( nStartPos
, nDiff
/2 ) ), aString
);
1537 void ScTextWnd::Resize()
1541 Size aSize
= GetOutputSizePixel();
1542 long nDiff
= aSize
.Height()
1543 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
1545 pEditView
->SetOutputArea(
1546 PixelToLogic( Rectangle( Point( 0, (nDiff
> 0) ? nDiff
/2 : 1 ),
1551 void ScTextWnd::MouseMove( const MouseEvent
& rMEvt
)
1554 pEditView
->MouseMove( rMEvt
);
1557 void ScTextWnd::MouseButtonDown( const MouseEvent
& rMEvt
)
1562 if ( SC_MOD()->IsEditMode() )
1568 pEditView
->SetEditEngineUpdateMode( true );
1569 pEditView
->MouseButtonDown( rMEvt
);
1573 void ScTextWnd::MouseButtonUp( const MouseEvent
& rMEvt
)
1576 if (pEditView
->MouseButtonUp( rMEvt
))
1578 if ( rMEvt
.IsMiddle() &&
1579 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1581 // EditView may have pasted from selection
1582 SC_MOD()->InputChanged( pEditView
);
1585 SC_MOD()->InputSelection( pEditView
);
1589 void ScTextWnd::Command( const CommandEvent
& rCEvt
)
1592 sal_uInt16 nCommand
= rCEvt
.GetCommand();
1593 if ( pEditView
/* && nCommand == COMMAND_STARTDRAG */ )
1595 ScModule
* pScMod
= SC_MOD();
1596 ScTabViewShell
* pStartViewSh
= ScTabViewShell::GetActiveViewShell();
1598 // don't modify the font defaults here - the right defaults are
1599 // already set in StartEditEngine when the EditEngine is created
1601 // verhindern, dass die EditView beim View-Umschalten wegkommt
1602 pScMod
->SetInEditCommand( true );
1603 pEditView
->Command( rCEvt
);
1604 pScMod
->SetInEditCommand( false );
1606 // COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
1607 // darum in dem Fall kein InputChanged
1608 //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten
1610 if ( nCommand
== COMMAND_STARTDRAG
)
1612 // ist auf eine andere View gedraggt worden?
1613 ScTabViewShell
* pEndViewSh
= ScTabViewShell::GetActiveViewShell();
1614 if ( pEndViewSh
!= pStartViewSh
&& pStartViewSh
!= NULL
)
1616 ScViewData
* pViewData
= pStartViewSh
->GetViewData();
1617 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pStartViewSh
);
1618 if ( pHdl
&& pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1620 pHdl
->CancelHandler();
1621 pViewData
->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv
1625 else if ( nCommand
== COMMAND_CURSORPOS
)
1627 // don't call InputChanged for COMMAND_CURSORPOS
1629 else if ( nCommand
== COMMAND_INPUTLANGUAGECHANGE
)
1631 // #i55929# Font and font size state depends on input language if nothing is selected,
1632 // so the slots have to be invalidated when the input language is changed.
1634 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1637 SfxBindings
& rBindings
= pViewFrm
->GetBindings();
1638 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
1639 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
1642 else if ( nCommand
== COMMAND_WHEEL
)
1644 //don't call InputChanged for COMMAND_WHEEL
1647 SC_MOD()->InputChanged( pEditView
);
1650 Window::Command(rCEvt
); // sonst soll sich die Basisklasse drum kuemmern...
1655 void ScTextWnd::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
1659 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, true );
1660 pEditView
->Command( aDragEvent
);
1662 // handling of d&d to different view (CancelHandler) can't be done here,
1663 // because the call returns before d&d is complete.
1667 void ScTextWnd::KeyInput(const KeyEvent
& rKEvt
)
1670 if (!SC_MOD()->InputKeyEvent( rKEvt
))
1673 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1675 bUsed
= pViewSh
->SfxKeyInput(rKEvt
); // nur Acceleratoren, keine Eingabe
1677 Window::KeyInput( rKEvt
);
1682 void ScTextWnd::GetFocus()
1684 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1686 pViewSh
->SetFormShellAtTop( false ); // focus in input line -> FormShell no longer on top
1689 void ScTextWnd::LoseFocus()
1693 OUString
ScTextWnd::GetText() const
1695 // ueberladen, um per Testtool an den Text heranzukommen
1698 return pEditEngine
->GetText();
1700 return GetTextString();
1703 void ScTextWnd::SetFormulaMode( bool bSet
)
1705 if ( bSet
!= bFormulaMode
)
1707 bFormulaMode
= bSet
;
1708 UpdateAutoCorrFlag();
1712 void ScTextWnd::UpdateAutoCorrFlag()
1716 sal_uLong nControl
= pEditEngine
->GetControlWord();
1717 sal_uLong nOld
= nControl
;
1719 nControl
&= ~EE_CNTRL_AUTOCORRECT
; // keine Autokorrektur in Formeln
1721 nControl
|= EE_CNTRL_AUTOCORRECT
; // sonst schon
1722 if ( nControl
!= nOld
)
1723 pEditEngine
->SetControlWord( nControl
);
1727 ScTabViewShell
* ScTextWnd::GetViewShell()
1732 void ScTextWnd::StartEditEngine()
1734 // Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1735 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1736 if ( pObjSh
&& pObjSh
->IsInModalMode() )
1739 if ( !pEditView
|| !pEditEngine
)
1741 ScFieldEditEngine
* pNew
;
1742 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1745 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
1746 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1749 pNew
= new ScFieldEditEngine(NULL
, EditEngine::CreatePool(), NULL
, true);
1750 pNew
->SetExecuteURL( false );
1753 pEditEngine
->SetUpdateMode( false );
1754 pEditEngine
->SetPaperSize( Size( bIsRTL
? USHRT_MAX
: THESIZE
, 300 ) );
1755 pEditEngine
->SetWordDelimiters(
1756 ScEditUtil::ModifyDelimiters( pEditEngine
->GetWordDelimiters() ) );
1758 UpdateAutoCorrFlag();
1761 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1762 pEditEngine
->SetFontInfoInItemSet( *pSet
, aTextFont
);
1763 lcl_ExtendEditFontAttribs( *pSet
);
1764 // turn off script spacing to match DrawText output
1765 pSet
->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING
) );
1767 lcl_ModifyRTLDefaults( *pSet
);
1768 pEditEngine
->SetDefaults( pSet
);
1771 // Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1772 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1774 bool bFilled
= false;
1775 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1776 if ( pHdl
) //! Testen, ob's der richtige InputHdl ist?
1777 bFilled
= pHdl
->GetTextAndFields( *pEditEngine
);
1779 pEditEngine
->SetUpdateMode( true );
1781 // aString ist die Wahrheit...
1782 if (bFilled
&& pEditEngine
->GetText() == aString
)
1783 Invalidate(); // Repaint fuer (hinterlegte) Felder
1785 pEditEngine
->SetText(aString
); // dann wenigstens den richtigen Text
1787 pEditView
= new EditView( pEditEngine
, this );
1788 pEditView
->SetInsertMode(bIsInsertMode
);
1790 // Text aus Clipboard wird als ASCII einzeilig uebernommen
1791 sal_uLong n
= pEditView
->GetControlWord();
1792 pEditView
->SetControlWord( n
| EV_CNTRL_SINGLELINEPASTE
);
1794 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1799 lcl_ModifyRTLVisArea( pEditView
);
1801 pEditEngine
->SetModifyHdl(LINK(this, ScTextWnd
, NotifyHdl
));
1803 if (!maAccTextDatas
.empty())
1804 maAccTextDatas
.back()->StartEdit();
1806 // as long as EditEngine and DrawText sometimes differ for CTL text,
1807 // repaint now to have the EditEngine's version visible
1808 // SfxObjectShell* pObjSh = SfxObjectShell::Current();
1809 if ( pObjSh
&& pObjSh
->ISA(ScDocShell
) )
1811 ScDocument
* pDoc
= ((ScDocShell
*)pObjSh
)->GetDocument(); // any document
1812 sal_uInt8 nScript
= pDoc
->GetStringScriptType( aString
);
1813 if ( nScript
& SCRIPTTYPE_COMPLEX
)
1818 SC_MOD()->SetInputMode( SC_INPUT_TOP
);
1820 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1822 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1825 IMPL_LINK_NOARG(ScTextWnd
, NotifyHdl
)
1827 if (pEditView
&& !bInputMode
)
1829 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1831 // Use the InputHandler's InOwnChange flag to prevent calling InputChanged
1832 // while an InputHandler method is modifying the EditEngine content
1834 if ( pHdl
&& !pHdl
->IsInOwnChange() )
1835 pHdl
->InputChanged( pEditView
, true ); // #i20282# InputChanged must know if called from modify handler
1841 void ScTextWnd::StopEditEngine( bool bAll
)
1845 if (!maAccTextDatas
.empty())
1846 maAccTextDatas
.back()->EndEdit();
1848 ScModule
* pScMod
= SC_MOD();
1851 pScMod
->InputSelection( pEditView
);
1852 aString
= pEditEngine
->GetText();
1853 bIsInsertMode
= pEditView
->IsInsertMode();
1854 bool bSelection
= pEditView
->HasSelection();
1855 pEditEngine
->SetModifyHdl(Link());
1857 DELETEZ(pEditEngine
);
1859 if ( pScMod
->IsEditMode() && !bAll
)
1860 pScMod
->SetInputMode(SC_INPUT_TABLE
);
1862 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1864 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1867 Invalidate(); // damit Selektion nicht stehenbleibt
1871 static sal_Int32
findFirstNonMatchingChar(const OUString
& rStr1
, const OUString
& rStr2
)
1873 // Search the string for unmatching chars
1874 const sal_Unicode
* pStr1
= rStr1
.getStr();
1875 const sal_Unicode
* pStr2
= rStr2
.getStr();
1877 while ( i
< rStr1
.getLength() )
1879 // Abort on the first unmatching char
1880 if ( *pStr1
!= *pStr2
)
1890 void ScTextWnd::SetTextString( const OUString
& rNewString
)
1892 if ( rNewString
!= aString
)
1896 // Position der Aenderung suchen, nur Rest painten
1905 // test if CTL script type is involved
1906 sal_uInt8 nOldScript
= 0;
1907 sal_uInt8 nNewScript
= 0;
1908 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1909 if ( pObjSh
&& pObjSh
->ISA(ScDocShell
) )
1911 // any document can be used (used only for its break iterator)
1912 ScDocument
* pDoc
= ((ScDocShell
*)pObjSh
)->GetDocument();
1913 nOldScript
= pDoc
->GetStringScriptType( aString
);
1914 nNewScript
= pDoc
->GetStringScriptType( rNewString
);
1916 bPaintAll
= ( nOldScript
& SCRIPTTYPE_COMPLEX
) || ( nNewScript
& SCRIPTTYPE_COMPLEX
);
1921 // if CTL is involved, the whole text has to be redrawn
1928 if (rNewString
.getLength() > aString
.getLength())
1929 nDifPos
= findFirstNonMatchingChar(rNewString
, aString
);
1931 nDifPos
= findFirstNonMatchingChar(aString
, rNewString
);
1933 long nSize1
= GetTextWidth(aString
);
1934 long nSize2
= GetTextWidth(rNewString
);
1935 if ( nSize1
>0 && nSize2
>0 )
1936 nTextSize
= std::max( nSize1
, nSize2
);
1938 nTextSize
= GetOutputSize().Width(); // Ueberlauf
1940 Point aLogicStart
= PixelToLogic(Point(0,0));
1941 long nStartPos
= aLogicStart
.X();
1942 long nInvPos
= nStartPos
;
1944 nInvPos
+= GetTextWidth(aString
,0,nDifPos
);
1946 sal_uInt16 nFlags
= 0;
1947 if ( nDifPos
== aString
.getLength() ) // only new characters appended
1948 nFlags
= INVALIDATE_NOERASE
; // then background is already clear
1949 Invalidate( Rectangle( nInvPos
, 0,
1950 nStartPos
+nTextSize
, GetOutputSize().Height()-1 ),
1956 pEditEngine
->SetText(rNewString
);
1959 aString
= rNewString
;
1961 if (!maAccTextDatas
.empty())
1962 maAccTextDatas
.back()->TextChanged();
1968 const OUString
& ScTextWnd::GetTextString() const
1973 bool ScTextWnd::IsInputActive()
1978 EditView
* ScTextWnd::GetEditView()
1983 void ScTextWnd::MakeDialogEditView()
1985 if ( pEditView
) return;
1987 ScFieldEditEngine
* pNew
;
1988 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1991 ScDocument
* pDoc
= pViewSh
->GetViewData()->GetDocument();
1992 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1995 pNew
= new ScFieldEditEngine(NULL
, EditEngine::CreatePool(), NULL
, true);
1996 pNew
->SetExecuteURL( false );
1999 pEditEngine
->SetUpdateMode( false );
2000 pEditEngine
->SetWordDelimiters( pEditEngine
->GetWordDelimiters() + "=" );
2001 pEditEngine
->SetPaperSize( Size( bIsRTL
? USHRT_MAX
: THESIZE
, 300 ) );
2003 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
2004 pEditEngine
->SetFontInfoInItemSet( *pSet
, aTextFont
);
2005 lcl_ExtendEditFontAttribs( *pSet
);
2007 lcl_ModifyRTLDefaults( *pSet
);
2008 pEditEngine
->SetDefaults( pSet
);
2009 pEditEngine
->SetUpdateMode( true );
2011 pEditView
= new EditView( pEditEngine
, this );
2012 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
2017 lcl_ModifyRTLVisArea( pEditView
);
2019 if (!maAccTextDatas
.empty())
2020 maAccTextDatas
.back()->StartEdit();
2023 void ScTextWnd::ImplInitSettings()
2025 bIsRTL
= GetSettings().GetLayoutRTL();
2027 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2029 Color aBgColor
= rStyleSettings
.GetWindowColor();
2030 Color aTxtColor
= rStyleSettings
.GetWindowTextColor();
2032 aTextFont
.SetFillColor ( aBgColor
);
2033 aTextFont
.SetColor (aTxtColor
);
2034 SetBackground ( aBgColor
);
2038 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> ScTextWnd::CreateAccessible()
2040 return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL
, this,
2041 OUString(ScResId(STR_ACC_EDITLINE_NAME
)),
2042 OUString(ScResId(STR_ACC_EDITLINE_DESCR
)), ScAccessibleEditObject::EditLine
);
2045 void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
2047 OSL_ENSURE( ::std::find( maAccTextDatas
.begin(), maAccTextDatas
.end(), &rTextData
) == maAccTextDatas
.end(),
2048 "ScTextWnd::InsertAccessibleTextData - passed object already registered" );
2049 maAccTextDatas
.push_back( &rTextData
);
2052 void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
2054 AccTextDataVector::iterator aEnd
= maAccTextDatas
.end();
2055 AccTextDataVector::iterator aIt
= ::std::find( maAccTextDatas
.begin(), aEnd
, &rTextData
);
2056 OSL_ENSURE( aIt
!= aEnd
, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
2058 maAccTextDatas
.erase( aIt
);
2061 void ScTextWnd::DataChanged( const DataChangedEvent
& rDCEvt
)
2063 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
2064 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
2070 Window::DataChanged( rDCEvt
);
2073 void ScTextWnd::TextGrabFocus()
2082 ScPosWnd::ScPosWnd( Window
* pParent
) :
2083 ComboBox ( pParent
, WinBits(WB_HIDE
| WB_DROPDOWN
) ),
2086 bFormulaMode( false )
2088 Size
aSize( GetTextWidth( OUString("GW99999:GW99999") ),
2090 aSize
.Width() += 25; // ??
2091 aSize
.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..."
2092 SetSizePixel( aSize
);
2096 StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates
2099 ScPosWnd::~ScPosWnd()
2101 EndListening( *SFX_APP() );
2108 void ScPosWnd::SetFormulaMode( bool bSet
)
2110 if ( bSet
!= bFormulaMode
)
2112 bFormulaMode
= bSet
;
2123 void ScPosWnd::SetPos( const OUString
& rPosStr
)
2125 if ( aPosStr
!= rPosStr
)
2134 OUString
createLocalRangeName(const OUString
& rName
, const OUString
& rTableName
)
2136 OUStringBuffer
aString (rName
);
2137 aString
.append(" (");
2138 aString
.append(rTableName
);
2139 aString
.append(")");
2140 return aString
.makeStringAndClear();
2145 void ScPosWnd::FillRangeNames()
2149 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
2150 if ( pObjSh
&& pObjSh
->ISA(ScDocShell
) )
2152 ScDocument
* pDoc
= ((ScDocShell
*)pObjSh
)->GetDocument();
2154 InsertEntry(ScGlobal::GetRscString( STR_MANAGE_NAMES
));
2158 std::set
<OUString
> aSet
;
2159 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
2160 if (!pRangeNames
->empty())
2162 ScRangeName::const_iterator itrBeg
= pRangeNames
->begin(), itrEnd
= pRangeNames
->end();
2163 for (ScRangeName::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
2165 if (itr
->second
->IsValidReference(aDummy
))
2166 aSet
.insert(itr
->second
->GetName());
2169 for (SCTAB i
= 0; i
< pDoc
->GetTableCount(); ++i
)
2171 ScRangeName
* pLocalRangeName
= pDoc
->GetRangeName(i
);
2172 if (pLocalRangeName
&& !pLocalRangeName
->empty())
2174 OUString aTableName
;
2175 pDoc
->GetName(i
, aTableName
);
2176 for (ScRangeName::const_iterator itr
= pLocalRangeName
->begin(); itr
!= pLocalRangeName
->end(); ++itr
)
2178 if (itr
->second
->IsValidReference(aDummy
))
2179 aSet
.insert(createLocalRangeName(itr
->second
->GetName(), aTableName
));
2186 for (std::set
<OUString
>::iterator itr
= aSet
.begin();
2187 itr
!= aSet
.end(); ++itr
)
2196 void ScPosWnd::FillFunctions()
2200 OUString aFirstName
;
2201 const ScAppOptions
& rOpt
= SC_MOD()->GetAppOptions();
2202 sal_uInt16 nMRUCount
= rOpt
.GetLRUFuncListCount();
2203 const sal_uInt16
* pMRUList
= rOpt
.GetLRUFuncList();
2206 const ScFunctionList
* pFuncList
= ScGlobal::GetStarCalcFunctionList();
2207 sal_uLong nListCount
= pFuncList
->GetCount();
2208 for (sal_uInt16 i
=0; i
<nMRUCount
; i
++)
2210 sal_uInt16 nId
= pMRUList
[i
];
2211 for (sal_uLong j
=0; j
<nListCount
; j
++)
2213 const ScFuncDesc
* pDesc
= pFuncList
->GetFunction( j
);
2214 if ( pDesc
->nFIndex
== nId
&& pDesc
->pFuncName
)
2216 InsertEntry( *pDesc
->pFuncName
);
2217 if (aFirstName
.isEmpty())
2218 aFirstName
= *pDesc
->pFuncName
;
2219 break; // nicht weitersuchen
2225 //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
2226 //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!
2228 // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
2230 SetText(aFirstName
);
2233 void ScPosWnd::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
2235 if ( !bFormulaMode
)
2237 // muss die Liste der Bereichsnamen updgedated werden?
2239 if ( rHint
.ISA(SfxSimpleHint
) )
2241 sal_uLong nHintId
= ((SfxSimpleHint
&)rHint
).GetId();
2242 if ( nHintId
== SC_HINT_AREAS_CHANGED
|| nHintId
== SC_HINT_NAVIGATOR_UPDATEALL
)
2245 else if ( rHint
.ISA(SfxEventHint
) )
2247 sal_uLong nEventId
= ((SfxEventHint
&)rHint
).GetEventId();
2248 if ( nEventId
== SFX_EVENT_ACTIVATEDOC
)
2254 void ScPosWnd::HideTip()
2258 Help::HideTip( nTipVisible
);
2263 static ScNameInputType
lcl_GetInputType( const OUString
& rText
)
2265 ScNameInputType eRet
= SC_NAME_INPUT_BAD_NAME
; // the more general error
2267 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2270 ScViewData
* pViewData
= pViewSh
->GetViewData();
2271 ScDocument
* pDoc
= pViewData
->GetDocument();
2272 SCTAB nTab
= pViewData
->GetTabNo();
2273 formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
2275 // test in same order as in SID_CURRENTCELL execute
2279 ScRangeUtil aRangeUtil
;
2283 if (rText
== ScGlobal::GetRscString(STR_MANAGE_NAMES
))
2284 eRet
= SC_MANAGE_NAMES
;
2285 else if ( aRange
.Parse( rText
, pDoc
, eConv
) & SCA_VALID
)
2286 eRet
= SC_NAME_INPUT_RANGE
;
2287 else if ( aAddress
.Parse( rText
, pDoc
, eConv
) & SCA_VALID
)
2288 eRet
= SC_NAME_INPUT_CELL
;
2289 else if ( aRangeUtil
.MakeRangeFromName( rText
, pDoc
, nTab
, aRange
, RUTL_NAMES
, eConv
) )
2290 eRet
= SC_NAME_INPUT_NAMEDRANGE
;
2291 else if ( aRangeUtil
.MakeRangeFromName( rText
, pDoc
, nTab
, aRange
, RUTL_DBASE
, eConv
) )
2292 eRet
= SC_NAME_INPUT_DATABASE
;
2293 else if ( comphelper::string::isdigitAsciiString( rText
) &&
2294 ( nNumeric
= rText
.toInt32() ) > 0 && nNumeric
<= MAXROW
+1 )
2295 eRet
= SC_NAME_INPUT_ROW
;
2296 else if ( pDoc
->GetTable( rText
, nNameTab
) )
2297 eRet
= SC_NAME_INPUT_SHEET
;
2298 else if ( ScRangeData::IsNameValid( rText
, pDoc
) ) // nothing found, create new range?
2300 if ( pViewData
->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
2301 eRet
= SC_NAME_INPUT_DEFINE
;
2303 eRet
= SC_NAME_INPUT_BAD_SELECTION
;
2306 eRet
= SC_NAME_INPUT_BAD_NAME
;
2312 void ScPosWnd::Modify()
2318 if ( !IsTravelSelect() && !bFormulaMode
)
2320 // determine the action that would be taken for the current input
2322 ScNameInputType eType
= lcl_GetInputType( GetText() ); // uses current view
2323 sal_uInt16 nStrId
= 0;
2326 case SC_NAME_INPUT_CELL
:
2327 nStrId
= STR_NAME_INPUT_CELL
;
2329 case SC_NAME_INPUT_RANGE
:
2330 case SC_NAME_INPUT_NAMEDRANGE
:
2331 nStrId
= STR_NAME_INPUT_RANGE
; // named range or range reference
2333 case SC_NAME_INPUT_DATABASE
:
2334 nStrId
= STR_NAME_INPUT_DBRANGE
;
2336 case SC_NAME_INPUT_ROW
:
2337 nStrId
= STR_NAME_INPUT_ROW
;
2339 case SC_NAME_INPUT_SHEET
:
2340 nStrId
= STR_NAME_INPUT_SHEET
;
2342 case SC_NAME_INPUT_DEFINE
:
2343 nStrId
= STR_NAME_INPUT_DEFINE
;
2346 // other cases (error): no tip help
2352 // show the help tip at the text cursor position
2354 Window
* pWin
= GetSubEdit();
2358 Cursor
* pCur
= pWin
->GetCursor();
2360 aPos
= pWin
->LogicToPixel( pCur
->GetPos() );
2361 aPos
= pWin
->OutputToScreenPixel( aPos
);
2362 Rectangle
aRect( aPos
, aPos
);
2364 OUString aText
= ScGlobal::GetRscString( nStrId
);
2365 sal_uInt16 nAlign
= QUICKHELP_LEFT
|QUICKHELP_BOTTOM
;
2366 nTipVisible
= Help::ShowTip(pWin
, aRect
, aText
, nAlign
);
2371 void ScPosWnd::Select()
2373 ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag
2377 if (!IsTravelSelect())
2381 void ScPosWnd::DoEnter()
2383 OUString aText
= GetText();
2384 if ( !aText
.isEmpty() )
2388 ScModule
* pScMod
= SC_MOD();
2389 if ( aText
== ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE
) )
2391 // Funktions-Autopilot
2392 //! mit dem bisher eingegebenen Text weiterarbeiten !!!
2394 //! new method at ScModule to query if function autopilot is open
2395 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
2396 if ( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) )
2397 pViewFrm
->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION
,
2398 SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
);
2402 ScTabViewShell
* pViewSh
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() );
2403 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
2405 pHdl
->InsertFunction( aText
);
2410 // depending on the input, select something or create a new named range
2412 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2415 ScViewData
* pViewData
= pViewSh
->GetViewData();
2416 ScDocShell
* pDocShell
= pViewData
->GetDocShell();
2417 ScDocument
* pDoc
= pDocShell
->GetDocument();
2419 ScNameInputType eType
= lcl_GetInputType( aText
);
2420 if ( eType
== SC_NAME_INPUT_BAD_NAME
|| eType
== SC_NAME_INPUT_BAD_SELECTION
)
2422 sal_uInt16 nId
= ( eType
== SC_NAME_INPUT_BAD_NAME
) ? STR_NAME_ERROR_NAME
: STR_NAME_ERROR_SELECTION
;
2423 pViewSh
->ErrorMessage( nId
);
2425 else if ( eType
== SC_NAME_INPUT_DEFINE
)
2427 ScRangeName
* pNames
= pDoc
->GetRangeName();
2429 if ( pNames
&& !pNames
->findByUpperName(ScGlobal::pCharClass
->uppercase(aText
)) &&
2430 (pViewData
->GetSimpleArea( aSelection
) == SC_MARK_SIMPLE
) )
2432 ScRangeName
aNewRanges( *pNames
);
2433 ScAddress
aCursor( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
2434 OUString
aContent(aSelection
.Format(SCR_ABS_3D
, pDoc
, pDoc
->GetAddressConvention()));
2435 ScRangeData
* pNew
= new ScRangeData( pDoc
, aText
, aContent
, aCursor
);
2436 if ( aNewRanges
.insert(pNew
) )
2438 pDocShell
->GetDocFunc().ModifyRangeNames( aNewRanges
);
2439 pViewSh
->UpdateInputHandler(true);
2443 else if (eType
== SC_MANAGE_NAMES
)
2445 sal_uInt16 nId
= ScNameDlgWrapper::GetChildWindowId();
2446 SfxViewFrame
* pViewFrm
= pViewSh
->GetViewFrame();
2447 SfxChildWindow
* pWnd
= pViewFrm
->GetChildWindow( nId
);
2449 SC_MOD()->SetRefDialog( nId
, pWnd
? false : sal_True
);
2453 // for all selection types, excecute the SID_CURRENTCELL slot.
2454 if (eType
== SC_NAME_INPUT_CELL
|| eType
== SC_NAME_INPUT_RANGE
)
2456 // Note that SID_CURRENTCELL always expects address to
2457 // be in Calc A1 format. Convert the text.
2458 ScRange
aRange(0,0,pViewData
->GetTabNo());
2459 aRange
.ParseAny(aText
, pDoc
, pDoc
->GetAddressConvention());
2460 aText
= aRange
.Format(SCR_ABS_3D
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
);
2463 SfxStringItem
aPosItem( SID_CURRENTCELL
, aText
);
2464 SfxBoolItem
aUnmarkItem( FN_PARAM_1
, true ); // remove existing selection
2466 pViewSh
->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL
,
2467 SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
,
2468 &aPosItem
, &aUnmarkItem
, 0L );
2476 ReleaseFocus_Impl();
2479 bool ScPosWnd::Notify( NotifyEvent
& rNEvt
)
2481 bool bHandled
= true;
2483 switch (rNEvt
.GetType())
2485 case EVENT_KEYINPUT
:
2487 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
2489 switch ( pKEvt
->GetKeyCode().GetCode() )
2498 // escape when the tip help is shown: only hide the tip
2505 ReleaseFocus_Impl();
2511 case EVENT_GETFOCUS
:
2513 // Select the whole text upon focus.
2514 OUString aStr
= GetText();
2515 SetSelection(Selection(0, aStr
.getLength()));
2518 case EVENT_LOSEFOCUS
:
2527 bHandled
= ComboBox::Notify(rNEvt
);
2532 void ScPosWnd::ReleaseFocus_Impl()
2536 SfxViewShell
* pCurSh
= SfxViewShell::Current();
2537 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell
, pCurSh
) );
2538 if ( pHdl
&& pHdl
->IsTopMode() )
2540 // Focus wieder in die Eingabezeile?
2542 ScInputWindow
* pInputWin
= pHdl
->GetInputWindow();
2545 pInputWin
->TextGrabFocus();
2550 // Focus auf die aktive View
2554 Window
* pShellWnd
= pCurSh
->GetWindow();
2557 pShellWnd
->GrabFocus();
2564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */