Update ooo320-m1
[ooovba.git] / sc / source / ui / app / inputwin.cxx
blob754e1109ec10b816a11e2dfa90d4423ceb8855a5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inputwin.cxx,v $
10 * $Revision: 1.57.22.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //------------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
41 #include <sfx2/app.hxx>
42 #include <svx/adjitem.hxx>
43 #include <svx/editview.hxx>
44 #include <svx/editstat.hxx>
45 #include <svx/frmdiritem.hxx>
46 #include <svx/lspcitem.hxx>
47 #include <sfx2/bindings.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/dispatch.hxx>
50 #include <sfx2/event.hxx>
51 #include <sfx2/imgmgr.hxx>
52 #include <stdlib.h> // qsort
53 #include <svx/scriptspaceitem.hxx>
54 #include <svx/scripttypeitem.hxx>
55 #include <vcl/cursor.hxx>
56 #include <vcl/help.hxx>
57 #include <svtools/stritem.hxx>
59 #include "inputwin.hxx"
60 #include "scmod.hxx"
61 #include "uiitems.hxx"
62 #include "global.hxx"
63 #include "scresid.hxx"
64 #include "sc.hrc"
65 #include "globstr.hrc"
66 #include "editutil.hxx"
67 #include "inputhdl.hxx"
68 #include "tabvwsh.hxx"
69 #include "document.hxx"
70 #include "docsh.hxx"
71 #include "appoptio.hxx"
72 #include "rangenam.hxx"
73 #include <formula/compiler.hrc>
74 #include "dbcolect.hxx"
75 #include "rangeutl.hxx"
76 #include "docfunc.hxx"
77 #include "funcdesc.hxx"
78 #include <svx/fontitem.hxx>
79 #include <com/sun/star/accessibility/XAccessible.hpp>
80 #include "AccessibleEditObject.hxx"
81 #include "AccessibleText.hxx"
83 #define TEXT_STARTPOS 3
84 #define THESIZE 1000000 //!!! langt... :-)
85 #define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich?
87 enum ScNameInputType
89 SC_NAME_INPUT_CELL,
90 SC_NAME_INPUT_RANGE,
91 SC_NAME_INPUT_NAMEDRANGE,
92 SC_NAME_INPUT_DATABASE,
93 SC_NAME_INPUT_ROW,
94 SC_NAME_INPUT_SHEET,
95 SC_NAME_INPUT_DEFINE,
96 SC_NAME_INPUT_BAD_NAME,
97 SC_NAME_INPUT_BAD_SELECTION
101 //==================================================================
102 // class ScInputWindowWrapper
103 //==================================================================
105 SFX_IMPL_CHILDWINDOW(ScInputWindowWrapper,FID_INPUTLINE_STATUS)
107 ScInputWindowWrapper::ScInputWindowWrapper( Window* pParentP,
108 USHORT nId,
109 SfxBindings* pBindings,
110 SfxChildWinInfo* /* pInfo */ )
111 : SfxChildWindow( pParentP, nId )
113 ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings );
114 pWindow = pWin;
116 pWin->Show();
118 pWin->SetSizePixel( pWin->CalcWindowSizePixel() );
120 eChildAlignment = SFX_ALIGN_LOWESTTOP;
121 pBindings->Invalidate( FID_TOGGLEINPUTLINE );
124 // GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!
126 SfxChildWinInfo __EXPORT ScInputWindowWrapper::GetInfo() const
128 SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
129 return aInfo;
132 //==================================================================
134 #define IMAGE(id) pImgMgr->SeekImage(id, bDark)
136 //==================================================================
137 // class ScInputWindow
138 //==================================================================
140 ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) :
141 #ifdef OS2
142 // #37192# ohne WB_CLIPCHILDREN wg. os/2 Paintproblem
143 ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK) ),
144 #else
145 // mit WB_CLIPCHILDREN, sonst Flicker
146 ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK|WB_CLIPCHILDREN) ),
147 #endif
148 aWndPos ( this ),
149 aTextWindow ( this ),
150 pInputHdl ( NULL ),
151 pBindings ( pBind ),
152 aTextOk ( ScResId( SCSTR_QHELP_BTNOK ) ), // nicht immer neu aus Resource
153 aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL ) ),
154 aTextSum ( ScResId( SCSTR_QHELP_BTNSUM ) ),
155 aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL ) ),
156 bIsOkCancelMode ( FALSE )
158 ScModule* pScMod = SC_MOD();
159 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
161 // #i73615# don't rely on SfxViewShell::Current while constructing the input line
162 // (also for GetInputHdl below)
163 ScTabViewShell* pViewSh = NULL;
164 SfxDispatcher* pDisp = pBind->GetDispatcher();
165 if ( pDisp )
167 SfxViewFrame* pViewFrm = pDisp->GetFrame();
168 if ( pViewFrm )
169 pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
171 DBG_ASSERT( pViewSh, "no view shell for input window" );
173 BOOL bDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
175 // Positionsfenster, 3 Buttons, Eingabefenster
176 InsertWindow ( 1, &aWndPos, 0, 0 );
177 InsertSeparator ( 1 );
178 InsertItem ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 );
179 InsertItem ( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
180 InsertItem ( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
181 InsertSeparator ( 5 );
182 InsertWindow ( 7, &aTextWindow, 0, 6 );
184 aWndPos .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) );
185 aWndPos .SetHelpId ( HID_INSWIN_POS );
186 aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
187 aTextWindow.SetHelpId ( HID_INSWIN_INPUT );
189 // kein SetHelpText, die Hilfetexte kommen aus der Hilfe
191 SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) );
192 SetHelpId ( SID_INPUT_FUNCTION, HID_INSWIN_CALC );
194 SetItemText ( SID_INPUT_SUM, aTextSum );
195 SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
197 SetItemText ( SID_INPUT_EQUAL, aTextEqual );
198 SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
200 SetHelpId( HID_SC_INPUTWIN ); // fuer die ganze Eingabezeile
202 aWndPos .Show();
203 aTextWindow .Show();
205 pInputHdl = SC_MOD()->GetInputHdl( pViewSh, FALSE ); // use own handler even if ref-handler is set
206 if (pInputHdl)
207 pInputHdl->SetInputWindow( this );
209 if ( pInputHdl && pInputHdl->GetFormString().Len() )
211 // Umschalten waehrend der Funktionsautopilot aktiv ist
212 // -> Inhalt des Funktionsautopiloten wieder anzeigen
213 //! auch Selektion (am InputHdl gemerkt) wieder anzeigen
215 aTextWindow.SetTextString( pInputHdl->GetFormString() );
217 else if ( pInputHdl && pInputHdl->IsInputMode() )
219 // wenn waehrend des Editierens die Eingabezeile weg war
220 // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
221 // wieder den gerade editierten Text aus dem InputHandler anzeigen
223 aTextWindow.SetTextString( pInputHdl->GetEditString() ); // Text anzeigen
224 if ( pInputHdl->IsTopMode() )
225 pInputHdl->SetMode( SC_INPUT_TABLE ); // Focus kommt eh nach unten
227 else if ( pViewSh )
228 pViewSh->UpdateInputHandler( TRUE ); // unbedingtes Update
230 pImgMgr->RegisterToolBox( this );
233 __EXPORT ScInputWindow::~ScInputWindow()
235 BOOL bDown = ( ScGlobal::pSysLocale == NULL ); // after Clear?
237 // if any view's input handler has a pointer to this input window, reset it
238 // (may be several ones, #74522#)
239 // member pInputHdl is not used here
241 if ( !bDown )
243 TypeId aScType = TYPE(ScTabViewShell);
244 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
245 while ( pSh )
247 ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler();
248 if ( pHdl && pHdl->GetInputWindow() == this )
250 pHdl->SetInputWindow( NULL );
251 pHdl->StopInputWinEngine( FALSE ); // #125841# reset pTopView pointer
253 pSh = SfxViewShell::GetNext( *pSh, &aScType );
257 SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
260 void ScInputWindow::SetInputHandler( ScInputHandler* pNew )
262 // wird im Activate der View gerufen...
264 if ( pNew != pInputHdl )
266 // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
267 // geloeschten ViewShell, darum hier auf keinen Fall anfassen!
269 pInputHdl = pNew;
270 if (pInputHdl)
271 pInputHdl->SetInputWindow( this );
275 sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const
277 sal_Bool bSubTotal(sal_False);
278 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
279 if ( pViewSh )
281 ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
282 sal_Int32 nRangeCount (pRangeList->Count());
283 sal_Int32 nRangeIndex (0);
284 while (!bSubTotal && nRangeIndex < nRangeCount)
286 const ScRange* pRange = pRangeList->GetObject( nRangeIndex );
287 if( pRange )
289 SCTAB nTabEnd(pRange->aEnd.Tab());
290 SCTAB nTab(pRange->aStart.Tab());
291 while (!bSubTotal && nTab <= nTabEnd)
293 SCROW nRowEnd(pRange->aEnd.Row());
294 SCROW nRow(pRange->aStart.Row());
295 while (!bSubTotal && nRow <= nRowEnd)
297 if (pDoc->RowFiltered(nRow, nTab))
298 bSubTotal = sal_True;
299 else
300 ++nRow;
302 ++nTab;
305 ++nRangeIndex;
308 ScDBCollection* pDBCollection = pDoc->GetDBCollection();
309 sal_uInt16 nDBCount (pDBCollection->GetCount());
310 sal_uInt16 nDBIndex (0);
311 while (!bSubTotal && nDBIndex < nDBCount)
313 ScDBData* pDB = (*pDBCollection)[nDBIndex];
314 if (pDB && pDB->HasAutoFilter())
316 nRangeIndex = 0;
317 while (!bSubTotal && nRangeIndex < nRangeCount)
319 const ScRange* pRange = pRangeList->GetObject( nRangeIndex );
320 if( pRange )
322 ScRange aDBArea;
323 pDB->GetArea(aDBArea);
324 if (aDBArea.Intersects(*pRange))
325 bSubTotal = sal_True;
327 ++nRangeIndex;
330 ++nDBIndex;
333 return bSubTotal;
336 void __EXPORT ScInputWindow::Select()
338 ScModule* pScMod = SC_MOD();
339 ToolBox::Select();
341 switch ( GetCurItemId() )
343 case SID_INPUT_FUNCTION:
345 //! new method at ScModule to query if function autopilot is open
346 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
347 if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
349 pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
350 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
352 // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
353 // zu werden, egal ob's geklappt hat oder nicht
354 // SetOkCancelMode();
357 break;
359 case SID_INPUT_CANCEL:
360 pScMod->InputCancelHandler();
361 SetSumAssignMode();
362 break;
364 case SID_INPUT_OK:
365 pScMod->InputEnterHandler();
366 SetSumAssignMode();
367 aTextWindow.Invalidate(); // sonst bleibt Selektion stehen
368 break;
370 case SID_INPUT_SUM:
372 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
373 if ( pViewSh )
375 const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
376 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
378 ScRangeList aMarkRangeList;
379 rMark.FillRangeListWithMarks( &aMarkRangeList, FALSE );
380 ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
382 // check if one of the marked ranges is empty
383 bool bEmpty = false;
384 const ULONG nCount = aMarkRangeList.Count();
385 for ( ULONG i = 0; i < nCount; ++i )
387 const ScRange aRange( *aMarkRangeList.GetObject( i ) );
388 if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
389 aRange.aStart.Col(), aRange.aStart.Row(),
390 aRange.aEnd.Col(), aRange.aEnd.Row() ) )
392 bEmpty = true;
393 break;
397 if ( bEmpty )
399 ScRangeList aRangeList;
400 const BOOL bDataFound = pViewSh->GetAutoSumArea( aRangeList );
401 if ( bDataFound )
403 const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
404 pViewSh->EnterAutoSum( aRangeList, bSubTotal ); // Block mit Summen fuellen
407 else
409 const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
410 for ( ULONG i = 0; i < nCount; ++i )
412 const ScRange aRange( *aMarkRangeList.GetObject( i ) );
413 const bool bSetCursor = ( i == nCount - 1 ? true : false );
414 const bool bContinue = ( i != 0 ? true : false );
415 if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
417 pViewSh->MarkRange( aRange, FALSE, FALSE );
418 pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
419 const ScRangeList aRangeList;
420 const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal );
421 SetFuncString( aFormula );
422 break;
427 else // nur in Eingabezeile einfuegen
429 ScRangeList aRangeList;
430 const BOOL bDataFound = pViewSh->GetAutoSumArea( aRangeList );
431 const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
432 const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal );
433 SetFuncString( aFormula );
435 if ( bDataFound && pScMod->IsEditMode() )
437 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
438 if ( pHdl )
440 pHdl->InitRangeFinder( aFormula );
442 //! SetSelection am InputHandler ???
443 //! bSelIsRef setzen ???
444 const xub_StrLen nOpen = aFormula.Search('(');
445 const xub_StrLen nLen = aFormula.Len();
446 if ( nOpen != STRING_NOTFOUND && nLen > nOpen )
448 sal_uInt8 nAdd(1);
449 if (bSubTotal)
450 nAdd = 3;
451 ESelection aSel(0,nOpen+nAdd,0,nLen-1);
452 EditView* pTableView = pHdl->GetTableView();
453 if (pTableView)
454 pTableView->SetSelection(aSel);
455 EditView* pTopView = pHdl->GetTopView();
456 if (pTopView)
457 pTopView->SetSelection(aSel);
464 break;
466 case SID_INPUT_EQUAL:
468 aTextWindow.StartEditEngine();
469 if ( pScMod->IsEditMode() ) // nicht, wenn z.B. geschuetzt
471 aTextWindow.GrabFocus();
472 aTextWindow.SetTextString( '=' );
474 EditView* pView = aTextWindow.GetEditView();
475 if (pView)
477 pView->SetSelection( ESelection(0,1, 0,1) );
478 pScMod->InputChanged(pView);
479 SetOkCancelMode();
480 pView->SetEditEngineUpdateMode(TRUE);
483 break;
488 void __EXPORT ScInputWindow::Resize()
490 ToolBox::Resize();
492 long nWidth = GetSizePixel().Width();
493 long nLeft = aTextWindow.GetPosPixel().X();
494 Size aSize = aTextWindow.GetSizePixel();
496 aSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 );
497 aTextWindow.SetSizePixel( aSize );
498 aTextWindow.Invalidate();
501 void ScInputWindow::SetFuncString( const String& rString, BOOL bDoEdit )
503 //! new method at ScModule to query if function autopilot is open
504 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
505 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
506 aTextWindow.StartEditEngine();
508 ScModule* pScMod = SC_MOD();
509 if ( pScMod->IsEditMode() )
511 if ( bDoEdit )
512 aTextWindow.GrabFocus();
513 aTextWindow.SetTextString( rString );
514 EditView* pView = aTextWindow.GetEditView();
515 if (pView)
517 xub_StrLen nLen = rString.Len();
519 if ( nLen > 0 )
521 nLen--;
522 pView->SetSelection( ESelection( 0, nLen, 0, nLen ) );
525 pScMod->InputChanged(pView);
526 if ( bDoEdit )
527 SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel
529 pView->SetEditEngineUpdateMode(TRUE);
534 void ScInputWindow::SetPosString( const String& rStr )
536 aWndPos.SetPos( rStr );
539 void ScInputWindow::SetTextString( const String& rString )
541 if (rString.Len() <= 32767)
542 aTextWindow.SetTextString(rString);
543 else
545 String aNew = rString;
546 aNew.Erase(32767);
547 aTextWindow.SetTextString(aNew);
551 void ScInputWindow::SetOkCancelMode()
553 //! new method at ScModule to query if function autopilot is open
554 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
555 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
557 ScModule* pScMod = SC_MOD();
558 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
559 if (!bIsOkCancelMode)
561 BOOL bDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
563 RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
564 RemoveItem( 3 );
565 InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 );
566 InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 );
567 SetItemText ( SID_INPUT_CANCEL, aTextCancel );
568 SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL );
569 SetItemText ( SID_INPUT_OK, aTextOk );
570 SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK );
571 bIsOkCancelMode = TRUE;
575 void ScInputWindow::SetSumAssignMode()
577 //! new method at ScModule to query if function autopilot is open
578 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
579 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
581 ScModule* pScMod = SC_MOD();
582 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
583 if (bIsOkCancelMode)
585 BOOL bDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
587 // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
588 RemoveItem( 3 );
589 RemoveItem( 3 );
590 InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
591 InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
592 SetItemText ( SID_INPUT_SUM, aTextSum );
593 SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
594 SetItemText ( SID_INPUT_EQUAL, aTextEqual );
595 SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
596 bIsOkCancelMode = FALSE;
598 SetFormulaMode(FALSE); // kein editieren -> keine Formel
602 void ScInputWindow::SetFormulaMode( BOOL bSet )
604 aWndPos.SetFormulaMode(bSet);
605 aTextWindow.SetFormulaMode(bSet);
608 void __EXPORT ScInputWindow::SetText( const String& rString )
610 ToolBox::SetText(rString);
613 String __EXPORT ScInputWindow::GetText() const
615 return ToolBox::GetText();
619 //UNUSED2008-05 EditView* ScInputWindow::ActivateEdit( const String& rText,
620 //UNUSED2008-05 const ESelection& rSel )
621 //UNUSED2008-05 {
622 //UNUSED2008-05 if ( !aTextWindow.IsInputActive() )
623 //UNUSED2008-05 {
624 //UNUSED2008-05 aTextWindow.StartEditEngine();
625 //UNUSED2008-05 aTextWindow.GrabFocus();
626 //UNUSED2008-05 aTextWindow.SetTextString( rText );
627 //UNUSED2008-05 aTextWindow.GetEditView()->SetSelection( rSel );
628 //UNUSED2008-05 }
629 //UNUSED2008-05
630 //UNUSED2008-05 return aTextWindow.GetEditView();
631 //UNUSED2008-05 }
633 BOOL ScInputWindow::IsInputActive()
635 return aTextWindow.IsInputActive();
638 EditView* ScInputWindow::GetEditView()
640 return aTextWindow.GetEditView();
643 void ScInputWindow::MakeDialogEditView()
645 aTextWindow.MakeDialogEditView();
648 void ScInputWindow::StopEditEngine( BOOL bAll )
650 aTextWindow.StopEditEngine( bAll );
653 void ScInputWindow::TextGrabFocus()
655 aTextWindow.GrabFocus();
658 void ScInputWindow::TextInvalidate()
660 aTextWindow.Invalidate();
663 void ScInputWindow::SwitchToTextWin()
665 // used for shift-ctrl-F2
667 aTextWindow.StartEditEngine();
668 if ( SC_MOD()->IsEditMode() )
670 aTextWindow.GrabFocus();
671 EditView* pView = aTextWindow.GetEditView();
672 if (pView)
674 xub_StrLen nLen = pView->GetEditEngine()->GetTextLen(0);
675 ESelection aSel( 0, nLen, 0, nLen );
676 pView->SetSelection( aSel ); // set cursor to end of text
681 void ScInputWindow::PosGrabFocus()
683 aWndPos.GrabFocus();
686 void ScInputWindow::EnableButtons( BOOL bEnable )
688 // when enabling buttons, always also enable the input window itself
689 if ( bEnable && !IsEnabled() )
690 Enable();
692 EnableItem( SID_INPUT_FUNCTION, bEnable );
693 EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable );
694 EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable );
695 // Invalidate();
698 void ScInputWindow::StateChanged( StateChangedType nType )
700 ToolBox::StateChanged( nType );
702 if ( nType == STATE_CHANGE_INITSHOW ) Resize();
705 void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt )
707 if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
709 // update item images
711 ScModule* pScMod = SC_MOD();
712 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
713 BOOL bDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
714 // IMAGE macro uses pScMod, pImgMgr, bDark
716 SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) );
717 if ( bIsOkCancelMode )
719 SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) );
720 SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) );
722 else
724 SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) );
725 SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) );
729 ToolBox::DataChanged( rDCEvt );
732 //========================================================================
733 // Eingabefenster
734 //========================================================================
736 ScTextWnd::ScTextWnd( Window* pParent )
737 : Window ( pParent, WinBits(WB_HIDE | WB_BORDER) ),
738 DragSourceHelper( this ),
739 pEditEngine ( NULL ),
740 pEditView ( NULL ),
741 pAccTextData ( NULL ),
742 bIsInsertMode( TRUE ),
743 bFormulaMode ( FALSE ),
744 bInputMode ( FALSE )
746 EnableRTL( FALSE ); // #106269# EditEngine can't be used with VCL EnableRTL
748 bIsRTL = GetSettings().GetLayoutRTL();
750 // #79096# always use application font, so a font with cjk chars can be installed
751 Font aAppFont = GetFont();
752 aTextFont = aAppFont;
753 aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln
755 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
757 Color aBgColor= rStyleSettings.GetWindowColor();
758 Color aTxtColor= rStyleSettings.GetWindowTextColor();
760 aTextFont.SetTransparent ( TRUE );
761 aTextFont.SetFillColor ( aBgColor );
762 //aTextFont.SetColor ( COL_FIELDTEXT );
763 aTextFont.SetColor (aTxtColor);
764 aTextFont.SetWeight ( WEIGHT_NORMAL );
766 SetSizePixel ( Size(1,TBX_WINDOW_HEIGHT) );
767 SetBackground ( aBgColor );
768 SetLineColor ( COL_BLACK );
769 SetMapMode ( MAP_TWIP );
770 SetPointer ( POINTER_TEXT );
773 __EXPORT ScTextWnd::~ScTextWnd()
775 delete pEditView;
776 delete pEditEngine;
777 if (pAccTextData)
778 pAccTextData->Dispose();
781 void __EXPORT ScTextWnd::Paint( const Rectangle& rRec )
783 if (pEditView)
784 pEditView->Paint( rRec );
785 else
787 SetFont( aTextFont );
789 long nDiff = GetOutputSizePixel().Height()
790 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
791 // if (nDiff<2) nDiff=2; // mind. 1 Pixel
793 long nStartPos = TEXT_STARTPOS;
794 if ( bIsRTL )
796 // right-align
797 nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS -
798 LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width();
800 // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem
803 DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString );
807 void __EXPORT ScTextWnd::Resize()
809 if (pEditView)
811 Size aSize = GetOutputSizePixel();
812 long nDiff = aSize.Height()
813 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
815 #ifdef OS2_DOCH_NICHT
816 nDiff-=2; // wird durch 2 geteilt
817 // passt sonst nicht zur normalen Textausgabe
818 #endif
820 aSize.Width() -= 2 * TEXT_STARTPOS - 1;
822 pEditView->SetOutputArea(
823 PixelToLogic( Rectangle( Point( TEXT_STARTPOS, (nDiff > 0) ? nDiff/2 : 1 ),
824 aSize ) ) );
828 void __EXPORT ScTextWnd::MouseMove( const MouseEvent& rMEvt )
830 if (pEditView)
831 pEditView->MouseMove( rMEvt );
834 void __EXPORT ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt )
836 if (!HasFocus())
838 StartEditEngine();
839 if ( SC_MOD()->IsEditMode() )
840 GrabFocus();
843 if (pEditView)
845 pEditView->SetEditEngineUpdateMode( TRUE );
846 pEditView->MouseButtonDown( rMEvt );
850 void __EXPORT ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt )
852 if (pEditView)
853 if (pEditView->MouseButtonUp( rMEvt ))
855 if ( rMEvt.IsMiddle() &&
856 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
858 // EditView may have pasted from selection
859 SC_MOD()->InputChanged( pEditView );
861 else
862 SC_MOD()->InputSelection( pEditView );
866 void __EXPORT ScTextWnd::Command( const CommandEvent& rCEvt )
868 bInputMode = TRUE;
869 USHORT nCommand = rCEvt.GetCommand();
870 if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ )
872 ScModule* pScMod = SC_MOD();
873 ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell();
875 // #109441# don't modify the font defaults here - the right defaults are
876 // already set in StartEditEngine when the EditEngine is created
878 // #63263# verhindern, dass die EditView beim View-Umschalten wegkommt
879 pScMod->SetInEditCommand( TRUE );
880 pEditView->Command( rCEvt );
881 pScMod->SetInEditCommand( FALSE );
883 // #48929# COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
884 // darum in dem Fall kein InputChanged
885 //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten
887 if ( nCommand == COMMAND_STARTDRAG )
889 // ist auf eine andere View gedraggt worden?
890 ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell();
891 if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL )
893 ScViewData* pViewData = pStartViewSh->GetViewData();
894 ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh );
895 if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) )
897 pHdl->CancelHandler();
898 pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv
902 else if ( nCommand == COMMAND_CURSORPOS )
904 // don't call InputChanged for COMMAND_CURSORPOS
906 else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE )
908 // #i55929# Font and font size state depends on input language if nothing is selected,
909 // so the slots have to be invalidated when the input language is changed.
911 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
912 if (pViewFrm)
914 SfxBindings& rBindings = pViewFrm->GetBindings();
915 rBindings.Invalidate( SID_ATTR_CHAR_FONT );
916 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
919 else
920 SC_MOD()->InputChanged( pEditView );
922 else
923 Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern...
925 bInputMode = FALSE;
928 void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
930 if ( pEditView )
932 CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, TRUE );
933 pEditView->Command( aDragEvent );
935 // handling of d&d to different view (CancelHandler) can't be done here,
936 // because the call returns before d&d is complete.
940 void __EXPORT ScTextWnd::KeyInput(const KeyEvent& rKEvt)
942 bInputMode = TRUE;
943 if (!SC_MOD()->InputKeyEvent( rKEvt ))
945 BOOL bUsed = FALSE;
946 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
947 if ( pViewSh )
948 bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe
949 if (!bUsed)
950 Window::KeyInput( rKEvt );
952 bInputMode = FALSE;
955 void __EXPORT ScTextWnd::GetFocus()
957 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
958 if ( pViewSh )
959 pViewSh->SetFormShellAtTop( FALSE ); // focus in input line -> FormShell no longer on top
962 void __EXPORT ScTextWnd::LoseFocus()
966 String __EXPORT ScTextWnd::GetText() const
968 // ueberladen, um per Testtool an den Text heranzukommen
970 if ( pEditEngine )
971 return pEditEngine->GetText();
972 else
973 return GetTextString();
976 void ScTextWnd::SetFormulaMode( BOOL bSet )
978 if ( bSet != bFormulaMode )
980 bFormulaMode = bSet;
981 UpdateAutoCorrFlag();
985 void ScTextWnd::UpdateAutoCorrFlag()
987 if ( pEditEngine )
989 ULONG nControl = pEditEngine->GetControlWord();
990 ULONG nOld = nControl;
991 if ( bFormulaMode )
992 nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln
993 else
994 nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon
995 if ( nControl != nOld )
996 pEditEngine->SetControlWord( nControl );
1000 void lcl_ExtendEditFontAttribs( SfxItemSet& rSet )
1002 const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO );
1003 rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK );
1004 rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL );
1005 const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT );
1006 rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK );
1007 rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL );
1008 const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT );
1009 rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
1010 rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
1011 const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC );
1012 rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
1013 rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
1014 const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE );
1015 rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
1016 rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
1019 void lcl_ModifyRTLDefaults( SfxItemSet& rSet )
1021 rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1023 // always using rtl writing direction would break formulas
1024 //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1026 // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
1027 // USHORT values in EditLine), so the text may be wrapped and line spacing must be
1028 // increased to not see the beginning of the next line.
1029 SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
1030 aItem.SetPropLineSpace( 200 );
1031 rSet.Put( aItem );
1034 void lcl_ModifyRTLVisArea( EditView* pEditView )
1036 Rectangle aVisArea = pEditView->GetVisArea();
1037 Size aPaper = pEditView->GetEditEngine()->GetPaperSize();
1038 long nDiff = aPaper.Width() - aVisArea.Right();
1039 aVisArea.Left() += nDiff;
1040 aVisArea.Right() += nDiff;
1041 pEditView->SetVisArea(aVisArea);
1044 void ScTextWnd::StartEditEngine()
1046 // #31147# Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1047 SfxObjectShell* pObjSh = SfxObjectShell::Current();
1048 if ( pObjSh && pObjSh->IsInModalMode() )
1049 return;
1051 if ( !pEditView || !pEditEngine )
1053 ScFieldEditEngine* pNew;
1054 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1055 if ( pViewSh )
1057 const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
1058 pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
1060 else
1061 pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE );
1062 pNew->SetExecuteURL( FALSE );
1063 pEditEngine = pNew;
1065 pEditEngine->SetUpdateMode( FALSE );
1066 pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
1067 pEditEngine->SetWordDelimiters(
1068 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1070 UpdateAutoCorrFlag();
1073 SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1074 pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
1075 lcl_ExtendEditFontAttribs( *pSet );
1076 // turn off script spacing to match DrawText output
1077 pSet->Put( SvxScriptSpaceItem( FALSE, EE_PARA_ASIANCJKSPACING ) );
1078 if ( bIsRTL )
1079 lcl_ModifyRTLDefaults( *pSet );
1080 pEditEngine->SetDefaults( pSet );
1083 // #57254# Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1084 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1086 BOOL bFilled = FALSE;
1087 ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1088 if ( pHdl ) //! Testen, ob's der richtige InputHdl ist?
1089 bFilled = pHdl->GetTextAndFields( *pEditEngine );
1091 pEditEngine->SetUpdateMode( TRUE );
1093 // aString ist die Wahrheit...
1094 if ( bFilled && pEditEngine->GetText() == aString )
1095 Invalidate(); // Repaint fuer (hinterlegte) Felder
1096 else
1097 pEditEngine->SetText(aString); // dann wenigstens den richtigen Text
1099 pEditView = new EditView( pEditEngine, this );
1100 pEditView->SetInsertMode(bIsInsertMode);
1102 // Text aus Clipboard wird als ASCII einzeilig uebernommen
1103 ULONG n = pEditView->GetControlWord();
1104 pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );
1106 pEditEngine->InsertView( pEditView, EE_APPEND );
1108 Resize();
1110 if ( bIsRTL )
1111 lcl_ModifyRTLVisArea( pEditView );
1113 pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl));
1115 if (pAccTextData)
1116 pAccTextData->StartEdit();
1118 // as long as EditEngine and DrawText sometimes differ for CTL text,
1119 // repaint now to have the EditEngine's version visible
1120 // SfxObjectShell* pObjSh = SfxObjectShell::Current();
1121 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1123 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document
1124 BYTE nScript = pDoc->GetStringScriptType( aString );
1125 if ( nScript & SCRIPTTYPE_COMPLEX )
1126 Invalidate();
1130 SC_MOD()->SetInputMode( SC_INPUT_TOP );
1132 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1133 if (pViewFrm)
1134 pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
1137 IMPL_LINK(ScTextWnd, NotifyHdl, EENotify*, EMPTYARG)
1139 if (pEditView && !bInputMode)
1141 ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1143 // #105354# Use the InputHandler's InOwnChange flag to prevent calling InputChanged
1144 // while an InputHandler method is modifying the EditEngine content
1146 if ( pHdl && !pHdl->IsInOwnChange() )
1147 pHdl->InputChanged( pEditView, TRUE ); // #i20282# InputChanged must know if called from modify handler
1150 return 0;
1153 void ScTextWnd::StopEditEngine( BOOL bAll )
1155 if (pEditView)
1157 if (pAccTextData)
1158 pAccTextData->EndEdit();
1160 ScModule* pScMod = SC_MOD();
1162 if (!bAll)
1163 pScMod->InputSelection( pEditView );
1164 aString = pEditEngine->GetText();
1165 bIsInsertMode = pEditView->IsInsertMode();
1166 BOOL bSelection = pEditView->HasSelection();
1167 pEditEngine->SetModifyHdl(Link());
1168 DELETEZ(pEditView);
1169 DELETEZ(pEditEngine);
1171 if ( pScMod->IsEditMode() && !bAll )
1172 pScMod->SetInputMode(SC_INPUT_TABLE);
1174 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1175 if (pViewFrm)
1176 pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
1178 if (bSelection)
1179 Invalidate(); // damit Selektion nicht stehenbleibt
1183 void ScTextWnd::SetTextString( const String& rNewString )
1185 if ( rNewString != aString )
1187 bInputMode = TRUE;
1189 // Position der Aenderung suchen, nur Rest painten
1191 long nInvPos = 0;
1192 long nStartPos = 0;
1193 long nTextSize = 0;
1195 if (!pEditEngine)
1197 BOOL bPaintAll;
1198 if ( bIsRTL )
1199 bPaintAll = TRUE;
1200 else
1202 // test if CTL script type is involved
1203 BYTE nOldScript = 0;
1204 BYTE nNewScript = 0;
1205 SfxObjectShell* pObjSh = SfxObjectShell::Current();
1206 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1208 // any document can be used (used only for its break iterator)
1209 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
1210 nOldScript = pDoc->GetStringScriptType( aString );
1211 nNewScript = pDoc->GetStringScriptType( rNewString );
1213 bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX );
1216 if ( bPaintAll )
1218 // if CTL is involved, the whole text has to be redrawn
1219 Invalidate();
1221 else
1223 xub_StrLen nDifPos;
1224 if (rNewString.Len() > aString.Len())
1225 nDifPos = rNewString.Match(aString);
1226 else
1227 nDifPos = aString.Match(rNewString);
1229 long nSize1 = GetTextWidth(aString);
1230 long nSize2 = GetTextWidth(rNewString);
1231 if ( nSize1>0 && nSize2>0 )
1232 nTextSize = Max( nSize1, nSize2 );
1233 else
1234 nTextSize = GetOutputSize().Width(); // Ueberlauf
1236 if (nDifPos == STRING_MATCH)
1237 nDifPos = 0;
1239 // -1 wegen Rundung und "A"
1240 Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0));
1241 nStartPos = aLogicStart.X();
1242 nInvPos = nStartPos;
1243 if (nDifPos)
1244 nInvPos += GetTextWidth(aString,0,nDifPos);
1246 USHORT nFlags = 0;
1247 if ( nDifPos == aString.Len() ) // only new characters appended
1248 nFlags = INVALIDATE_NOERASE; // then background is already clear
1250 Invalidate( Rectangle( nInvPos, 0,
1251 nStartPos+nTextSize, GetOutputSize().Height()-1 ),
1252 nFlags );
1255 else
1257 pEditEngine->SetText(rNewString);
1260 aString = rNewString;
1262 if (pAccTextData)
1263 pAccTextData->TextChanged();
1265 bInputMode = FALSE;
1269 const String& ScTextWnd::GetTextString() const
1271 return aString;
1274 BOOL ScTextWnd::IsInputActive()
1276 return HasFocus();
1279 EditView* ScTextWnd::GetEditView()
1281 return pEditView;
1284 void ScTextWnd::MakeDialogEditView()
1286 if ( pEditView ) return;
1288 ScFieldEditEngine* pNew;
1289 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1290 if ( pViewSh )
1292 const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
1293 pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
1295 else
1296 pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE );
1297 pNew->SetExecuteURL( FALSE );
1298 pEditEngine = pNew;
1300 pEditEngine->SetUpdateMode( FALSE );
1301 pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' );
1302 pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
1304 SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1305 pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
1306 lcl_ExtendEditFontAttribs( *pSet );
1307 if ( bIsRTL )
1308 lcl_ModifyRTLDefaults( *pSet );
1309 pEditEngine->SetDefaults( pSet );
1310 pEditEngine->SetUpdateMode( TRUE );
1312 pEditView = new EditView( pEditEngine, this );
1313 pEditEngine->InsertView( pEditView, EE_APPEND );
1315 Resize();
1317 if ( bIsRTL )
1318 lcl_ModifyRTLVisArea( pEditView );
1320 if (pAccTextData)
1321 pAccTextData->StartEdit();
1324 void ScTextWnd::ImplInitSettings()
1326 bIsRTL = GetSettings().GetLayoutRTL();
1328 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1330 Color aBgColor= rStyleSettings.GetWindowColor();
1331 Color aTxtColor= rStyleSettings.GetWindowTextColor();
1333 aTextFont.SetFillColor ( aBgColor );
1334 aTextFont.SetColor (aTxtColor);
1335 SetBackground ( aBgColor );
1336 Invalidate();
1339 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible()
1341 return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this,
1342 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))),
1343 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine);
1346 // -----------------------------------------------------------------------
1348 void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt )
1350 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1351 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1353 ImplInitSettings();
1354 Invalidate();
1356 else
1357 Window::DataChanged( rDCEvt );
1361 //========================================================================
1362 // Positionsfenster
1363 //========================================================================
1365 ScPosWnd::ScPosWnd( Window* pParent ) :
1366 ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ),
1367 pAccel ( NULL ),
1368 nTipVisible ( 0 ),
1369 bFormulaMode( FALSE )
1371 Size aSize( GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:GW99999")) ),
1372 GetTextHeight() );
1373 aSize.Width() += 25; // ??
1374 aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..."
1375 SetSizePixel( aSize );
1377 FillRangeNames();
1379 StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates
1382 __EXPORT ScPosWnd::~ScPosWnd()
1384 EndListening( *SFX_APP() );
1386 HideTip();
1388 delete pAccel;
1391 void ScPosWnd::SetFormulaMode( BOOL bSet )
1393 if ( bSet != bFormulaMode )
1395 bFormulaMode = bSet;
1397 if ( bSet )
1398 FillFunctions();
1399 else
1400 FillRangeNames();
1402 HideTip();
1406 void ScPosWnd::SetPos( const String& rPosStr )
1408 if ( aPosStr != rPosStr )
1410 aPosStr = rPosStr;
1411 SetText(aPosStr);
1415 void ScPosWnd::FillRangeNames()
1417 Clear();
1419 SfxObjectShell* pObjSh = SfxObjectShell::Current();
1420 if ( pObjSh && pObjSh->ISA(ScDocShell) )
1422 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
1424 // per Hand sortieren, weil Funktionen nicht sortiert werden:
1426 ScRangeName* pRangeNames = pDoc->GetRangeName();
1427 USHORT nCount = pRangeNames->GetCount();
1428 if ( nCount > 0 )
1430 USHORT nValidCount = 0;
1431 ScRange aDummy;
1432 USHORT i;
1433 for ( i=0; i<nCount; i++ )
1435 ScRangeData* pData = (*pRangeNames)[i];
1436 if (pData->IsValidReference(aDummy))
1437 nValidCount++;
1439 if ( nValidCount )
1441 ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
1442 USHORT j;
1443 for ( i=0, j=0; i<nCount; i++ )
1445 ScRangeData* pData = (*pRangeNames)[i];
1446 if (pData->IsValidReference(aDummy))
1447 ppSortArray[j++] = pData;
1449 #ifndef ICC
1450 qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
1451 &ScRangeData_QsortNameCompare );
1452 #else
1453 qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
1454 ICCQsortNameCompare );
1455 #endif
1456 for ( j=0; j<nValidCount; j++ )
1457 InsertEntry( ppSortArray[j]->GetName() );
1458 delete [] ppSortArray;
1462 SetText(aPosStr);
1465 void ScPosWnd::FillFunctions()
1467 Clear();
1469 String aFirstName;
1470 const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
1471 USHORT nMRUCount = rOpt.GetLRUFuncListCount();
1472 const USHORT* pMRUList = rOpt.GetLRUFuncList();
1473 if (pMRUList)
1475 const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
1476 ULONG nListCount = pFuncList->GetCount();
1477 for (USHORT i=0; i<nMRUCount; i++)
1479 USHORT nId = pMRUList[i];
1480 for (ULONG j=0; j<nListCount; j++)
1482 const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
1483 if ( pDesc->nFIndex == nId && pDesc->pFuncName )
1485 InsertEntry( *pDesc->pFuncName );
1486 if (!aFirstName.Len())
1487 aFirstName = *pDesc->pFuncName;
1488 break; // nicht weitersuchen
1494 //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
1495 //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!
1497 // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
1499 SetText(aFirstName);
1502 void __EXPORT ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint )
1504 if ( !bFormulaMode )
1506 // muss die Liste der Bereichsnamen updgedated werden?
1508 if ( rHint.ISA(SfxSimpleHint) )
1510 ULONG nHintId = ((SfxSimpleHint&)rHint).GetId();
1511 if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL)
1512 FillRangeNames();
1514 else if ( rHint.ISA(SfxEventHint) )
1516 ULONG nEventId = ((SfxEventHint&)rHint).GetEventId();
1517 if ( nEventId == SFX_EVENT_ACTIVATEDOC )
1518 FillRangeNames();
1523 void ScPosWnd::HideTip()
1525 if ( nTipVisible )
1527 Help::HideTip( nTipVisible );
1528 nTipVisible = 0;
1532 ScNameInputType lcl_GetInputType( const String& rText )
1534 ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error
1536 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1537 if ( pViewSh )
1539 ScViewData* pViewData = pViewSh->GetViewData();
1540 ScDocument* pDoc = pViewData->GetDocument();
1541 SCTAB nTab = pViewData->GetTabNo();
1542 formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
1544 // test in same order as in SID_CURRENTCELL execute
1546 ScRange aRange;
1547 ScAddress aAddress;
1548 ScRangeUtil aRangeUtil;
1549 SCTAB nNameTab;
1550 sal_Int32 nNumeric;
1552 if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID )
1553 eRet = SC_NAME_INPUT_NAMEDRANGE;
1554 else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID )
1555 eRet = SC_NAME_INPUT_CELL;
1556 else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) )
1557 eRet = SC_NAME_INPUT_NAMEDRANGE;
1558 else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) )
1559 eRet = SC_NAME_INPUT_DATABASE;
1560 else if ( ByteString( rText, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() &&
1561 ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
1562 eRet = SC_NAME_INPUT_ROW;
1563 else if ( pDoc->GetTable( rText, nNameTab ) )
1564 eRet = SC_NAME_INPUT_SHEET;
1565 else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range?
1567 if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
1568 eRet = SC_NAME_INPUT_DEFINE;
1569 else
1570 eRet = SC_NAME_INPUT_BAD_SELECTION;
1572 else
1573 eRet = SC_NAME_INPUT_BAD_NAME;
1576 return eRet;
1579 void ScPosWnd::Modify()
1581 ComboBox::Modify();
1583 HideTip();
1585 if ( !IsTravelSelect() && !bFormulaMode )
1587 // determine the action that would be taken for the current input
1589 ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view
1590 USHORT nStrId = 0;
1591 switch ( eType )
1593 case SC_NAME_INPUT_CELL:
1594 nStrId = STR_NAME_INPUT_CELL;
1595 break;
1596 case SC_NAME_INPUT_RANGE:
1597 case SC_NAME_INPUT_NAMEDRANGE:
1598 nStrId = STR_NAME_INPUT_RANGE; // named range or range reference
1599 break;
1600 case SC_NAME_INPUT_DATABASE:
1601 nStrId = STR_NAME_INPUT_DBRANGE;
1602 break;
1603 case SC_NAME_INPUT_ROW:
1604 nStrId = STR_NAME_INPUT_ROW;
1605 break;
1606 case SC_NAME_INPUT_SHEET:
1607 nStrId = STR_NAME_INPUT_SHEET;
1608 break;
1609 case SC_NAME_INPUT_DEFINE:
1610 nStrId = STR_NAME_INPUT_DEFINE;
1611 break;
1612 default:
1613 // other cases (error): no tip help
1614 break;
1617 if ( nStrId )
1619 // show the help tip at the text cursor position
1621 Window* pWin = GetSubEdit();
1622 if (!pWin)
1623 pWin = this;
1624 Point aPos;
1625 Cursor* pCur = pWin->GetCursor();
1626 if (pCur)
1627 aPos = pWin->LogicToPixel( pCur->GetPos() );
1628 aPos = pWin->OutputToScreenPixel( aPos );
1629 Rectangle aRect( aPos, aPos );
1631 String aText = ScGlobal::GetRscString( nStrId );
1632 USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
1633 nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign);
1638 void __EXPORT ScPosWnd::Select()
1640 ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag
1642 HideTip();
1644 if (!IsTravelSelect())
1645 DoEnter();
1648 void ScPosWnd::DoEnter()
1650 String aText = GetText();
1651 if ( aText.Len() )
1653 if ( bFormulaMode )
1655 ScModule* pScMod = SC_MOD();
1656 if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) )
1658 // Funktions-Autopilot
1659 //! mit dem bisher eingegebenen Text weiterarbeiten !!!
1661 //! new method at ScModule to query if function autopilot is open
1662 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1663 if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
1664 pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
1665 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
1667 else
1669 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
1670 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
1671 if (pHdl)
1672 pHdl->InsertFunction( aText );
1675 else
1677 // depending on the input, select something or create a new named range
1679 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1680 if ( pViewSh )
1682 ScNameInputType eType = lcl_GetInputType( aText );
1683 if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION )
1685 USHORT nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION;
1686 pViewSh->ErrorMessage( nId );
1688 else if ( eType == SC_NAME_INPUT_DEFINE )
1690 ScViewData* pViewData = pViewSh->GetViewData();
1691 ScDocShell* pDocShell = pViewData->GetDocShell();
1692 ScDocument* pDoc = pDocShell->GetDocument();
1693 ScRangeName* pNames = pDoc->GetRangeName();
1694 ScRange aSelection;
1695 USHORT nIndex = 0;
1696 if ( pNames && !pNames->SearchName( aText, nIndex ) &&
1697 (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) )
1699 ScRangeName aNewRanges( *pNames );
1700 ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
1701 String aContent;
1702 aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
1703 ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
1704 if ( aNewRanges.Insert(pNew) )
1706 ScDocFunc aFunc(*pDocShell);
1707 aFunc.ModifyRangeNames( aNewRanges, FALSE );
1708 pViewSh->UpdateInputHandler(TRUE);
1710 else
1711 delete pNew; // shouldn't happen
1714 else
1716 // for all selection types, excecute the SID_CURRENTCELL slot
1718 SfxStringItem aPosItem( SID_CURRENTCELL, aText );
1719 SfxBoolItem aUnmarkItem( FN_PARAM_1, TRUE ); // remove existing selection
1721 pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL,
1722 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
1723 &aPosItem, &aUnmarkItem, 0L );
1728 else
1729 SetText( aPosStr );
1731 ReleaseFocus_Impl();
1734 long __EXPORT ScPosWnd::Notify( NotifyEvent& rNEvt )
1736 long nHandled = 0;
1738 if ( rNEvt.GetType() == EVENT_KEYINPUT )
1740 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
1742 switch ( pKEvt->GetKeyCode().GetCode() )
1744 case KEY_RETURN:
1745 DoEnter();
1746 nHandled = 1;
1747 break;
1749 case KEY_ESCAPE:
1750 if (nTipVisible)
1752 // escape when the tip help is shown: only hide the tip
1753 HideTip();
1755 else
1757 if (!bFormulaMode)
1758 SetText( aPosStr );
1759 ReleaseFocus_Impl();
1761 nHandled = 1;
1762 break;
1766 if ( !nHandled )
1767 nHandled = ComboBox::Notify( rNEvt );
1769 if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
1770 HideTip();
1772 return nHandled;
1775 void ScPosWnd::ReleaseFocus_Impl()
1777 HideTip();
1779 SfxViewShell* pCurSh = SfxViewShell::Current();
1780 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) );
1781 if ( pHdl && pHdl->IsTopMode() )
1783 // Focus wieder in die Eingabezeile?
1785 ScInputWindow* pInputWin = pHdl->GetInputWindow();
1786 if (pInputWin)
1788 pInputWin->TextGrabFocus();
1789 return;
1793 // Focus auf die aktive View
1795 if ( pCurSh )
1797 Window* pShellWnd = pCurSh->GetWindow();
1799 if ( pShellWnd )
1800 pShellWnd->GrabFocus();