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 .
22 #include "scitems.hxx"
23 #include <editeng/eeitem.hxx>
25 #include <sfx2/app.hxx>
26 #include <editeng/adjustitem.hxx>
27 #include <editeng/editview.hxx>
28 #include <editeng/editstat.hxx>
29 #include <editeng/frmdiritem.hxx>
30 #include <editeng/lspcitem.hxx>
31 #include <sfx2/bindings.hxx>
32 #include <sfx2/viewfrm.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/event.hxx>
35 #include <sfx2/imgmgr.hxx>
37 #include <editeng/scriptspaceitem.hxx>
38 #include <editeng/scripttypeitem.hxx>
39 #include <vcl/cursor.hxx>
40 #include <vcl/help.hxx>
41 #include <vcl/settings.hxx>
42 #include <svl/stritem.hxx>
44 #include "inputwin.hxx"
46 #include "uiitems.hxx"
48 #include "scresid.hxx"
50 #include "globstr.hrc"
51 #include "reffact.hxx"
52 #include "editutil.hxx"
53 #include "inputhdl.hxx"
54 #include "tabvwsh.hxx"
55 #include "document.hxx"
57 #include "appoptio.hxx"
58 #include "rangenam.hxx"
59 #include <formula/compiler.hrc>
61 #include "rangeutl.hxx"
62 #include "docfunc.hxx"
63 #include "funcdesc.hxx"
64 #include "markdata.hxx"
65 #include <editeng/fontitem.hxx>
66 #include <com/sun/star/accessibility/XAccessible.hpp>
67 #include "AccessibleEditObject.hxx"
68 #include "AccessibleText.hxx"
69 #include <svtools/miscopt.hxx>
70 #include <comphelper/string.hxx>
71 #include <com/sun/star/frame/XLayoutManager.hpp>
73 #define THESIZE 1000000 // Should be more than enough!
74 #define TBX_WINDOW_HEIGHT 22 // in pixel - TODO: The same on all systems?
75 #define MULTILINE_BUTTON_WIDTH 20 // Width of the button which opens the multiline dropdown
77 #define INPUTWIN_MULTILINES 6
78 const long BUTTON_OFFSET
= 2; ///< space between input line and the button to expand / collapse
79 const long ADDITIONAL_BORDER
= 1; ///< height of the line at the bottom
80 const long ADDITIONAL_SPACE
= 4; ///< additional vertical space when the multiline edit has more lines
82 using com::sun::star::uno::Reference
;
83 using com::sun::star::uno::UNO_QUERY
;
85 using com::sun::star::frame::XLayoutManager
;
86 using com::sun::star::beans::XPropertySet
;
92 SC_NAME_INPUT_NAMEDRANGE
,
93 SC_NAME_INPUT_DATABASE
,
97 SC_NAME_INPUT_BAD_NAME
,
98 SC_NAME_INPUT_BAD_SELECTION
,
102 ScTextWndBase::ScTextWndBase( vcl::Window
* pParent
, WinBits nStyle
)
103 : Window ( pParent
, nStyle
)
105 if ( IsNativeControlSupported( ControlType::Editbox
, ControlPart::Entire
) )
107 SetType( WINDOW_CALCINPUTLINE
);
108 SetBorderStyle( WindowBorderStyle::NWF
);
112 // class ScInputWindowWrapper
114 SFX_IMPL_CHILDWINDOW_WITHID(ScInputWindowWrapper
,FID_INPUTLINE_STATUS
)
116 ScInputWindowWrapper::ScInputWindowWrapper( vcl::Window
* pParentP
,
118 SfxBindings
* pBindings
,
119 SfxChildWinInfo
* /* pInfo */ )
120 : SfxChildWindow( pParentP
, nId
)
122 VclPtr
<ScInputWindow
> pWin
= VclPtr
<ScInputWindow
>::Create( pParentP
, pBindings
);
127 pWin
->SetSizePixel( pWin
->CalcWindowSizePixel() );
129 SetAlignment(SfxChildAlignment::LOWESTTOP
);
130 pBindings
->Invalidate( FID_TOGGLEINPUTLINE
);
134 * GetInfo is disposed of if there's a SFX_IMPL_TOOLBOX!
136 SfxChildWinInfo
ScInputWindowWrapper::GetInfo() const
138 SfxChildWinInfo aInfo
= SfxChildWindow::GetInfo();
142 #define IMAGE(id) pImgMgr->SeekImage(id)
144 // class ScInputWindow
146 static VclPtr
<ScTextWndBase
> lcl_chooseRuntimeImpl( vcl::Window
* pParent
, SfxBindings
* pBind
)
148 ScTabViewShell
* pViewSh
= nullptr;
149 SfxDispatcher
* pDisp
= pBind
->GetDispatcher();
152 SfxViewFrame
* pViewFrm
= pDisp
->GetFrame();
154 pViewSh
= dynamic_cast<ScTabViewShell
*>( pViewFrm
->GetViewShell() );
157 return VclPtr
<ScInputBarGroup
>::Create( pParent
, pViewSh
);
160 ScInputWindow::ScInputWindow( vcl::Window
* pParent
, SfxBindings
* pBind
) :
161 // With WB_CLIPCHILDREN otherwise we get flickering
162 ToolBox ( pParent
, WinBits(WB_CLIPCHILDREN
) ),
163 aWndPos ( VclPtr
<ScPosWnd
>::Create(this) ),
164 pRuntimeWindow ( lcl_chooseRuntimeImpl( this, pBind
) ),
165 aTextWindow ( *pRuntimeWindow
),
166 pInputHdl ( nullptr ),
167 aTextOk ( ScResId( SCSTR_QHELP_BTNOK
) ), // Not always new as a Resource
168 aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL
) ),
169 aTextSum ( ScResId( SCSTR_QHELP_BTNSUM
) ),
170 aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL
) ),
172 bIsOkCancelMode ( false ),
175 ScModule
* pScMod
= SC_MOD();
176 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager(*pScMod
);
178 // #i73615# don't rely on SfxViewShell::Current while constructing the input line
179 // (also for GetInputHdl below)
180 ScTabViewShell
* pViewSh
= nullptr;
181 SfxDispatcher
* pDisp
= pBind
->GetDispatcher();
184 SfxViewFrame
* pViewFrm
= pDisp
->GetFrame();
186 pViewSh
= dynamic_cast<ScTabViewShell
*>( pViewFrm
->GetViewShell() );
188 OSL_ENSURE( pViewSh
, "no view shell for input window" );
190 // Position window, 3 buttons, input window
191 InsertWindow (1, aWndPos
.get(), ToolBoxItemBits::NONE
, 0);
193 InsertItem (SID_INPUT_FUNCTION
, IMAGE(SID_INPUT_FUNCTION
), ToolBoxItemBits::NONE
, 2);
194 InsertItem (SID_INPUT_SUM
, IMAGE(SID_INPUT_SUM
), ToolBoxItemBits::NONE
, 3);
195 InsertItem (SID_INPUT_EQUAL
, IMAGE(SID_INPUT_EQUAL
), ToolBoxItemBits::NONE
, 4);
197 InsertWindow (7, &aTextWindow
, ToolBoxItemBits::NONE
, 6);
199 aWndPos
->SetQuickHelpText(ScResId(SCSTR_QHELP_POSWND
));
200 aWndPos
->SetHelpId (HID_INSWIN_POS
);
201 aTextWindow
.SetQuickHelpText(ScResId(SCSTR_QHELP_INPUTWND
));
202 aTextWindow
.SetHelpId (HID_INSWIN_INPUT
);
204 // No SetHelpText: the helptexts come from the Help
205 SetItemText (SID_INPUT_FUNCTION
, ScResId(SCSTR_QHELP_BTNCALC
));
206 SetHelpId (SID_INPUT_FUNCTION
, HID_INSWIN_CALC
);
208 SetItemText (SID_INPUT_SUM
, aTextSum
);
209 SetHelpId (SID_INPUT_SUM
, HID_INSWIN_SUMME
);
211 SetItemText (SID_INPUT_EQUAL
, aTextEqual
);
212 SetHelpId (SID_INPUT_EQUAL
, HID_INSWIN_FUNC
);
214 SetHelpId( HID_SC_INPUTWIN
); // For the whole input row
219 pInputHdl
= SC_MOD()->GetInputHdl( pViewSh
, false ); // use own handler even if ref-handler is set
221 pInputHdl
->SetInputWindow( this );
223 if (pInputHdl
&& !pInputHdl
->GetFormString().isEmpty())
225 // Switch over while the Function AutoPilot is active
226 // -> show content of the Function AutoPilot again
227 // Also show selection (remember at the InputHdl)
228 aTextWindow
.SetTextString( pInputHdl
->GetFormString() );
230 else if (pInputHdl
&& pInputHdl
->IsInputMode())
232 // If the input row was hidden while editing (e.g. when editing a formula
233 // and then switching to another document or the help), display the text
234 // we just edited from the InputHandler
235 aTextWindow
.SetTextString( pInputHdl
->GetEditString() ); // Display text
236 if ( pInputHdl
->IsTopMode() )
237 pInputHdl
->SetMode( SC_INPUT_TABLE
); // Focus ends up at the bottom anyways
240 pViewSh
->UpdateInputHandler(true); // Absolutely necessary update
242 pImgMgr
->RegisterToolBox(this);
243 SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA
));
246 ScInputWindow::~ScInputWindow()
251 void ScInputWindow::dispose()
253 bool bDown
= ( ScGlobal::pSysLocale
== nullptr ); // after Clear?
255 // if any view's input handler has a pointer to this input window, reset it
256 // (may be several ones, #74522#)
257 // member pInputHdl is not used here
261 SfxViewShell
* pSh
= SfxViewShell::GetFirst( true, checkSfxViewShell
<ScTabViewShell
> );
264 ScInputHandler
* pHdl
= static_cast<ScTabViewShell
*>(pSh
)->GetInputHandler();
265 if ( pHdl
&& pHdl
->GetInputWindow() == this )
267 pHdl
->SetInputWindow( nullptr );
268 pHdl
->StopInputWinEngine( false ); // reset pTopView pointer
270 pSh
= SfxViewShell::GetNext( *pSh
, true, checkSfxViewShell
<ScTabViewShell
> );
274 SfxImageManager::GetImageManager( *SC_MOD() )->ReleaseToolBox( this );
276 pRuntimeWindow
.disposeAndClear();
277 aWndPos
.disposeAndClear();
282 void ScInputWindow::SetInputHandler( ScInputHandler
* pNew
)
284 // Is called in the Activate of the View ...
285 if ( pNew
!= pInputHdl
)
287 // On Reload (last version) the pInputHdl is the InputHandler of the old, deleted
288 // ViewShell: so don't touch it here!
291 pInputHdl
->SetInputWindow( this );
295 bool ScInputWindow::UseSubTotal(ScRangeList
* pRangeList
)
297 bool bSubTotal
= false;
298 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>( SfxViewShell::Current() );
301 ScDocument
* pDoc
= pViewSh
->GetViewData().GetDocument();
302 size_t nRangeCount (pRangeList
->size());
303 size_t nRangeIndex (0);
304 while (!bSubTotal
&& nRangeIndex
< nRangeCount
)
306 const ScRange
* pRange
= (*pRangeList
)[nRangeIndex
];
309 SCTAB
nTabEnd(pRange
->aEnd
.Tab());
310 SCTAB
nTab(pRange
->aStart
.Tab());
311 while (!bSubTotal
&& nTab
<= nTabEnd
)
313 SCROW
nRowEnd(pRange
->aEnd
.Row());
314 SCROW
nRow(pRange
->aStart
.Row());
315 while (!bSubTotal
&& nRow
<= nRowEnd
)
317 if (pDoc
->RowFiltered(nRow
, nTab
))
328 const ScDBCollection::NamedDBs
& rDBs
= pDoc
->GetDBCollection()->getNamedDBs();
329 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
330 for (; !bSubTotal
&& itr
!= itrEnd
; ++itr
)
332 const ScDBData
& rDB
= **itr
;
333 if (!rDB
.HasAutoFilter())
337 while (!bSubTotal
&& nRangeIndex
< nRangeCount
)
339 const ScRange
* pRange
= (*pRangeList
)[nRangeIndex
];
343 rDB
.GetArea(aDBArea
);
344 if (aDBArea
.Intersects(*pRange
))
354 void ScInputWindow::Select()
356 ScModule
* pScMod
= SC_MOD();
359 switch ( GetCurItemId() )
361 case SID_INPUT_FUNCTION
:
363 //! new method at ScModule to query if function autopilot is open
364 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
365 if ( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) )
367 pViewFrm
->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION
,
368 SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
);
370 // The Toolbox will be disabled anyways, so we don't need to switch here,
371 // regardless whether it succeeded or not!
372 // SetOkCancelMode();
377 case SID_INPUT_CANCEL
:
378 pScMod
->InputCancelHandler();
383 pScMod
->InputEnterHandler();
385 aTextWindow
.Invalidate(); // Or else the Selection remains
390 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>( SfxViewShell::Current() );
393 const ScMarkData
& rMark
= pViewSh
->GetViewData().GetMarkData();
394 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
396 ScRangeList aMarkRangeList
;
397 rMark
.FillRangeListWithMarks( &aMarkRangeList
, false );
398 ScDocument
* pDoc
= pViewSh
->GetViewData().GetDocument();
400 // check if one of the marked ranges is empty
402 const size_t nCount
= aMarkRangeList
.size();
403 for ( size_t i
= 0; i
< nCount
; ++i
)
405 const ScRange
aRange( *aMarkRangeList
[i
] );
406 if ( pDoc
->IsBlockEmpty( aRange
.aStart
.Tab(),
407 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
408 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() ) )
417 ScRangeList aRangeList
;
418 const bool bDataFound
= pViewSh
->GetAutoSumArea( aRangeList
);
421 ScAddress aAddr
= aRangeList
.back()->aEnd
;
423 const bool bSubTotal( UseSubTotal( &aRangeList
) );
424 pViewSh
->EnterAutoSum( aRangeList
, bSubTotal
, aAddr
);
429 const bool bSubTotal( UseSubTotal( &aMarkRangeList
) );
430 for ( size_t i
= 0; i
< nCount
; ++i
)
432 const ScRange
aRange( *aMarkRangeList
[i
] );
433 const bool bSetCursor
= ( i
== nCount
- 1 );
434 const bool bContinue
= ( i
!= 0 );
435 if ( !pViewSh
->AutoSum( aRange
, bSubTotal
, bSetCursor
, bContinue
) )
437 pViewSh
->MarkRange( aRange
, false );
438 pViewSh
->SetCursor( aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
439 const ScRangeList aRangeList
;
440 ScAddress aAddr
= aRange
.aEnd
;
442 const OUString aFormula
= pViewSh
->GetAutoSumFormula(
443 aRangeList
, bSubTotal
, aAddr
);
444 SetFuncString( aFormula
);
450 else // Only insert into input row
452 ScRangeList aRangeList
;
453 const bool bDataFound
= pViewSh
->GetAutoSumArea( aRangeList
);
454 const bool bSubTotal( UseSubTotal( &aRangeList
) );
455 ScAddress aAddr
= pViewSh
->GetViewData().GetCurPos();
456 const OUString aFormula
= pViewSh
->GetAutoSumFormula( aRangeList
, bSubTotal
, aAddr
);
457 SetFuncString( aFormula
);
459 if ( bDataFound
&& pScMod
->IsEditMode() )
461 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
464 pHdl
->InitRangeFinder( aFormula
);
466 //! SetSelection at the InputHandler?
468 const sal_Int32 nOpen
= aFormula
.indexOf('(');
469 const sal_Int32 nLen
= aFormula
.getLength();
470 if ( nOpen
!= -1 && nLen
> nOpen
)
475 ESelection
aSel(0,nOpen
+nAdd
,0,nLen
-1);
476 EditView
* pTableView
= pHdl
->GetTableView();
478 pTableView
->SetSelection(aSel
);
479 EditView
* pTopView
= pHdl
->GetTopView();
481 pTopView
->SetSelection(aSel
);
490 case SID_INPUT_EQUAL
:
492 aTextWindow
.StartEditEngine();
493 if ( pScMod
->IsEditMode() ) // Isn't if e.g. protected
495 aTextWindow
.StartEditEngine();
497 sal_Int32 nStartPos
= 1;
498 sal_Int32 nEndPos
= 1;
500 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>( SfxViewShell::Current() );
503 const OUString
& rString
= aTextWindow
.GetTextString();
504 const sal_Int32 nLen
= rString
.getLength();
506 ScDocument
* pDoc
= pViewSh
->GetViewData().GetDocument();
507 CellType eCellType
= pDoc
->GetCellType( pViewSh
->GetViewData().GetCurPos() );
513 aTextWindow
.SetTextString("=" + rString
);
516 case CELLTYPE_STRING
:
521 case CELLTYPE_FORMULA
:
525 aTextWindow
.SetTextString("=");
530 EditView
* pView
= aTextWindow
.GetEditView();
533 pView
->SetSelection( ESelection(0, nStartPos
, 0, nEndPos
) );
534 pScMod
->InputChanged(pView
);
536 pView
->SetEditEngineUpdateMode(true);
544 void ScInputWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
546 ToolBox::Paint(rRenderContext
, rRect
);
548 // draw a line at the bottom to distinguish that from the grid
549 // (we have space for that thanks to ADDITIONAL_BORDER)
550 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
551 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
553 Size aSize
= GetSizePixel();
554 rRenderContext
.DrawLine(Point(0, aSize
.Height() - 1),
555 Point(aSize
.Width() - 1, aSize
.Height() - 1));
558 void ScInputWindow::Resize()
562 aTextWindow
.Resize();
563 Size aSize
= GetSizePixel();
564 aSize
.Height() = CalcWindowSizePixel().Height() + ADDITIONAL_BORDER
;
565 ScInputBarGroup
* pGroupBar
= dynamic_cast<ScInputBarGroup
*>(pRuntimeWindow
.get());
568 // To ensure smooth display and prevent the items in the toolbar being
569 // repositioned ( vertically ) we lock the vertical positioning of the toolbox
570 // items when we are displaying > 1 line.
571 // So, we need to adjust the height of the toolbox accordingly. If we don't
572 // then the largest item ( e.g. the GroupBar window ) will actually be
573 // positioned such that the toolbar will cut off the bottom of that item
574 if (pGroupBar
->GetNumLines() > 1)
575 aSize
.Height() += pGroupBar
->GetVertOffset() + ADDITIONAL_SPACE
;
581 void ScInputWindow::SetFuncString( const OUString
& rString
, bool bDoEdit
)
583 //! new method at ScModule to query if function autopilot is open
584 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
585 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
586 aTextWindow
.StartEditEngine();
588 ScModule
* pScMod
= SC_MOD();
589 if ( pScMod
->IsEditMode() )
592 aTextWindow
.GrabFocus();
593 aTextWindow
.SetTextString( rString
);
594 EditView
* pView
= aTextWindow
.GetEditView();
597 sal_Int32 nLen
= rString
.getLength();
602 pView
->SetSelection( ESelection( 0, nLen
, 0, nLen
) );
605 pScMod
->InputChanged(pView
);
607 SetOkCancelMode(); // Not the case if immediately followed by Enter/Cancel
609 pView
->SetEditEngineUpdateMode(true);
614 void ScInputWindow::SetPosString( const OUString
& rStr
)
616 aWndPos
->SetPos( rStr
);
619 void ScInputWindow::SetTextString( const OUString
& rString
)
621 if (rString
.getLength() <= 32767)
622 aTextWindow
.SetTextString(rString
);
624 aTextWindow
.SetTextString(rString
.copy(0, 32767));
627 void ScInputWindow::SetOkCancelMode()
629 //! new method at ScModule to query if function autopilot is open
630 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
631 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
633 ScModule
* pScMod
= SC_MOD();
634 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager(*pScMod
);
635 if (!bIsOkCancelMode
)
637 RemoveItem( 3 ); // Remove SID_INPUT_SUM and SID_INPUT_EQUAL
639 InsertItem( SID_INPUT_CANCEL
, IMAGE( SID_INPUT_CANCEL
), ToolBoxItemBits::NONE
, 3 );
640 InsertItem( SID_INPUT_OK
, IMAGE( SID_INPUT_OK
), ToolBoxItemBits::NONE
, 4 );
641 SetItemText ( SID_INPUT_CANCEL
, aTextCancel
);
642 SetHelpId ( SID_INPUT_CANCEL
, HID_INSWIN_CANCEL
);
643 SetItemText ( SID_INPUT_OK
, aTextOk
);
644 SetHelpId ( SID_INPUT_OK
, HID_INSWIN_OK
);
645 bIsOkCancelMode
= true;
649 void ScInputWindow::SetSumAssignMode()
651 //! new method at ScModule to query if function autopilot is open
652 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
653 EnableButtons( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) );
655 ScModule
* pScMod
= SC_MOD();
656 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager(*pScMod
);
659 // Remove SID_INPUT_CANCEL, and SID_INPUT_OK
662 InsertItem( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
), ToolBoxItemBits::NONE
, 3 );
663 InsertItem( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
), ToolBoxItemBits::NONE
, 4 );
664 SetItemText ( SID_INPUT_SUM
, aTextSum
);
665 SetHelpId ( SID_INPUT_SUM
, HID_INSWIN_SUMME
);
666 SetItemText ( SID_INPUT_EQUAL
, aTextEqual
);
667 SetHelpId ( SID_INPUT_EQUAL
, HID_INSWIN_FUNC
);
668 bIsOkCancelMode
= false;
670 SetFormulaMode(false); // No editing -> no formula
674 void ScInputWindow::SetFormulaMode( bool bSet
)
676 aWndPos
->SetFormulaMode(bSet
);
677 aTextWindow
.SetFormulaMode(bSet
);
680 void ScInputWindow::SetText( const OUString
& rString
)
682 ToolBox::SetText(rString
);
685 OUString
ScInputWindow::GetText() const
687 return ToolBox::GetText();
690 bool ScInputWindow::IsInputActive()
692 return aTextWindow
.IsInputActive();
695 EditView
* ScInputWindow::GetEditView()
697 return aTextWindow
.GetEditView();
700 void ScInputWindow::MakeDialogEditView()
702 aTextWindow
.MakeDialogEditView();
705 void ScInputWindow::StopEditEngine( bool bAll
)
707 aTextWindow
.StopEditEngine( bAll
);
710 void ScInputWindow::TextGrabFocus()
712 aTextWindow
.TextGrabFocus();
715 void ScInputWindow::TextInvalidate()
717 aTextWindow
.Invalidate();
720 void ScInputWindow::SwitchToTextWin()
722 // used for shift-ctrl-F2
724 aTextWindow
.StartEditEngine();
725 if ( SC_MOD()->IsEditMode() )
727 aTextWindow
.TextGrabFocus();
728 EditView
* pView
= aTextWindow
.GetEditView();
731 sal_Int32 nPara
= pView
->GetEditEngine()->GetParagraphCount() ? ( pView
->GetEditEngine()->GetParagraphCount() - 1 ) : 0;
732 sal_Int32 nLen
= pView
->GetEditEngine()->GetTextLen( nPara
);
733 ESelection
aSel( nPara
, nLen
, nPara
, nLen
);
734 pView
->SetSelection( aSel
); // set cursor to end of text
739 void ScInputWindow::PosGrabFocus()
741 aWndPos
->GrabFocus();
744 void ScInputWindow::EnableButtons( bool bEnable
)
746 // when enabling buttons, always also enable the input window itself
747 if ( bEnable
&& !IsEnabled() )
750 EnableItem( SID_INPUT_FUNCTION
, bEnable
);
751 EnableItem( bIsOkCancelMode
? SID_INPUT_CANCEL
: SID_INPUT_SUM
, bEnable
);
752 EnableItem( bIsOkCancelMode
? SID_INPUT_OK
: SID_INPUT_EQUAL
, bEnable
);
756 void ScInputWindow::StateChanged( StateChangedType nType
)
758 ToolBox::StateChanged( nType
);
760 if ( nType
== StateChangedType::InitShow
) Resize();
763 void ScInputWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
765 if ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
&& (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
767 // update item images
768 ScModule
* pScMod
= SC_MOD();
769 SfxImageManager
* pImgMgr
= SfxImageManager::GetImageManager(*pScMod
);
771 // IMAGE macro uses pScMod, pImgMg
772 SetItemImage( SID_INPUT_FUNCTION
, IMAGE( SID_INPUT_FUNCTION
) );
773 if ( bIsOkCancelMode
)
775 SetItemImage( SID_INPUT_CANCEL
, IMAGE( SID_INPUT_CANCEL
) );
776 SetItemImage( SID_INPUT_OK
, IMAGE( SID_INPUT_OK
) );
780 SetItemImage( SID_INPUT_SUM
, IMAGE( SID_INPUT_SUM
) );
781 SetItemImage( SID_INPUT_EQUAL
, IMAGE( SID_INPUT_EQUAL
) );
785 ToolBox::DataChanged( rDCEvt
);
788 bool ScInputWindow::IsPointerAtResizePos()
790 if ( GetOutputSizePixel().Height() - GetPointerPosPixel().Y() <= 4 )
796 void ScInputWindow::MouseMove( const MouseEvent
& rMEvt
)
798 Point aPosPixel
= GetPointerPosPixel();
800 ScInputBarGroup
* pGroupBar
= dynamic_cast<ScInputBarGroup
*>(pRuntimeWindow
.get());
802 if (bInResize
|| IsPointerAtResizePos())
803 SetPointer(Pointer(PointerStyle::WindowSSize
));
805 SetPointer(Pointer(PointerStyle::Arrow
));
810 long nResizeThreshold
= ((long)TBX_WINDOW_HEIGHT
* 0.7);
811 bool bResetPointerPos
= false;
813 // Detect attempt to expand toolbar too much
814 if (aPosPixel
.Y() >= mnMaxY
)
816 bResetPointerPos
= true;
817 aPosPixel
.Y() = mnMaxY
;
818 } // or expanding down
819 else if (GetOutputSizePixel().Height() - aPosPixel
.Y() < -nResizeThreshold
)
821 pGroupBar
->IncrementVerticalSize();
822 bResetPointerPos
= true;
824 else if ((GetOutputSizePixel().Height() - aPosPixel
.Y()) > nResizeThreshold
)
826 bResetPointerPos
= true;
827 pGroupBar
->DecrementVerticalSize();
830 if (bResetPointerPos
)
832 aPosPixel
.Y() = GetOutputSizePixel().Height();
833 SetPointerPosPixel(aPosPixel
);
837 ToolBox::MouseMove(rMEvt
);
840 void ScInputWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
844 if (IsPointerAtResizePos())
846 // 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 // calculate 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
)
866 if ( rMEvt
.IsLeft() )
872 ToolBox::MouseButtonUp( rMEvt
);
875 ScInputBarGroup::ScInputBarGroup(vcl::Window
* pParent
, ScTabViewShell
* pViewSh
)
876 : ScTextWndBase(pParent
, WinBits(WB_HIDE
| WB_TABSTOP
)),
877 maTextWnd(VclPtr
<ScTextWnd
>::Create(this, pViewSh
)),
878 maButton(VclPtr
<ImageButton
>::Create(this, WB_TABSTOP
| WB_RECTSTYLE
| WB_SMALLSTYLE
)),
879 maScrollbar(VclPtr
<ScrollBar
>::Create(this, WB_TABSTOP
| WB_VERT
| WB_DRAG
)),
883 maTextWnd
->SetQuickHelpText(ScResId(SCSTR_QHELP_INPUTWND
));
884 maTextWnd
->SetHelpId(HID_INSWIN_INPUT
);
886 Size
aSize(MULTILINE_BUTTON_WIDTH
, maTextWnd
->GetPixelHeightForLines(1));
888 maButton
->SetClickHdl(LINK(this, ScInputBarGroup
, ClickHdl
));
889 maButton
->SetSizePixel(aSize
);
891 maButton
->SetSymbol(SymbolType::SPIN_DOWN
);
892 maButton
->SetQuickHelpText(ScResId(SCSTR_QHELP_EXPAND_FORMULA
));
895 maScrollbar
->SetSizePixel(aSize
);
896 maScrollbar
->SetScrollHdl(LINK(this, ScInputBarGroup
, Impl_ScrollHdl
));
899 ScInputBarGroup::~ScInputBarGroup()
904 void ScInputBarGroup::dispose()
906 maTextWnd
.disposeAndClear();
907 maButton
.disposeAndClear();
908 maScrollbar
.disposeAndClear();
909 ScTextWndBase::dispose();
912 void ScInputBarGroup::InsertAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
914 maTextWnd
->InsertAccessibleTextData( rTextData
);
917 void ScInputBarGroup::RemoveAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
919 maTextWnd
->RemoveAccessibleTextData( rTextData
);
922 const OUString
& ScInputBarGroup::GetTextString() const
924 return maTextWnd
->GetTextString();
927 void ScInputBarGroup::SetTextString( const OUString
& rString
)
929 maTextWnd
->SetTextString(rString
);
932 void ScInputBarGroup::Resize()
934 vcl::Window
*w
= GetParent();
935 ScInputWindow
*pParent
;
936 pParent
= dynamic_cast<ScInputWindow
*>(w
);
938 if (pParent
== nullptr)
940 OSL_FAIL("The parent window pointer pParent is null");
944 long nWidth
= pParent
->GetSizePixel().Width();
945 long nLeft
= GetPosPixel().X();
947 Size aSize
= GetSizePixel();
948 aSize
.Width() = std::max(long(nWidth
- nLeft
- LEFT_OFFSET
), long(0));
950 maScrollbar
->SetPosPixel(Point( aSize
.Width() - maButton
->GetSizePixel().Width(), maButton
->GetSizePixel().Height() ) );
952 Size
aTmpSize( aSize
);
953 aTmpSize
.Width() = aTmpSize
.Width() - maButton
->GetSizePixel().Width() - BUTTON_OFFSET
;
954 maTextWnd
->SetSizePixel(aTmpSize
);
958 aSize
.Height() = maTextWnd
->GetSizePixel().Height();
962 if (maTextWnd
->GetNumLines() > 1)
964 maButton
->SetSymbol( SymbolType::SPIN_UP
);
965 maButton
->SetQuickHelpText( ScResId( SCSTR_QHELP_COLLAPSE_FORMULA
) );
966 Size scrollSize
= maButton
->GetSizePixel();
967 scrollSize
.Height() = maTextWnd
->GetSizePixel().Height() - maButton
->GetSizePixel().Height();
968 maScrollbar
->SetSizePixel( scrollSize
);
970 Size aOutSz
= maTextWnd
->GetOutputSize();
972 maScrollbar
->SetVisibleSize( aOutSz
.Height() );
973 maScrollbar
->SetPageSize( aOutSz
.Height() );
974 maScrollbar
->SetLineSize( maTextWnd
->GetTextHeight() );
975 maScrollbar
->SetRange( Range( 0, maTextWnd
->GetEditEngTxtHeight() ) );
977 maScrollbar
->Resize();
982 maButton
->SetSymbol( SymbolType::SPIN_DOWN
);
983 maButton
->SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA
) );
987 maButton
->SetPosPixel(Point(aSize
.Width() - maButton
->GetSizePixel().Width(), 0));
992 void ScInputBarGroup::StopEditEngine( bool bAll
)
994 maTextWnd
->StopEditEngine( bAll
);
997 void ScInputBarGroup::StartEditEngine()
999 maTextWnd
->StartEditEngine();
1002 void ScInputBarGroup::MakeDialogEditView()
1004 maTextWnd
->MakeDialogEditView();
1007 EditView
* ScInputBarGroup::GetEditView()
1009 return maTextWnd
->GetEditView();
1012 bool ScInputBarGroup::IsInputActive()
1014 return maTextWnd
->IsInputActive();
1017 void ScInputBarGroup::SetFormulaMode(bool bSet
)
1019 maTextWnd
->SetFormulaMode(bSet
);
1022 void ScInputBarGroup::IncrementVerticalSize()
1024 maTextWnd
->SetNumLines( maTextWnd
->GetNumLines() + 1 );
1025 TriggerToolboxLayout();
1028 void ScInputBarGroup::DecrementVerticalSize()
1030 if ( maTextWnd
->GetNumLines() > 1 )
1032 maTextWnd
->SetNumLines( maTextWnd
->GetNumLines() - 1 );
1033 TriggerToolboxLayout();
1037 IMPL_LINK_NOARG_TYPED(ScInputBarGroup
, ClickHdl
, Button
*, void)
1039 vcl::Window
* w
= GetParent();
1040 ScInputWindow
* pParent
;
1041 pParent
= dynamic_cast<ScInputWindow
*>(w
);
1043 if (pParent
== nullptr)
1045 OSL_FAIL("The parent window pointer pParent is null");
1048 if (maTextWnd
->GetNumLines() > 1)
1050 maTextWnd
->SetNumLines(1);
1054 maTextWnd
->SetNumLines(maTextWnd
->GetLastNumExpandedLines());
1056 TriggerToolboxLayout();
1058 // Restore focus to input line(s) if necessary
1059 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1060 if ( pHdl
&& pHdl
->IsTopMode() )
1061 maTextWnd
->GrabFocus();
1064 void ScInputBarGroup::TriggerToolboxLayout()
1066 vcl::Window
*w
=GetParent();
1067 ScInputWindow
&rParent
= dynamic_cast<ScInputWindow
&>(*w
);
1068 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1070 // Capture the vertical position of this window in the toolbar, when we increase
1071 // the size of the toolbar to accommodate expanded line input we need to take this
1073 if ( !mnVertOffset
)
1074 mnVertOffset
= rParent
.GetItemPosRect( rParent
.GetItemCount() - 1 ).Top();
1078 Reference
< css::beans::XPropertySet
> xPropSet( pViewFrm
->GetFrame().GetFrameInterface(), UNO_QUERY
);
1079 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1081 if ( xPropSet
.is() )
1083 css::uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1084 aValue
>>= xLayoutManager
;
1087 if ( xLayoutManager
.is() )
1089 if ( maTextWnd
->GetNumLines() > 1)
1090 rParent
.SetToolbarLayoutMode( TBX_LAYOUT_LOCKVERT
);
1092 rParent
.SetToolbarLayoutMode( TBX_LAYOUT_NORMAL
);
1093 xLayoutManager
->lock();
1094 DataChangedEvent
aFakeUpdate( DataChangedEventType::SETTINGS
, nullptr, AllSettingsFlags::STYLE
);
1096 // this basically will trigger the reposititioning of the
1097 // items in the toolbar from ImplFormat ( which is controlled by
1098 // mnWinHeight ) which in turn is updated in ImplCalcItem which is
1099 // controlled by mbCalc. Additionally the ImplFormat above is
1100 // controlled via mbFormat. It seems the easiest way to get these
1101 // booleans set is to send in the fake event below.
1102 rParent
.DataChanged( aFakeUpdate
);
1104 // highest item in toolbar will have been calculated via the
1105 // event above. Call resize on InputBar to pick up the height
1109 // unlock relayouts the toolbars in the 4 quadrants
1110 xLayoutManager
->unlock();
1115 IMPL_LINK_NOARG_TYPED(ScInputBarGroup
, Impl_ScrollHdl
, ScrollBar
*, void)
1117 maTextWnd
->DoScroll();
1120 void ScInputBarGroup::TextGrabFocus()
1122 maTextWnd
->TextGrabFocus();
1125 void ScTextWnd::Paint( vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
1127 EditView
* pView
= GetEditView();
1132 pView
->Invalidate();
1133 mbInvalidate
= false;
1135 pEditView
->Paint(rRect
, &rRenderContext
);
1139 EditView
* ScTextWnd::GetEditView()
1146 long ScTextWnd::GetPixelHeightForLines(long nLines
)
1148 // add padding ( for the borders of the window )
1149 return ( nLines
* LogicToPixel( Size( 0, GetTextHeight() ) ).Height() ) + mnBorderHeight
;
1152 void ScTextWnd::SetNumLines(long nLines
)
1157 mnLastExpandedLines
= nLines
;
1162 void ScTextWnd::Resize()
1164 // Only Height is recalculated here, Width is applied from
1165 // parent/container window
1166 Size aTextBoxSize
= GetSizePixel();
1168 aTextBoxSize
.Height() = GetPixelHeightForLines( mnLines
);
1169 SetSizePixel( aTextBoxSize
);
1173 Size aOutputSize
= GetOutputSizePixel();
1174 Rectangle aOutputArea
= PixelToLogic( Rectangle( Point(), aOutputSize
));
1175 pEditView
->SetOutputArea( aOutputArea
);
1177 // Don't leave an empty area at the bottom if we can move the text down.
1178 long nMaxVisAreaTop
= pEditEngine
->GetTextHeight() - aOutputArea
.GetHeight();
1179 if (pEditView
->GetVisArea().Top() > nMaxVisAreaTop
)
1181 pEditView
->Scroll(0, pEditView
->GetVisArea().Top() - nMaxVisAreaTop
);
1184 pEditEngine
->SetPaperSize( PixelToLogic( Size( aOutputSize
.Width(), 10000 ) ) );
1187 SetScrollBarRange();
1190 long ScTextWnd::GetEditEngTxtHeight()
1192 return pEditView
? pEditView
->GetEditEngine()->GetTextHeight() : 0;
1195 void ScTextWnd::SetScrollBarRange()
1199 ScrollBar
& rVBar
= mrGroupBar
.GetScrollBar();
1200 rVBar
.SetRange( Range( 0, GetEditEngTxtHeight() ) );
1201 long currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1202 rVBar
.SetThumbPos( currentDocPos
);
1206 void ScTextWnd::DoScroll()
1210 ScrollBar
& rVBar
= mrGroupBar
.GetScrollBar();
1211 long currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1212 long nDiff
= currentDocPos
- rVBar
.GetThumbPos();
1213 pEditView
->Scroll( 0, nDiff
);
1214 currentDocPos
= pEditView
->GetVisArea().TopLeft().Y();
1215 rVBar
.SetThumbPos( currentDocPos
);
1219 void ScTextWnd::StartEditEngine()
1221 // Don't activate if we're a modal dialog ourselves (Doc-modal dialog)
1222 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1223 if ( pObjSh
&& pObjSh
->IsInModalMode() )
1226 if ( !pEditView
|| !pEditEngine
)
1231 SC_MOD()->SetInputMode( SC_INPUT_TOP
);
1233 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1235 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1238 static void lcl_ExtendEditFontAttribs( SfxItemSet
& rSet
)
1240 const SfxPoolItem
& rFontItem
= rSet
.Get( EE_CHAR_FONTINFO
);
1241 rSet
.Put( rFontItem
, EE_CHAR_FONTINFO_CJK
);
1242 rSet
.Put( rFontItem
, EE_CHAR_FONTINFO_CTL
);
1243 const SfxPoolItem
& rHeightItem
= rSet
.Get( EE_CHAR_FONTHEIGHT
);
1244 rSet
.Put( rHeightItem
, EE_CHAR_FONTHEIGHT_CJK
);
1245 rSet
.Put( rHeightItem
, EE_CHAR_FONTHEIGHT_CTL
);
1246 const SfxPoolItem
& rWeightItem
= rSet
.Get( EE_CHAR_WEIGHT
);
1247 rSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CJK
);
1248 rSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CTL
);
1249 const SfxPoolItem
& rItalicItem
= rSet
.Get( EE_CHAR_ITALIC
);
1250 rSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CJK
);
1251 rSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CTL
);
1252 const SfxPoolItem
& rLangItem
= rSet
.Get( EE_CHAR_LANGUAGE
);
1253 rSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CJK
);
1254 rSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CTL
);
1257 static void lcl_ModifyRTLDefaults( SfxItemSet
& rSet
)
1259 rSet
.Put( SvxAdjustItem( SVX_ADJUST_RIGHT
, EE_PARA_JUST
) );
1261 // always using rtl writing direction would break formulas
1262 //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1264 // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
1265 // sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be
1266 // increased to not see the beginning of the next line.
1267 SvxLineSpacingItem
aItem( SVX_LINESPACE_TWO_LINES
, EE_PARA_SBL
);
1268 aItem
.SetPropLineSpace( 200 );
1272 static void lcl_ModifyRTLVisArea( EditView
* pEditView
)
1274 Rectangle aVisArea
= pEditView
->GetVisArea();
1275 Size aPaper
= pEditView
->GetEditEngine()->GetPaperSize();
1276 long nDiff
= aPaper
.Width() - aVisArea
.Right();
1277 aVisArea
.Left() += nDiff
;
1278 aVisArea
.Right() += nDiff
;
1279 pEditView
->SetVisArea(aVisArea
);
1282 void ScTextWnd::InitEditEngine()
1284 ScFieldEditEngine
* pNew
;
1285 ScTabViewShell
* pViewSh
= GetViewShell();
1286 ScDocShell
* pDocSh
= nullptr;
1289 pDocSh
= pViewSh
->GetViewData().GetDocShell();
1290 ScDocument
* pDoc
= pViewSh
->GetViewData().GetDocument();
1291 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1294 pNew
= new ScFieldEditEngine(nullptr, EditEngine::CreatePool(), nullptr, true);
1295 pNew
->SetExecuteURL( false );
1298 Size barSize
=GetSizePixel();
1299 pEditEngine
->SetUpdateMode( false );
1300 pEditEngine
->SetPaperSize( PixelToLogic(Size(barSize
.Width(),10000)) );
1301 pEditEngine
->SetWordDelimiters(
1302 ScEditUtil::ModifyDelimiters( pEditEngine
->GetWordDelimiters() ) );
1303 pEditEngine
->SetReplaceLeadingSingleQuotationMark( false );
1305 UpdateAutoCorrFlag();
1308 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1309 EditEngine::SetFontInfoInItemSet( *pSet
, aTextFont
);
1310 lcl_ExtendEditFontAttribs( *pSet
);
1311 // turn off script spacing to match DrawText output
1312 pSet
->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING
) );
1314 lcl_ModifyRTLDefaults( *pSet
);
1315 pEditEngine
->SetDefaults( pSet
);
1318 // If the Cell contains URLFields, they need to be taken over into the entry row,
1319 // or else the position is not correct anymore
1320 bool bFilled
= false;
1321 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1322 if ( pHdl
) //! Test if it's the right InputHdl?
1323 bFilled
= pHdl
->GetTextAndFields( *pEditEngine
);
1325 pEditEngine
->SetUpdateMode( true );
1327 // aString is the truth ...
1328 if (bFilled
&& pEditEngine
->GetText() == aString
)
1329 Invalidate(); // Repaint for (filled) Field
1331 pEditEngine
->SetText(aString
); // At least the right text then
1333 pEditView
= new EditView( pEditEngine
, this );
1334 pEditView
->SetInsertMode(bIsInsertMode
);
1336 // Text from Clipboard is taken over as ASCII in a single row
1337 EVControlBits n
= pEditView
->GetControlWord();
1338 pEditView
->SetControlWord( n
| EVControlBits::SINGLELINEPASTE
);
1340 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1345 lcl_ModifyRTLVisArea( pEditView
);
1347 pEditEngine
->SetModifyHdl(LINK(this, ScTextWnd
, ModifyHdl
));
1348 pEditEngine
->SetNotifyHdl(LINK(this, ScTextWnd
, NotifyHdl
));
1350 if (!maAccTextDatas
.empty())
1351 maAccTextDatas
.back()->StartEdit();
1353 // as long as EditEngine and DrawText sometimes differ for CTL text,
1354 // repaint now to have the EditEngine's version visible
1357 ScDocument
& rDoc
= pDocSh
->GetDocument(); // any document
1358 SvtScriptType nScript
= rDoc
.GetStringScriptType( aString
);
1359 if ( nScript
& SvtScriptType::COMPLEX
)
1364 ScTextWnd::ScTextWnd(ScInputBarGroup
* pParent
, ScTabViewShell
* pViewSh
)
1365 : ScTextWndBase(pParent
, WinBits(WB_HIDE
| WB_BORDER
)),
1366 DragSourceHelper(this),
1367 pEditEngine (nullptr),
1368 pEditView (nullptr),
1369 bIsInsertMode(true),
1370 bFormulaMode (false),
1372 mpViewShell(pViewSh
),
1373 mrGroupBar(*pParent
),
1375 mnLastExpandedLines(INPUTWIN_MULTILINES
),
1378 EnableRTL(false); // EditEngine can't be used with VCL EnableRTL
1380 bIsRTL
= AllSettings::GetLayoutRTL();
1382 // always use application font, so a font with cjk chars can be installed
1383 vcl::Font aAppFont
= GetFont();
1384 aTextFont
= aAppFont
;
1385 aTextFont
.SetFontSize(PixelToLogic(aAppFont
.GetFontSize(), MAP_TWIP
)); // AppFont is in pixels
1387 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1389 Color aBgColor
= rStyleSettings
.GetWindowColor();
1390 Color aTxtColor
= rStyleSettings
.GetWindowTextColor();
1392 aTextFont
.SetTransparent(true);
1393 aTextFont
.SetFillColor(aBgColor
);
1394 aTextFont
.SetColor(aTxtColor
);
1395 aTextFont
.SetWeight(WEIGHT_NORMAL
);
1397 Size
aSize(1,TBX_WINDOW_HEIGHT
);
1398 Size
aMinEditSize( Edit::GetMinimumEditSize() );
1399 if( aMinEditSize
.Height() > aSize
.Height() )
1400 aSize
.Height() = aMinEditSize
.Height();
1402 SetSizePixel(aSize
);
1403 SetBackground(aBgColor
);
1404 SetLineColor(COL_BLACK
);
1405 SetMapMode(MAP_TWIP
);
1406 SetPointer(PointerStyle::Text
);
1410 aBorder
= CalcWindowSize(aBorder
);
1411 mnBorderHeight
= aBorder
.Height();
1414 ScTextWnd::~ScTextWnd()
1419 void ScTextWnd::dispose()
1421 while (!maAccTextDatas
.empty()) {
1422 maAccTextDatas
.back()->Dispose();
1425 pEditView
= nullptr;
1427 pEditEngine
= nullptr;
1429 ScTextWndBase::dispose();
1432 void ScTextWnd::MouseMove( const MouseEvent
& rMEvt
)
1435 pEditView
->MouseMove( rMEvt
);
1438 void ScTextWnd::MouseButtonDown( const MouseEvent
& rMEvt
)
1443 if ( SC_MOD()->IsEditMode() )
1449 pEditView
->SetEditEngineUpdateMode( true );
1450 pEditView
->MouseButtonDown( rMEvt
);
1454 void ScTextWnd::MouseButtonUp( const MouseEvent
& rMEvt
)
1457 if (pEditView
->MouseButtonUp( rMEvt
))
1459 if ( rMEvt
.IsMiddle() &&
1460 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MouseMiddleButtonAction::PasteSelection
)
1462 // EditView may have pasted from selection
1463 SC_MOD()->InputChanged( pEditView
);
1466 SC_MOD()->InputSelection( pEditView
);
1470 void ScTextWnd::Command( const CommandEvent
& rCEvt
)
1473 CommandEventId nCommand
= rCEvt
.GetCommand();
1474 if ( pEditView
/* && nCommand == CommandEventId::StartDrag */ )
1476 ScModule
* pScMod
= SC_MOD();
1477 ScTabViewShell
* pStartViewSh
= ScTabViewShell::GetActiveViewShell();
1479 // don't modify the font defaults here - the right defaults are
1480 // already set in StartEditEngine when the EditEngine is created
1482 // Prevent that the EditView is lost when switching between Views
1483 pScMod
->SetInEditCommand( true );
1484 pEditView
->Command( rCEvt
);
1485 pScMod
->SetInEditCommand( false );
1487 // CommandEventId::StartDrag does not mean by far that the content was actually changed,
1488 // so don't trigger an InputChanged.
1489 //! Detect if dragged with Move or forbid Drag&Move somehow
1491 if ( nCommand
== CommandEventId::StartDrag
)
1493 // Is dragged onto another View?
1494 ScTabViewShell
* pEndViewSh
= ScTabViewShell::GetActiveViewShell();
1495 if ( pEndViewSh
!= pStartViewSh
&& pStartViewSh
!= nullptr )
1497 ScViewData
& rViewData
= pStartViewSh
->GetViewData();
1498 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pStartViewSh
);
1499 if ( pHdl
&& rViewData
.HasEditView( rViewData
.GetActivePart() ) )
1501 pHdl
->CancelHandler();
1502 rViewData
.GetView()->ShowCursor(); // Missing for KillEditView, due to being inactive
1506 else if ( nCommand
== CommandEventId::CursorPos
)
1508 // don't call InputChanged for CommandEventId::CursorPos
1510 else if ( nCommand
== CommandEventId::InputLanguageChange
)
1512 // #i55929# Font and font size state depends on input language if nothing is selected,
1513 // so the slots have to be invalidated when the input language is changed.
1515 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1518 SfxBindings
& rBindings
= pViewFrm
->GetBindings();
1519 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
1520 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
1523 else if ( nCommand
== CommandEventId::Wheel
)
1525 //don't call InputChanged for CommandEventId::Wheel
1527 else if ( nCommand
== CommandEventId::Swipe
)
1529 //don't call InputChanged for CommandEventId::Swipe
1532 SC_MOD()->InputChanged( pEditView
);
1535 Window::Command(rCEvt
); // Or else let the base class handle it...
1540 void ScTextWnd::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
1544 CommandEvent
aDragEvent( rPosPixel
, CommandEventId::StartDrag
, true );
1545 pEditView
->Command( aDragEvent
);
1547 // handling of d&d to different view (CancelHandler) can't be done here,
1548 // because the call returns before d&d is complete.
1552 void ScTextWnd::KeyInput(const KeyEvent
& rKEvt
)
1555 if (!SC_MOD()->InputKeyEvent( rKEvt
))
1558 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1560 bUsed
= pViewSh
->SfxKeyInput(rKEvt
); // Only accelerators, no input
1562 Window::KeyInput( rKEvt
);
1567 void ScTextWnd::GetFocus()
1569 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1571 pViewSh
->SetFormShellAtTop( false ); // focus in input line -> FormShell no longer on top
1574 void ScTextWnd::LoseFocus()
1578 OUString
ScTextWnd::GetText() const
1580 // Override to get the text via the testtool
1582 return pEditEngine
->GetText();
1584 return GetTextString();
1587 void ScTextWnd::SetFormulaMode( bool bSet
)
1589 if ( bSet
!= bFormulaMode
)
1591 bFormulaMode
= bSet
;
1592 UpdateAutoCorrFlag();
1596 void ScTextWnd::UpdateAutoCorrFlag()
1600 EEControlBits nControl
= pEditEngine
->GetControlWord();
1601 EEControlBits nOld
= nControl
;
1603 nControl
&= ~EEControlBits::AUTOCORRECT
; // No AutoCorrect in Formulas
1605 nControl
|= EEControlBits::AUTOCORRECT
; // Else do enable it
1607 if ( nControl
!= nOld
)
1608 pEditEngine
->SetControlWord( nControl
);
1612 IMPL_LINK_TYPED(ScTextWnd
, NotifyHdl
, EENotify
&, rNotify
, void)
1614 // need to process EE_NOTIFY_TEXTVIEWSCROLLED here
1615 // sometimes we don't seem to get EE_NOTIFY_TEXTVIEWSCROLLED e.g. when
1616 // we insert text at the beginning of the text so the cursor never moves
1617 // down to generate a scroll event
1619 if ( rNotify
.eNotificationType
== EE_NOTIFY_TEXTVIEWSCROLLED
1620 || rNotify
.eNotificationType
== EE_NOTIFY_TEXTHEIGHTCHANGED
)
1621 SetScrollBarRange();
1624 IMPL_LINK_NOARG_TYPED(ScTextWnd
, ModifyHdl
, LinkParamNone
*, void)
1626 if (pEditView
&& !bInputMode
)
1628 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1630 // Use the InputHandler's InOwnChange flag to prevent calling InputChanged
1631 // while an InputHandler method is modifying the EditEngine content
1633 if ( pHdl
&& !pHdl
->IsInOwnChange() )
1634 pHdl
->InputChanged( pEditView
, true ); // #i20282# InputChanged must know if called from modify handler
1638 void ScTextWnd::StopEditEngine( bool bAll
)
1643 pEditEngine
->SetNotifyHdl(Link
<EENotify
&, void>());
1647 if (!maAccTextDatas
.empty())
1648 maAccTextDatas
.back()->EndEdit();
1650 ScModule
* pScMod
= SC_MOD();
1653 pScMod
->InputSelection( pEditView
);
1654 aString
= pEditEngine
->GetText();
1655 bIsInsertMode
= pEditView
->IsInsertMode();
1656 bool bSelection
= pEditView
->HasSelection();
1657 pEditEngine
->SetModifyHdl(Link
<LinkParamNone
*,void>());
1659 DELETEZ(pEditEngine
);
1661 if ( pScMod
->IsEditMode() && !bAll
)
1662 pScMod
->SetInputMode(SC_INPUT_TABLE
);
1664 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1666 pViewFrm
->GetBindings().Invalidate( SID_ATTR_INSERT
);
1669 Invalidate(); // So that the Selection is not left there
1673 static sal_Int32
findFirstNonMatchingChar(const OUString
& rStr1
, const OUString
& rStr2
)
1675 // Search the string for unmatching chars
1676 const sal_Unicode
* pStr1
= rStr1
.getStr();
1677 const sal_Unicode
* pStr2
= rStr2
.getStr();
1679 while ( i
< rStr1
.getLength() )
1681 // Abort on the first unmatching char
1682 if ( *pStr1
!= *pStr2
)
1692 void ScTextWnd::SetTextString( const OUString
& rNewString
)
1694 // Ideally it would be best to create on demand the EditEngine/EditView here, but... for
1695 // the initialisation scenario where a cell is first clicked on we end up with the text in the
1696 // inputbar window scrolled to the bottom if we do that here ( because the tableview and topview
1697 // are synced I guess ).
1698 // should fix that I suppose :-/ need to look a bit further into that
1699 mbInvalidate
= true; // ensure next Paint ( that uses editengine ) call will call Invalidate first
1701 if ( rNewString
!= aString
)
1705 // Find position of the change, only paint the rest
1713 // test if CTL script type is involved
1714 SvtScriptType nOldScript
= SvtScriptType::NONE
;
1715 SvtScriptType nNewScript
= SvtScriptType::NONE
;
1716 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1717 if ( pObjSh
&& dynamic_cast<const ScDocShell
*>( pObjSh
) != nullptr )
1719 // any document can be used (used only for its break iterator)
1720 ScDocument
& rDoc
= static_cast<ScDocShell
*>(pObjSh
)->GetDocument();
1721 nOldScript
= rDoc
.GetStringScriptType( aString
);
1722 nNewScript
= rDoc
.GetStringScriptType( rNewString
);
1724 bPaintAll
= ( nOldScript
& SvtScriptType::COMPLEX
) || ( nNewScript
& SvtScriptType::COMPLEX
);
1729 // if CTL is involved, the whole text has to be redrawn
1736 if (rNewString
.getLength() > aString
.getLength())
1737 nDifPos
= findFirstNonMatchingChar(rNewString
, aString
);
1739 nDifPos
= findFirstNonMatchingChar(aString
, rNewString
);
1741 long nSize1
= GetTextWidth(aString
);
1742 long nSize2
= GetTextWidth(rNewString
);
1743 if ( nSize1
>0 && nSize2
>0 )
1744 nTextSize
= std::max( nSize1
, nSize2
);
1746 nTextSize
= GetOutputSize().Width(); // Overflow
1748 Point aLogicStart
= PixelToLogic(Point(0,0));
1749 long nStartPos
= aLogicStart
.X();
1750 long nInvPos
= nStartPos
;
1752 nInvPos
+= GetTextWidth(aString
,0,nDifPos
);
1754 InvalidateFlags nFlags
= InvalidateFlags::NONE
;
1755 if ( nDifPos
== aString
.getLength() ) // only new characters appended
1756 nFlags
= InvalidateFlags::NoErase
; // then background is already clear
1758 Invalidate( Rectangle( nInvPos
, 0, nStartPos
+nTextSize
, GetOutputSize().Height()-1 ), nFlags
);
1763 pEditEngine
->SetText(rNewString
);
1766 aString
= rNewString
;
1768 if (!maAccTextDatas
.empty())
1769 maAccTextDatas
.back()->TextChanged();
1774 SetScrollBarRange();
1778 const OUString
& ScTextWnd::GetTextString() const
1783 bool ScTextWnd::IsInputActive()
1788 void ScTextWnd::MakeDialogEditView()
1790 if ( pEditView
) return;
1792 ScFieldEditEngine
* pNew
;
1793 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
1796 ScDocument
* pDoc
= pViewSh
->GetViewData().GetDocument();
1797 pNew
= new ScFieldEditEngine(pDoc
, pDoc
->GetEnginePool(), pDoc
->GetEditPool());
1800 pNew
= new ScFieldEditEngine(nullptr, EditEngine::CreatePool(), nullptr, true);
1801 pNew
->SetExecuteURL( false );
1804 pEditEngine
->SetUpdateMode( false );
1805 pEditEngine
->SetWordDelimiters( pEditEngine
->GetWordDelimiters() + "=" );
1806 pEditEngine
->SetPaperSize( Size( bIsRTL
? USHRT_MAX
: THESIZE
, 300 ) );
1808 SfxItemSet
* pSet
= new SfxItemSet( pEditEngine
->GetEmptyItemSet() );
1809 EditEngine::SetFontInfoInItemSet( *pSet
, aTextFont
);
1810 lcl_ExtendEditFontAttribs( *pSet
);
1812 lcl_ModifyRTLDefaults( *pSet
);
1813 pEditEngine
->SetDefaults( pSet
);
1814 pEditEngine
->SetUpdateMode( true );
1816 pEditView
= new EditView( pEditEngine
, this );
1817 pEditEngine
->InsertView( pEditView
, EE_APPEND
);
1822 lcl_ModifyRTLVisArea( pEditView
);
1824 if (!maAccTextDatas
.empty())
1825 maAccTextDatas
.back()->StartEdit();
1828 void ScTextWnd::ImplInitSettings()
1830 bIsRTL
= AllSettings::GetLayoutRTL();
1832 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1834 Color aBgColor
= rStyleSettings
.GetWindowColor();
1835 Color aTxtColor
= rStyleSettings
.GetWindowTextColor();
1837 aTextFont
.SetFillColor ( aBgColor
);
1838 aTextFont
.SetColor (aTxtColor
);
1839 SetBackground ( aBgColor
);
1843 css::uno::Reference
< css::accessibility::XAccessible
> ScTextWnd::CreateAccessible()
1845 return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), nullptr, this,
1846 OUString(ScResId(STR_ACC_EDITLINE_NAME
)),
1847 OUString(ScResId(STR_ACC_EDITLINE_DESCR
)), ScAccessibleEditObject::EditLine
);
1850 void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
1852 OSL_ENSURE( ::std::find( maAccTextDatas
.begin(), maAccTextDatas
.end(), &rTextData
) == maAccTextDatas
.end(),
1853 "ScTextWnd::InsertAccessibleTextData - passed object already registered" );
1854 maAccTextDatas
.push_back( &rTextData
);
1857 void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData
& rTextData
)
1859 AccTextDataVector::iterator aEnd
= maAccTextDatas
.end();
1860 AccTextDataVector::iterator aIt
= ::std::find( maAccTextDatas
.begin(), aEnd
, &rTextData
);
1861 OSL_ENSURE( aIt
!= aEnd
, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
1863 maAccTextDatas
.erase( aIt
);
1866 void ScTextWnd::DataChanged( const DataChangedEvent
& rDCEvt
)
1868 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1869 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1875 Window::DataChanged( rDCEvt
);
1878 void ScTextWnd::TextGrabFocus()
1885 ScPosWnd::ScPosWnd( vcl::Window
* pParent
) :
1886 ComboBox ( pParent
, WinBits(WB_HIDE
| WB_DROPDOWN
) ),
1888 bFormulaMode( false )
1890 Size
aSize( GetTextWidth( "GW99999:GW99999" ),
1892 aSize
.Width() += 25; // FIXME: ??
1893 aSize
.Height() = CalcWindowSizePixel(11); // Functions: 10 MRU + "others..."
1894 SetSizePixel( aSize
);
1898 StartListening( *SfxGetpApp() ); // For Navigator rangename updates
1901 ScPosWnd::~ScPosWnd()
1906 void ScPosWnd::dispose()
1908 EndListening( *SfxGetpApp() );
1912 ComboBox::dispose();
1915 void ScPosWnd::SetFormulaMode( bool bSet
)
1917 if ( bSet
!= bFormulaMode
)
1919 bFormulaMode
= bSet
;
1930 void ScPosWnd::SetPos( const OUString
& rPosStr
)
1932 if ( aPosStr
!= rPosStr
)
1941 OUString
createLocalRangeName(const OUString
& rName
, const OUString
& rTableName
)
1943 OUStringBuffer
aString (rName
);
1944 aString
.append(" (");
1945 aString
.append(rTableName
);
1946 aString
.append(")");
1947 return aString
.makeStringAndClear();
1952 void ScPosWnd::FillRangeNames()
1956 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
1957 if ( pObjSh
&& dynamic_cast<const ScDocShell
*>( pObjSh
) != nullptr )
1959 ScDocument
& rDoc
= static_cast<ScDocShell
*>(pObjSh
)->GetDocument();
1961 InsertEntry(ScGlobal::GetRscString( STR_MANAGE_NAMES
));
1965 std::set
<OUString
> aSet
;
1966 ScRangeName
* pRangeNames
= rDoc
.GetRangeName();
1967 if (!pRangeNames
->empty())
1969 ScRangeName::const_iterator itrBeg
= pRangeNames
->begin(), itrEnd
= pRangeNames
->end();
1970 for (ScRangeName::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
1972 if (itr
->second
->IsValidReference(aDummy
))
1973 aSet
.insert(itr
->second
->GetName());
1976 for (SCTAB i
= 0; i
< rDoc
.GetTableCount(); ++i
)
1978 ScRangeName
* pLocalRangeName
= rDoc
.GetRangeName(i
);
1979 if (pLocalRangeName
&& !pLocalRangeName
->empty())
1981 OUString aTableName
;
1982 rDoc
.GetName(i
, aTableName
);
1983 for (ScRangeName::const_iterator itr
= pLocalRangeName
->begin(); itr
!= pLocalRangeName
->end(); ++itr
)
1985 if (itr
->second
->IsValidReference(aDummy
))
1986 aSet
.insert(createLocalRangeName(itr
->second
->GetName(), aTableName
));
1993 for (std::set
<OUString
>::iterator itr
= aSet
.begin();
1994 itr
!= aSet
.end(); ++itr
)
2003 void ScPosWnd::FillFunctions()
2007 OUString aFirstName
;
2008 const ScAppOptions
& rOpt
= SC_MOD()->GetAppOptions();
2009 sal_uInt16 nMRUCount
= rOpt
.GetLRUFuncListCount();
2010 const sal_uInt16
* pMRUList
= rOpt
.GetLRUFuncList();
2013 const ScFunctionList
* pFuncList
= ScGlobal::GetStarCalcFunctionList();
2014 sal_uLong nListCount
= pFuncList
->GetCount();
2015 for (sal_uInt16 i
=0; i
<nMRUCount
; i
++)
2017 sal_uInt16 nId
= pMRUList
[i
];
2018 for (sal_uLong j
=0; j
<nListCount
; j
++)
2020 const ScFuncDesc
* pDesc
= pFuncList
->GetFunction( j
);
2021 if ( pDesc
->nFIndex
== nId
&& pDesc
->pFuncName
)
2023 InsertEntry( *pDesc
->pFuncName
);
2024 if (aFirstName
.isEmpty())
2025 aFirstName
= *pDesc
->pFuncName
;
2026 break; // Stop searching
2032 //! Re-add entry "Other..." for Function AutoPilot if it can work with text that
2033 // has been entered so far
2035 // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
2037 SetText(aFirstName
);
2040 void ScPosWnd::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
2042 if ( !bFormulaMode
)
2044 // Does the list of range names need updating?
2045 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
2048 const sal_uInt32 nHintId
= pSimpleHint
->GetId();
2049 if ( nHintId
== SC_HINT_AREAS_CHANGED
|| nHintId
== SC_HINT_NAVIGATOR_UPDATEALL
)
2052 else if ( dynamic_cast<const SfxEventHint
*>(&rHint
) )
2054 sal_uLong nEventId
= static_cast<const SfxEventHint
*>(&rHint
)->GetEventId();
2055 if ( nEventId
== SFX_EVENT_ACTIVATEDOC
)
2061 void ScPosWnd::HideTip()
2065 vcl::Window
* pWin
= GetSubEdit();
2068 Help::HidePopover(pWin
, nTipVisible
);
2073 static ScNameInputType
lcl_GetInputType( const OUString
& rText
)
2075 ScNameInputType eRet
= SC_NAME_INPUT_BAD_NAME
; // the more general error
2077 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2080 ScViewData
& rViewData
= pViewSh
->GetViewData();
2081 ScDocument
* pDoc
= rViewData
.GetDocument();
2082 SCTAB nTab
= rViewData
.GetTabNo();
2083 formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
2085 // test in same order as in SID_CURRENTCELL execute
2089 ScRangeUtil aRangeUtil
;
2093 if (rText
== ScGlobal::GetRscString(STR_MANAGE_NAMES
))
2094 eRet
= SC_MANAGE_NAMES
;
2095 else if ( aRange
.Parse( rText
, pDoc
, eConv
) & ScRefFlags::VALID
)
2096 eRet
= SC_NAME_INPUT_RANGE
;
2097 else if ( aAddress
.Parse( rText
, pDoc
, eConv
) & ScRefFlags::VALID
)
2098 eRet
= SC_NAME_INPUT_CELL
;
2099 else if ( ScRangeUtil::MakeRangeFromName( rText
, pDoc
, nTab
, aRange
, RUTL_NAMES
, eConv
) )
2100 eRet
= SC_NAME_INPUT_NAMEDRANGE
;
2101 else if ( ScRangeUtil::MakeRangeFromName( rText
, pDoc
, nTab
, aRange
, RUTL_DBASE
, eConv
) )
2102 eRet
= SC_NAME_INPUT_DATABASE
;
2103 else if ( comphelper::string::isdigitAsciiString( rText
) &&
2104 ( nNumeric
= rText
.toInt32() ) > 0 && nNumeric
<= MAXROW
+1 )
2105 eRet
= SC_NAME_INPUT_ROW
;
2106 else if ( pDoc
->GetTable( rText
, nNameTab
) )
2107 eRet
= SC_NAME_INPUT_SHEET
;
2108 else if ( ScRangeData::IsNameValid( rText
, pDoc
) ) // nothing found, create new range?
2110 if ( rViewData
.GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
2111 eRet
= SC_NAME_INPUT_DEFINE
;
2113 eRet
= SC_NAME_INPUT_BAD_SELECTION
;
2116 eRet
= SC_NAME_INPUT_BAD_NAME
;
2122 void ScPosWnd::Modify()
2128 if ( !IsTravelSelect() && !bFormulaMode
)
2130 // determine the action that would be taken for the current input
2132 ScNameInputType eType
= lcl_GetInputType( GetText() ); // uses current view
2133 sal_uInt16 nStrId
= 0;
2136 case SC_NAME_INPUT_CELL
:
2137 nStrId
= STR_NAME_INPUT_CELL
;
2139 case SC_NAME_INPUT_RANGE
:
2140 case SC_NAME_INPUT_NAMEDRANGE
:
2141 nStrId
= STR_NAME_INPUT_RANGE
; // named range or range reference
2143 case SC_NAME_INPUT_DATABASE
:
2144 nStrId
= STR_NAME_INPUT_DBRANGE
;
2146 case SC_NAME_INPUT_ROW
:
2147 nStrId
= STR_NAME_INPUT_ROW
;
2149 case SC_NAME_INPUT_SHEET
:
2150 nStrId
= STR_NAME_INPUT_SHEET
;
2152 case SC_NAME_INPUT_DEFINE
:
2153 nStrId
= STR_NAME_INPUT_DEFINE
;
2156 // other cases (error): no tip help
2162 // show the help tip at the text cursor position
2164 vcl::Window
* pWin
= GetSubEdit();
2168 vcl::Cursor
* pCur
= pWin
->GetCursor();
2170 aPos
= pWin
->LogicToPixel( pCur
->GetPos() );
2171 aPos
= pWin
->OutputToScreenPixel( aPos
);
2172 Rectangle
aRect( aPos
, aPos
);
2174 OUString aText
= ScGlobal::GetRscString( nStrId
);
2175 QuickHelpFlags nAlign
= QuickHelpFlags::Left
|QuickHelpFlags::Bottom
;
2176 nTipVisible
= Help::ShowPopover(pWin
, aRect
, aText
, nAlign
);
2181 void ScPosWnd::Select()
2183 ComboBox::Select(); // In VCL GetText() only return the selected entry afterwards
2187 if (!IsTravelSelect())
2191 void ScPosWnd::DoEnter()
2193 OUString aText
= GetText();
2194 if ( !aText
.isEmpty() )
2198 ScModule
* pScMod
= SC_MOD();
2199 if ( aText
== ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE
) )
2201 // Function AutoPilot
2202 //! Continue working with the text entered so far
2204 //! new method at ScModule to query if function autopilot is open
2205 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
2206 if ( pViewFrm
&& !pViewFrm
->GetChildWindow( SID_OPENDLG_FUNCTION
) )
2207 pViewFrm
->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION
,
2208 SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
);
2212 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>( SfxViewShell::Current() );
2213 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
2215 pHdl
->InsertFunction( aText
);
2220 // depending on the input, select something or create a new named range
2222 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2225 ScViewData
& rViewData
= pViewSh
->GetViewData();
2226 ScDocShell
* pDocShell
= rViewData
.GetDocShell();
2227 ScDocument
& rDoc
= pDocShell
->GetDocument();
2229 ScNameInputType eType
= lcl_GetInputType( aText
);
2230 if ( eType
== SC_NAME_INPUT_BAD_NAME
|| eType
== SC_NAME_INPUT_BAD_SELECTION
)
2232 sal_uInt16 nId
= ( eType
== SC_NAME_INPUT_BAD_NAME
) ? STR_NAME_ERROR_NAME
: STR_NAME_ERROR_SELECTION
;
2233 pViewSh
->ErrorMessage( nId
);
2235 else if ( eType
== SC_NAME_INPUT_DEFINE
)
2237 ScRangeName
* pNames
= rDoc
.GetRangeName();
2239 if ( pNames
&& !pNames
->findByUpperName(ScGlobal::pCharClass
->uppercase(aText
)) &&
2240 (rViewData
.GetSimpleArea( aSelection
) == SC_MARK_SIMPLE
) )
2242 ScRangeName
aNewRanges( *pNames
);
2243 ScAddress
aCursor( rViewData
.GetCurX(), rViewData
.GetCurY(), rViewData
.GetTabNo() );
2244 OUString
aContent(aSelection
.Format(ScRefFlags::RANGE_ABS_3D
, &rDoc
, rDoc
.GetAddressConvention()));
2245 ScRangeData
* pNew
= new ScRangeData( &rDoc
, aText
, aContent
, aCursor
);
2246 if ( aNewRanges
.insert(pNew
) )
2248 pDocShell
->GetDocFunc().ModifyRangeNames( aNewRanges
);
2249 pViewSh
->UpdateInputHandler(true);
2253 else if (eType
== SC_MANAGE_NAMES
)
2255 sal_uInt16 nId
= ScNameDlgWrapper::GetChildWindowId();
2256 SfxViewFrame
* pViewFrm
= pViewSh
->GetViewFrame();
2257 SfxChildWindow
* pWnd
= pViewFrm
->GetChildWindow( nId
);
2259 SC_MOD()->SetRefDialog( nId
, pWnd
== nullptr );
2263 // for all selection types, execute the SID_CURRENTCELL slot.
2264 if (eType
== SC_NAME_INPUT_CELL
|| eType
== SC_NAME_INPUT_RANGE
)
2266 // Note that SID_CURRENTCELL always expects address to
2267 // be in Calc A1 format. Convert the text.
2268 ScRange
aRange(0,0, rViewData
.GetTabNo());
2269 aRange
.ParseAny(aText
, &rDoc
, rDoc
.GetAddressConvention());
2270 aText
= aRange
.Format(ScRefFlags::RANGE_ABS_3D
, &rDoc
, ::formula::FormulaGrammar::CONV_OOO
);
2273 SfxStringItem
aPosItem( SID_CURRENTCELL
, aText
);
2274 SfxBoolItem
aUnmarkItem( FN_PARAM_1
, true ); // remove existing selection
2276 pViewSh
->GetViewData().GetDispatcher().ExecuteList( SID_CURRENTCELL
,
2277 SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
,
2278 { &aPosItem
, &aUnmarkItem
});
2286 ReleaseFocus_Impl();
2289 bool ScPosWnd::Notify( NotifyEvent
& rNEvt
)
2291 bool bHandled
= true;
2293 switch (rNEvt
.GetType())
2295 case MouseNotifyEvent::KEYINPUT
:
2297 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
2299 switch ( pKEvt
->GetKeyCode().GetCode() )
2308 // escape when the tip help is shown: only hide the tip
2315 ReleaseFocus_Impl();
2325 case MouseNotifyEvent::GETFOCUS
:
2327 // Select the whole text upon focus.
2328 OUString aStr
= GetText();
2329 SetSelection(Selection(0, aStr
.getLength()));
2332 case MouseNotifyEvent::LOSEFOCUS
:
2341 bHandled
= ComboBox::Notify(rNEvt
);
2346 void ScPosWnd::ReleaseFocus_Impl()
2350 SfxViewShell
* pCurSh
= SfxViewShell::Current();
2351 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( dynamic_cast<ScTabViewShell
*>( pCurSh
) );
2352 if ( pHdl
&& pHdl
->IsTopMode() )
2354 // Focus back in input row?
2355 ScInputWindow
* pInputWin
= pHdl
->GetInputWindow();
2358 pInputWin
->TextGrabFocus();
2363 // Set focus to active View
2366 vcl::Window
* pShellWnd
= pCurSh
->GetWindow();
2369 pShellWnd
->GrabFocus();
2373 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */