Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <algorithm>
22 :
23 : #include "scitems.hxx"
24 : #include <editeng/eeitem.hxx>
25 :
26 : #include <sfx2/app.hxx>
27 : #include <editeng/adjitem.hxx>
28 : #include <editeng/editview.hxx>
29 : #include <editeng/editstat.hxx>
30 : #include <editeng/frmdiritem.hxx>
31 : #include <editeng/lspcitem.hxx>
32 : #include <sfx2/bindings.hxx>
33 : #include <sfx2/viewfrm.hxx>
34 : #include <sfx2/dispatch.hxx>
35 : #include <sfx2/event.hxx>
36 : #include <sfx2/imgmgr.hxx>
37 : #include <stdlib.h> // qsort
38 : #include <editeng/scriptspaceitem.hxx>
39 : #include <editeng/scripttypeitem.hxx>
40 : #include <vcl/cursor.hxx>
41 : #include <vcl/help.hxx>
42 : #include <svl/stritem.hxx>
43 : #include <stdio.h>
44 :
45 : #include "inputwin.hxx"
46 : #include "scmod.hxx"
47 : #include "uiitems.hxx"
48 : #include "global.hxx"
49 : #include "scresid.hxx"
50 : #include "sc.hrc"
51 : #include "globstr.hrc"
52 : #include "reffact.hxx"
53 : #include "editutil.hxx"
54 : #include "inputhdl.hxx"
55 : #include "tabvwsh.hxx"
56 : #include "document.hxx"
57 : #include "docsh.hxx"
58 : #include "appoptio.hxx"
59 : #include "rangenam.hxx"
60 : #include <formula/compiler.hrc>
61 : #include "dbdata.hxx"
62 : #include "rangeutl.hxx"
63 : #include "docfunc.hxx"
64 : #include "funcdesc.hxx"
65 : #include "markdata.hxx"
66 : #include <editeng/fontitem.hxx>
67 : #include <com/sun/star/accessibility/XAccessible.hpp>
68 : #include "AccessibleEditObject.hxx"
69 : #include "AccessibleText.hxx"
70 : #include <svtools/miscopt.hxx>
71 : #include <comphelper/string.hxx>
72 : #include <com/sun/star/frame/XLayoutManager.hpp>
73 : #include <com/sun/star/frame/XModel.hpp>
74 : #include <com/sun/star/frame/XController.hpp>
75 :
76 : #define THESIZE 1000000 //!!! langt... :-)
77 : #define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich?
78 : #define LEFT_OFFSET 5
79 : #define INPUTWIN_MULTILINES 6
80 : const long BUTTON_OFFSET = 2; ///< space between input line and the button to expand / collapse
81 : const long ADDITIONAL_BORDER = 1; ///< height of the line at the bottom
82 : const long ADDITIONAL_SPACE = 4; ///< additional vertical space when the multiline edit has more lines
83 :
84 : using com::sun::star::uno::Reference;
85 : using com::sun::star::uno::UNO_QUERY;
86 :
87 : using com::sun::star::frame::XLayoutManager;
88 : using com::sun::star::frame::XModel;
89 : using com::sun::star::frame::XFrame;
90 : using com::sun::star::frame::XController;
91 : using com::sun::star::beans::XPropertySet;
92 :
93 :
94 : enum ScNameInputType
95 : {
96 : SC_NAME_INPUT_CELL,
97 : SC_NAME_INPUT_RANGE,
98 : SC_NAME_INPUT_NAMEDRANGE,
99 : SC_NAME_INPUT_DATABASE,
100 : SC_NAME_INPUT_ROW,
101 : SC_NAME_INPUT_SHEET,
102 : SC_NAME_INPUT_DEFINE,
103 : SC_NAME_INPUT_BAD_NAME,
104 : SC_NAME_INPUT_BAD_SELECTION,
105 : SC_MANAGE_NAMES
106 : };
107 :
108 :
109 0 : ScTextWndBase::ScTextWndBase( Window* pParent, WinBits nStyle )
110 0 : : Window ( pParent, nStyle )
111 : {
112 0 : if ( IsNativeControlSupported( CTRL_EDITBOX, PART_ENTIRE_CONTROL ) )
113 : {
114 0 : SetType( WINDOW_CALCINPUTLINE );
115 0 : SetBorderStyle( WINDOW_BORDER_NWF );
116 : }
117 0 : }
118 :
119 : //==================================================================
120 : // class ScInputWindowWrapper
121 : //==================================================================
122 :
123 5 : SFX_IMPL_CHILDWINDOW_WITHID(ScInputWindowWrapper,FID_INPUTLINE_STATUS)
124 :
125 0 : ScInputWindowWrapper::ScInputWindowWrapper( Window* pParentP,
126 : sal_uInt16 nId,
127 : SfxBindings* pBindings,
128 : SfxChildWinInfo* /* pInfo */ )
129 0 : : SfxChildWindow( pParentP, nId )
130 : {
131 0 : ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings );
132 0 : pWindow = pWin;
133 :
134 0 : pWin->Show();
135 :
136 0 : pWin->SetSizePixel( pWin->CalcWindowSizePixel() );
137 :
138 0 : eChildAlignment = SFX_ALIGN_LOWESTTOP;
139 0 : pBindings->Invalidate( FID_TOGGLEINPUTLINE );
140 0 : }
141 :
142 : // GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!
143 :
144 0 : SfxChildWinInfo ScInputWindowWrapper::GetInfo() const
145 : {
146 0 : SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
147 0 : return aInfo;
148 : }
149 :
150 : //==================================================================
151 :
152 : #define IMAGE(id) pImgMgr->SeekImage(id)
153 0 : static bool lcl_isExperimentalMode()
154 : {
155 : // make inputbar feature on by default, leave the switch for the
156 : // moment in case we need to back it out easily
157 0 : return true;
158 : }
159 :
160 : //==================================================================
161 : // class ScInputWindow
162 : //==================================================================
163 :
164 0 : static ScTextWndBase* lcl_chooseRuntimeImpl( Window* pParent, SfxBindings* pBind )
165 : {
166 0 : ScTabViewShell* pViewSh = NULL;
167 0 : SfxDispatcher* pDisp = pBind->GetDispatcher();
168 0 : if ( pDisp )
169 : {
170 0 : SfxViewFrame* pViewFrm = pDisp->GetFrame();
171 0 : if ( pViewFrm )
172 0 : pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
173 : }
174 :
175 0 : if ( !lcl_isExperimentalMode() )
176 0 : return new ScTextWnd( pParent, pViewSh );
177 0 : return new ScInputBarGroup( pParent, pViewSh );
178 : }
179 :
180 0 : ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) :
181 : // mit WB_CLIPCHILDREN, sonst Flicker
182 : ToolBox ( pParent, WinBits(WB_CLIPCHILDREN) ),
183 : aWndPos ( this ),
184 : pRuntimeWindow ( lcl_chooseRuntimeImpl( this, pBind ) ),
185 0 : aTextWindow ( *pRuntimeWindow ),
186 : pInputHdl ( NULL ),
187 : aTextOk ( ScResId( SCSTR_QHELP_BTNOK ) ), // nicht immer neu aus Resource
188 : aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL ) ),
189 : aTextSum ( ScResId( SCSTR_QHELP_BTNSUM ) ),
190 : aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL ) ),
191 : mnMaxY (0),
192 : bIsOkCancelMode ( false ),
193 : bInResize ( false ),
194 0 : mbIsMultiLine ( lcl_isExperimentalMode() )
195 : {
196 0 : ScModule* pScMod = SC_MOD();
197 0 : SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
198 :
199 : // #i73615# don't rely on SfxViewShell::Current while constructing the input line
200 : // (also for GetInputHdl below)
201 0 : ScTabViewShell* pViewSh = NULL;
202 0 : SfxDispatcher* pDisp = pBind->GetDispatcher();
203 0 : if ( pDisp )
204 : {
205 0 : SfxViewFrame* pViewFrm = pDisp->GetFrame();
206 0 : if ( pViewFrm )
207 0 : pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
208 : }
209 : OSL_ENSURE( pViewSh, "no view shell for input window" );
210 :
211 : // Position window, 3 buttons, input window
212 0 : InsertWindow ( 1, &aWndPos, 0, 0 );
213 0 : InsertSeparator ( 1 );
214 0 : InsertItem ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 );
215 0 : InsertItem ( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
216 0 : InsertItem ( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
217 0 : InsertSeparator ( 5 );
218 0 : InsertWindow ( 7, &aTextWindow, 0, 6 );
219 :
220 0 : aWndPos .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) );
221 0 : aWndPos .SetHelpId ( HID_INSWIN_POS );
222 0 : aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
223 0 : aTextWindow.SetHelpId ( HID_INSWIN_INPUT );
224 :
225 : // kein SetHelpText, die Hilfetexte kommen aus der Hilfe
226 :
227 0 : SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) );
228 0 : SetHelpId ( SID_INPUT_FUNCTION, HID_INSWIN_CALC );
229 :
230 0 : SetItemText ( SID_INPUT_SUM, aTextSum );
231 0 : SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
232 :
233 0 : SetItemText ( SID_INPUT_EQUAL, aTextEqual );
234 0 : SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
235 :
236 0 : SetHelpId( HID_SC_INPUTWIN ); // fuer die ganze Eingabezeile
237 :
238 0 : aWndPos .Show();
239 0 : aTextWindow.Show();
240 :
241 0 : pInputHdl = SC_MOD()->GetInputHdl( pViewSh, false ); // use own handler even if ref-handler is set
242 0 : if (pInputHdl)
243 0 : pInputHdl->SetInputWindow( this );
244 :
245 0 : if (pInputHdl && !pInputHdl->GetFormString().isEmpty())
246 : {
247 : // Umschalten waehrend der Funktionsautopilot aktiv ist
248 : // -> Inhalt des Funktionsautopiloten wieder anzeigen
249 : //! auch Selektion (am InputHdl gemerkt) wieder anzeigen
250 :
251 0 : aTextWindow.SetTextString( pInputHdl->GetFormString() );
252 : }
253 0 : else if ( pInputHdl && pInputHdl->IsInputMode() )
254 : {
255 : // wenn waehrend des Editierens die Eingabezeile weg war
256 : // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
257 : // wieder den gerade editierten Text aus dem InputHandler anzeigen
258 :
259 0 : aTextWindow.SetTextString( pInputHdl->GetEditString() ); // Text anzeigen
260 0 : if ( pInputHdl->IsTopMode() )
261 0 : pInputHdl->SetMode( SC_INPUT_TABLE ); // Focus kommt eh nach unten
262 : }
263 0 : else if ( pViewSh )
264 0 : pViewSh->UpdateInputHandler( sal_True ); // unbedingtes Update
265 :
266 0 : pImgMgr->RegisterToolBox( this );
267 0 : SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA));
268 0 : }
269 :
270 0 : ScInputWindow::~ScInputWindow()
271 : {
272 0 : sal_Bool bDown = ( ScGlobal::pSysLocale == NULL ); // after Clear?
273 :
274 : // if any view's input handler has a pointer to this input window, reset it
275 : // (may be several ones, #74522#)
276 : // member pInputHdl is not used here
277 :
278 0 : if ( !bDown )
279 : {
280 0 : TypeId aScType = TYPE(ScTabViewShell);
281 0 : SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
282 0 : while ( pSh )
283 : {
284 0 : ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler();
285 0 : if ( pHdl && pHdl->GetInputWindow() == this )
286 : {
287 0 : pHdl->SetInputWindow( NULL );
288 0 : pHdl->StopInputWinEngine( false ); // reset pTopView pointer
289 : }
290 0 : pSh = SfxViewShell::GetNext( *pSh, &aScType );
291 : }
292 : }
293 :
294 0 : SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
295 0 : }
296 :
297 0 : void ScInputWindow::SetInputHandler( ScInputHandler* pNew )
298 : {
299 : // wird im Activate der View gerufen...
300 :
301 0 : if ( pNew != pInputHdl )
302 : {
303 : // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
304 : // geloeschten ViewShell, darum hier auf keinen Fall anfassen!
305 :
306 0 : pInputHdl = pNew;
307 0 : if (pInputHdl)
308 0 : pInputHdl->SetInputWindow( this );
309 : }
310 0 : }
311 :
312 0 : bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const
313 : {
314 0 : bool bSubTotal = false;
315 0 : ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
316 0 : if ( pViewSh )
317 : {
318 0 : ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
319 0 : size_t nRangeCount (pRangeList->size());
320 0 : size_t nRangeIndex (0);
321 0 : while (!bSubTotal && nRangeIndex < nRangeCount)
322 : {
323 0 : const ScRange* pRange = (*pRangeList)[nRangeIndex];
324 0 : if( pRange )
325 : {
326 0 : SCTAB nTabEnd(pRange->aEnd.Tab());
327 0 : SCTAB nTab(pRange->aStart.Tab());
328 0 : while (!bSubTotal && nTab <= nTabEnd)
329 : {
330 0 : SCROW nRowEnd(pRange->aEnd.Row());
331 0 : SCROW nRow(pRange->aStart.Row());
332 0 : while (!bSubTotal && nRow <= nRowEnd)
333 : {
334 0 : if (pDoc->RowFiltered(nRow, nTab))
335 0 : bSubTotal = true;
336 : else
337 0 : ++nRow;
338 : }
339 0 : ++nTab;
340 : }
341 : }
342 0 : ++nRangeIndex;
343 : }
344 :
345 0 : const ScDBCollection::NamedDBs& rDBs = pDoc->GetDBCollection()->getNamedDBs();
346 0 : ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
347 0 : for (; !bSubTotal && itr != itrEnd; ++itr)
348 : {
349 0 : const ScDBData& rDB = *itr;
350 0 : if (!rDB.HasAutoFilter())
351 0 : continue;
352 :
353 0 : nRangeIndex = 0;
354 0 : while (!bSubTotal && nRangeIndex < nRangeCount)
355 : {
356 0 : const ScRange* pRange = (*pRangeList)[nRangeIndex];
357 0 : if( pRange )
358 : {
359 0 : ScRange aDBArea;
360 0 : rDB.GetArea(aDBArea);
361 0 : if (aDBArea.Intersects(*pRange))
362 0 : bSubTotal = true;
363 : }
364 0 : ++nRangeIndex;
365 : }
366 : }
367 : }
368 0 : return bSubTotal;
369 : }
370 :
371 0 : void ScInputWindow::Select()
372 : {
373 0 : ScModule* pScMod = SC_MOD();
374 0 : ToolBox::Select();
375 :
376 0 : switch ( GetCurItemId() )
377 : {
378 : case SID_INPUT_FUNCTION:
379 : {
380 : //! new method at ScModule to query if function autopilot is open
381 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
382 0 : if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
383 : {
384 : pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
385 0 : SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
386 :
387 : // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
388 : // zu werden, egal ob's geklappt hat oder nicht
389 : // SetOkCancelMode();
390 : }
391 : }
392 0 : break;
393 :
394 : case SID_INPUT_CANCEL:
395 0 : pScMod->InputCancelHandler();
396 0 : SetSumAssignMode();
397 0 : break;
398 :
399 : case SID_INPUT_OK:
400 0 : pScMod->InputEnterHandler();
401 0 : SetSumAssignMode();
402 0 : aTextWindow.Invalidate(); // sonst bleibt Selektion stehen
403 0 : break;
404 :
405 : case SID_INPUT_SUM:
406 : {
407 0 : ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
408 0 : if ( pViewSh )
409 : {
410 0 : const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
411 0 : if ( rMark.IsMarked() || rMark.IsMultiMarked() )
412 : {
413 0 : ScRangeList aMarkRangeList;
414 0 : rMark.FillRangeListWithMarks( &aMarkRangeList, false );
415 0 : ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
416 :
417 : // check if one of the marked ranges is empty
418 0 : bool bEmpty = false;
419 0 : const size_t nCount = aMarkRangeList.size();
420 0 : for ( size_t i = 0; i < nCount; ++i )
421 : {
422 0 : const ScRange aRange( *aMarkRangeList[i] );
423 0 : if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
424 0 : aRange.aStart.Col(), aRange.aStart.Row(),
425 0 : aRange.aEnd.Col(), aRange.aEnd.Row() ) )
426 : {
427 0 : bEmpty = true;
428 : break;
429 : }
430 : }
431 :
432 0 : if ( bEmpty )
433 : {
434 0 : ScRangeList aRangeList;
435 0 : const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
436 0 : if ( bDataFound )
437 : {
438 0 : ScAddress aAddr = aRangeList.back()->aEnd;
439 0 : aAddr.IncRow();
440 0 : const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
441 0 : pViewSh->EnterAutoSum( aRangeList, bSubTotal, aAddr );
442 0 : }
443 : }
444 : else
445 : {
446 0 : const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
447 0 : for ( size_t i = 0; i < nCount; ++i )
448 : {
449 0 : const ScRange aRange( *aMarkRangeList[i] );
450 0 : const bool bSetCursor = ( i == nCount - 1 ? true : false );
451 0 : const bool bContinue = ( i != 0 ? true : false );
452 0 : if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
453 : {
454 0 : pViewSh->MarkRange( aRange, false, false );
455 0 : pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
456 0 : const ScRangeList aRangeList;
457 0 : ScAddress aAddr = aRange.aEnd;
458 0 : aAddr.IncRow();
459 : const String aFormula = pViewSh->GetAutoSumFormula(
460 0 : aRangeList, bSubTotal, aAddr );
461 0 : SetFuncString( aFormula );
462 0 : break;
463 : }
464 : }
465 0 : }
466 : }
467 : else // nur in Eingabezeile einfuegen
468 : {
469 0 : ScRangeList aRangeList;
470 0 : const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
471 0 : const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
472 0 : ScAddress aAddr = pViewSh->GetViewData()->GetCurPos();
473 0 : const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal, aAddr );
474 0 : SetFuncString( aFormula );
475 :
476 0 : if ( bDataFound && pScMod->IsEditMode() )
477 : {
478 0 : ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
479 0 : if ( pHdl )
480 : {
481 0 : pHdl->InitRangeFinder( aFormula );
482 :
483 : //! SetSelection am InputHandler ???
484 : //! bSelIsRef setzen ???
485 0 : const xub_StrLen nOpen = aFormula.Search('(');
486 0 : const xub_StrLen nLen = aFormula.Len();
487 0 : if ( nOpen != STRING_NOTFOUND && nLen > nOpen )
488 : {
489 0 : sal_uInt8 nAdd(1);
490 0 : if (bSubTotal)
491 0 : nAdd = 3;
492 0 : ESelection aSel(0,nOpen+nAdd,0,nLen-1);
493 0 : EditView* pTableView = pHdl->GetTableView();
494 0 : if (pTableView)
495 0 : pTableView->SetSelection(aSel);
496 0 : EditView* pTopView = pHdl->GetTopView();
497 0 : if (pTopView)
498 0 : pTopView->SetSelection(aSel);
499 : }
500 : }
501 0 : }
502 : }
503 : }
504 : }
505 0 : break;
506 :
507 : case SID_INPUT_EQUAL:
508 : {
509 0 : aTextWindow.StartEditEngine();
510 0 : if ( pScMod->IsEditMode() ) // nicht, wenn z.B. geschuetzt
511 : {
512 0 : aTextWindow.StartEditEngine();
513 0 : aTextWindow.SetTextString(rtl::OUString('='));
514 :
515 0 : EditView* pView = aTextWindow.GetEditView();
516 0 : if (pView)
517 : {
518 0 : pView->SetSelection( ESelection(0,1, 0,1) );
519 0 : pScMod->InputChanged(pView);
520 0 : SetOkCancelMode();
521 0 : pView->SetEditEngineUpdateMode(sal_True);
522 : }
523 : }
524 0 : break;
525 : }
526 : }
527 0 : }
528 :
529 0 : void ScInputWindow::Paint( const Rectangle& rRect )
530 : {
531 0 : ToolBox::Paint( rRect );
532 :
533 : // draw a line at the bottom to distinguish that from the grid
534 : // (we have space for that thanks to ADDITIONAL_BORDER)
535 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
536 0 : SetLineColor( rStyleSettings.GetShadowColor() );
537 :
538 0 : Size aSize = GetSizePixel();
539 0 : DrawLine( Point( 0, aSize.Height() - 1 ), Point( aSize.Width() - 1, aSize.Height() - 1 ) );
540 0 : }
541 :
542 0 : void ScInputWindow::Resize()
543 : {
544 0 : ToolBox::Resize();
545 0 : if ( mbIsMultiLine )
546 : {
547 0 : aTextWindow.Resize();
548 0 : Size aSize = GetSizePixel();
549 0 : aSize.Height() = CalcWindowSizePixel().Height() + ADDITIONAL_BORDER;
550 0 : ScInputBarGroup* pGroupBar = dynamic_cast< ScInputBarGroup* > ( pRuntimeWindow.get() );
551 0 : if ( pGroupBar )
552 : {
553 : // To ensure smooth display and prevent the items in the toolbar being
554 : // repositioned ( vertically ) we lock the vertical positioning of the toolbox
555 : // items when we are displaying > 1 line.
556 : // So, we need to adjust the height of the toolbox accordingly. If we don't
557 : // then the largest item ( e.g. the GroupBar window ) will actually be
558 : // positioned such that the toolbar will cut off the bottom of that item
559 0 : if ( pGroupBar->GetNumLines() > 1 )
560 0 : aSize.Height() += pGroupBar->GetVertOffset() + ADDITIONAL_SPACE;
561 : }
562 0 : SetSizePixel(aSize);
563 0 : Invalidate();
564 : }
565 : else
566 : {
567 0 : long nWidth = GetSizePixel().Width();
568 0 : long nLeft = aTextWindow.GetPosPixel().X();
569 0 : Size aSize = aTextWindow.GetSizePixel();
570 :
571 0 : aSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 );
572 :
573 0 : aTextWindow.SetSizePixel( aSize );
574 0 : aTextWindow.Invalidate();
575 : }
576 0 : }
577 :
578 0 : void ScInputWindow::SetFuncString( const String& rString, sal_Bool bDoEdit )
579 : {
580 : //! new method at ScModule to query if function autopilot is open
581 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
582 0 : EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
583 0 : aTextWindow.StartEditEngine();
584 :
585 0 : ScModule* pScMod = SC_MOD();
586 0 : if ( pScMod->IsEditMode() )
587 : {
588 0 : if ( bDoEdit )
589 0 : aTextWindow.GrabFocus();
590 0 : aTextWindow.SetTextString( rString );
591 0 : EditView* pView = aTextWindow.GetEditView();
592 0 : if (pView)
593 : {
594 0 : xub_StrLen nLen = rString.Len();
595 :
596 0 : if ( nLen > 0 )
597 : {
598 0 : nLen--;
599 0 : pView->SetSelection( ESelection( 0, nLen, 0, nLen ) );
600 : }
601 :
602 0 : pScMod->InputChanged(pView);
603 0 : if ( bDoEdit )
604 0 : SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel
605 :
606 0 : pView->SetEditEngineUpdateMode(sal_True);
607 : }
608 : }
609 0 : }
610 :
611 0 : void ScInputWindow::SetPosString( const String& rStr )
612 : {
613 0 : aWndPos.SetPos( rStr );
614 0 : }
615 :
616 0 : void ScInputWindow::SetTextString( const String& rString )
617 : {
618 0 : if (rString.Len() <= 32767)
619 0 : aTextWindow.SetTextString(rString);
620 : else
621 : {
622 0 : String aNew = rString;
623 0 : aNew.Erase(32767);
624 0 : aTextWindow.SetTextString(aNew);
625 : }
626 0 : }
627 :
628 0 : void ScInputWindow::SetOkCancelMode()
629 : {
630 : //! new method at ScModule to query if function autopilot is open
631 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
632 0 : EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
633 :
634 0 : ScModule* pScMod = SC_MOD();
635 0 : SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
636 0 : if (!bIsOkCancelMode)
637 : {
638 0 : RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
639 0 : RemoveItem( 3 );
640 0 : InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 );
641 0 : InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 );
642 0 : SetItemText ( SID_INPUT_CANCEL, aTextCancel );
643 0 : SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL );
644 0 : SetItemText ( SID_INPUT_OK, aTextOk );
645 0 : SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK );
646 0 : bIsOkCancelMode = sal_True;
647 : }
648 0 : }
649 :
650 0 : void ScInputWindow::SetSumAssignMode()
651 : {
652 : //! new method at ScModule to query if function autopilot is open
653 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
654 0 : EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
655 :
656 0 : ScModule* pScMod = SC_MOD();
657 0 : SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
658 0 : if (bIsOkCancelMode)
659 : {
660 : // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
661 0 : RemoveItem( 3 );
662 0 : RemoveItem( 3 );
663 0 : InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
664 0 : InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
665 0 : SetItemText ( SID_INPUT_SUM, aTextSum );
666 0 : SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
667 0 : SetItemText ( SID_INPUT_EQUAL, aTextEqual );
668 0 : SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
669 0 : bIsOkCancelMode = false;
670 :
671 0 : SetFormulaMode(false); // kein editieren -> keine Formel
672 : }
673 0 : }
674 :
675 0 : void ScInputWindow::SetFormulaMode( sal_Bool bSet )
676 : {
677 0 : aWndPos.SetFormulaMode(bSet);
678 0 : aTextWindow.SetFormulaMode(bSet);
679 0 : }
680 :
681 0 : void ScInputWindow::SetText( const String& rString )
682 : {
683 0 : ToolBox::SetText(rString);
684 0 : }
685 :
686 0 : String ScInputWindow::GetText() const
687 : {
688 0 : return ToolBox::GetText();
689 : }
690 :
691 0 : sal_Bool ScInputWindow::IsInputActive()
692 : {
693 0 : return aTextWindow.IsInputActive();
694 : }
695 :
696 0 : EditView* ScInputWindow::GetEditView()
697 : {
698 0 : return aTextWindow.GetEditView();
699 : }
700 :
701 0 : void ScInputWindow::MakeDialogEditView()
702 : {
703 0 : aTextWindow.MakeDialogEditView();
704 0 : }
705 :
706 0 : void ScInputWindow::StopEditEngine( sal_Bool bAll )
707 : {
708 0 : aTextWindow.StopEditEngine( bAll );
709 0 : }
710 :
711 0 : void ScInputWindow::TextGrabFocus()
712 : {
713 0 : aTextWindow.TextGrabFocus();
714 0 : }
715 :
716 0 : void ScInputWindow::TextInvalidate()
717 : {
718 0 : aTextWindow.Invalidate();
719 0 : }
720 :
721 0 : void ScInputWindow::SwitchToTextWin()
722 : {
723 : // used for shift-ctrl-F2
724 :
725 0 : aTextWindow.StartEditEngine();
726 0 : if ( SC_MOD()->IsEditMode() )
727 : {
728 0 : aTextWindow.TextGrabFocus();
729 0 : EditView* pView = aTextWindow.GetEditView();
730 0 : if (pView)
731 : {
732 0 : sal_uInt16 nPara = pView->GetEditEngine()->GetParagraphCount() ? ( pView->GetEditEngine()->GetParagraphCount() - 1 ) : 0;
733 0 : xub_StrLen nLen = pView->GetEditEngine()->GetTextLen( nPara );
734 0 : ESelection aSel( nPara, nLen, nPara, nLen );
735 0 : pView->SetSelection( aSel ); // set cursor to end of text
736 : }
737 : }
738 0 : }
739 :
740 0 : void ScInputWindow::PosGrabFocus()
741 : {
742 0 : aWndPos.GrabFocus();
743 0 : }
744 :
745 0 : void ScInputWindow::EnableButtons( sal_Bool bEnable )
746 : {
747 : // when enabling buttons, always also enable the input window itself
748 0 : if ( bEnable && !IsEnabled() )
749 0 : Enable();
750 :
751 0 : EnableItem( SID_INPUT_FUNCTION, bEnable );
752 0 : EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable );
753 0 : EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable );
754 : // Invalidate();
755 0 : }
756 :
757 0 : void ScInputWindow::StateChanged( StateChangedType nType )
758 : {
759 0 : ToolBox::StateChanged( nType );
760 :
761 0 : if ( nType == STATE_CHANGE_INITSHOW ) Resize();
762 0 : }
763 :
764 0 : void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt )
765 : {
766 0 : if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
767 : {
768 : // update item images
769 0 : ScModule* pScMod = SC_MOD();
770 0 : SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
771 : // IMAGE macro uses pScMod, pImgMg
772 :
773 0 : SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) );
774 0 : if ( bIsOkCancelMode )
775 : {
776 0 : SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) );
777 0 : SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) );
778 : }
779 : else
780 : {
781 0 : SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) );
782 0 : SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) );
783 : }
784 : }
785 :
786 0 : ToolBox::DataChanged( rDCEvt );
787 0 : }
788 :
789 0 : bool ScInputWindow::IsPointerAtResizePos()
790 : {
791 0 : if ( GetOutputSizePixel().Height() - GetPointerPosPixel().Y() <= 4 )
792 0 : return true;
793 : else
794 0 : return false;
795 : }
796 :
797 0 : void ScInputWindow::MouseMove( const MouseEvent& rMEvt )
798 : {
799 0 : if ( mbIsMultiLine )
800 : {
801 0 : Point aPosPixel = GetPointerPosPixel();
802 :
803 0 : ScInputBarGroup* pGroupBar = dynamic_cast< ScInputBarGroup* > ( pRuntimeWindow.get() );
804 :
805 0 : if ( bInResize || IsPointerAtResizePos() )
806 0 : SetPointer( Pointer( POINTER_WINDOW_SSIZE ) );
807 : else
808 0 : SetPointer( Pointer( POINTER_ARROW ) );
809 :
810 0 : if ( bInResize )
811 : {
812 : // detect direction
813 0 : long nResizeThreshold = ( (long)TBX_WINDOW_HEIGHT * 0.7 );
814 0 : bool bResetPointerPos = false;
815 :
816 : // Detect attempt to expand toolbar too much
817 0 : if ( aPosPixel.Y() >= mnMaxY )
818 : {
819 0 : bResetPointerPos = true;
820 0 : aPosPixel.Y() = mnMaxY;
821 : } // or expanding down
822 0 : else if ( GetOutputSizePixel().Height() - aPosPixel.Y() < -nResizeThreshold )
823 : {
824 0 : pGroupBar->IncrementVerticalSize();
825 0 : bResetPointerPos = true;
826 : } // or shrinking up
827 0 : else if ( ( GetOutputSizePixel().Height() - aPosPixel.Y() ) > nResizeThreshold )
828 : {
829 0 : bResetPointerPos = true;
830 0 : pGroupBar->DecrementVerticalSize();
831 : }
832 :
833 0 : if ( bResetPointerPos )
834 : {
835 0 : aPosPixel.Y() = GetOutputSizePixel().Height();
836 0 : SetPointerPosPixel( aPosPixel );
837 : }
838 : }
839 : }
840 0 : ToolBox::MouseMove( rMEvt );
841 0 : }
842 :
843 0 : void ScInputWindow::MouseButtonDown( const MouseEvent& rMEvt )
844 : {
845 0 : if ( mbIsMultiLine )
846 : {
847 0 : if ( rMEvt.IsLeft() )
848 : {
849 0 : if ( IsPointerAtResizePos() )
850 : {
851 : // Don't leave the mouse pointer leave *this* window
852 0 : CaptureMouse();
853 0 : bInResize = true;
854 : // find the height of the gridwin, we don't wan't to be
855 : // able to expand the toolbar too far so we need to
856 : // caculate an upper limit
857 : // I'd prefer to leave at least a single column header and a
858 : // row but I don't know how to get that value in pixels.
859 : // Use TBX_WINDOW_HEIGHT for the moment
860 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
861 0 : mnMaxY = GetOutputSizePixel().Height() + ( pViewSh->GetGridHeight(SC_SPLIT_TOP) + pViewSh->GetGridHeight(SC_SPLIT_BOTTOM) ) - TBX_WINDOW_HEIGHT;
862 : }
863 : }
864 : }
865 0 : ToolBox::MouseButtonDown( rMEvt );
866 0 : }
867 0 : void ScInputWindow::MouseButtonUp( const MouseEvent& rMEvt )
868 : {
869 0 : if ( mbIsMultiLine )
870 : {
871 0 : ReleaseMouse();
872 0 : if ( rMEvt.IsLeft() )
873 : {
874 0 : bInResize = false;
875 0 : mnMaxY = 0;
876 : }
877 : }
878 0 : ToolBox::MouseButtonUp( rMEvt );
879 0 : }
880 :
881 :
882 : //========================================================================
883 : // ScInputBarGroup
884 : //========================================================================
885 :
886 0 : ScInputBarGroup::ScInputBarGroup(Window* pParent, ScTabViewShell* pViewSh)
887 : : ScTextWndBase ( pParent, WinBits(WB_HIDE | WB_TABSTOP ) ),
888 : aMultiTextWnd ( this, pViewSh ),
889 : aButton ( this, WB_TABSTOP | WB_RECTSTYLE | WB_SMALLSTYLE ),
890 : aScrollBar ( this, WB_TABSTOP | WB_VERT | WB_DRAG ),
891 0 : nVertOffset ( 0 )
892 : {
893 0 : aMultiTextWnd.Show();
894 0 : aMultiTextWnd.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
895 0 : aMultiTextWnd.SetHelpId( HID_INSWIN_INPUT );
896 :
897 0 : Size aSize( GetSettings().GetStyleSettings().GetScrollBarSize(), aMultiTextWnd.GetPixelHeightForLines(1) );
898 :
899 0 : aButton.SetClickHdl( LINK( this, ScInputBarGroup, ClickHdl ) );
900 0 : aButton.SetSizePixel( aSize );
901 0 : aButton.Enable();
902 0 : aButton.SetSymbol( SYMBOL_SPIN_DOWN );
903 0 : aButton.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA ) );
904 0 : aButton.Show();
905 :
906 0 : aScrollBar.SetSizePixel( aSize );
907 0 : aScrollBar.SetScrollHdl( LINK( this, ScInputBarGroup, Impl_ScrollHdl ) );
908 0 : }
909 :
910 0 : ScInputBarGroup::~ScInputBarGroup()
911 : {
912 :
913 0 : }
914 :
915 : void
916 0 : ScInputBarGroup::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
917 : {
918 0 : aMultiTextWnd.InsertAccessibleTextData( rTextData );
919 0 : }
920 :
921 : void
922 0 : ScInputBarGroup::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
923 : {
924 0 : aMultiTextWnd.RemoveAccessibleTextData( rTextData );
925 0 : }
926 :
927 : const String&
928 0 : ScInputBarGroup::GetTextString() const
929 : {
930 0 : return aMultiTextWnd.GetTextString();
931 : }
932 :
933 0 : void ScInputBarGroup::SetTextString( const String& rString )
934 : {
935 0 : aMultiTextWnd.SetTextString(rString);
936 0 : }
937 :
938 0 : void ScInputBarGroup::Resize()
939 : {
940 0 : Window *w=GetParent();
941 : ScInputWindow *pParent;
942 0 : pParent=dynamic_cast<ScInputWindow*>(w);
943 :
944 0 : if(pParent==NULL)
945 : {
946 : OSL_FAIL("The parent window pointer pParent is null");
947 0 : return;
948 : }
949 :
950 0 : long nWidth = pParent->GetSizePixel().Width();
951 0 : long nLeft = GetPosPixel().X();
952 :
953 0 : Size aSize = GetSizePixel();
954 0 : aSize.Width() = Max( ((long)(nWidth - nLeft - LEFT_OFFSET)), (long)0 );
955 :
956 0 : aScrollBar.SetPosPixel(Point( aSize.Width() - aButton.GetSizePixel().Width(), aButton.GetSizePixel().Height() ) );
957 :
958 0 : Size aTmpSize( aSize );
959 0 : aTmpSize.Width() = aTmpSize.Width() - aButton.GetSizePixel().Width() - BUTTON_OFFSET;
960 0 : aMultiTextWnd.SetSizePixel(aTmpSize);
961 :
962 0 : aMultiTextWnd.Resize();
963 :
964 0 : aSize.Height() = aMultiTextWnd.GetSizePixel().Height();
965 :
966 0 : SetSizePixel(aSize);
967 :
968 0 : if( aMultiTextWnd.GetNumLines() > 1 )
969 : {
970 0 : aButton.SetSymbol( SYMBOL_SPIN_UP );
971 0 : aButton.SetQuickHelpText( ScResId( SCSTR_QHELP_COLLAPSE_FORMULA ) );
972 0 : Size scrollSize = aButton.GetSizePixel();
973 0 : scrollSize.Height() = aMultiTextWnd.GetSizePixel().Height() - aButton.GetSizePixel().Height();
974 0 : aScrollBar.SetSizePixel( scrollSize );
975 :
976 0 : Size aOutSz = aMultiTextWnd.GetOutputSize();
977 :
978 0 : aScrollBar.SetVisibleSize( aOutSz.Height() );
979 0 : aScrollBar.SetPageSize( aOutSz.Height() );
980 0 : aScrollBar.SetLineSize( aMultiTextWnd.GetTextHeight() );
981 0 : aScrollBar.SetRange( Range( 0, aMultiTextWnd.GetEditEngTxtHeight() ) );
982 :
983 0 : aScrollBar.Resize();
984 0 : aScrollBar.Show();
985 : }
986 : else
987 : {
988 0 : aButton.SetSymbol( SYMBOL_SPIN_DOWN );
989 0 : aButton.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA ) );
990 0 : aScrollBar.Hide();
991 : }
992 :
993 0 : aButton.SetPosPixel(Point(aSize.Width() - aButton.GetSizePixel().Width(), 0));
994 :
995 0 : Invalidate();
996 : }
997 :
998 0 : void ScInputBarGroup::StopEditEngine( sal_Bool bAll )
999 : {
1000 0 : aMultiTextWnd.StopEditEngine( bAll );
1001 0 : }
1002 :
1003 0 : void ScInputBarGroup::StartEditEngine()
1004 : {
1005 0 : aMultiTextWnd.StartEditEngine();
1006 0 : }
1007 :
1008 :
1009 0 : void ScInputBarGroup::MakeDialogEditView()
1010 : {
1011 0 : aMultiTextWnd.MakeDialogEditView();
1012 0 : }
1013 :
1014 :
1015 0 : EditView* ScInputBarGroup::GetEditView()
1016 : {
1017 0 : return aMultiTextWnd.GetEditView();
1018 : }
1019 :
1020 0 : sal_Bool ScInputBarGroup::IsInputActive()
1021 : {
1022 0 : return aMultiTextWnd.IsInputActive();
1023 : }
1024 :
1025 0 : void ScInputBarGroup::SetFormulaMode(sal_Bool bSet)
1026 : {
1027 0 : aMultiTextWnd.SetFormulaMode(bSet);
1028 0 : }
1029 :
1030 0 : void ScInputBarGroup::IncrementVerticalSize()
1031 : {
1032 0 : aMultiTextWnd.SetNumLines( aMultiTextWnd.GetNumLines() + 1 );
1033 0 : TriggerToolboxLayout();
1034 0 : }
1035 :
1036 0 : void ScInputBarGroup::DecrementVerticalSize()
1037 : {
1038 0 : if ( aMultiTextWnd.GetNumLines() > 1 )
1039 : {
1040 0 : aMultiTextWnd.SetNumLines( aMultiTextWnd.GetNumLines() - 1 );
1041 0 : TriggerToolboxLayout();
1042 : }
1043 0 : }
1044 :
1045 0 : IMPL_LINK_NOARG(ScInputBarGroup, ClickHdl)
1046 : {
1047 0 : Window *w=GetParent();
1048 : ScInputWindow *pParent;
1049 0 : pParent=dynamic_cast<ScInputWindow*>(w);
1050 :
1051 0 : if(pParent==NULL)
1052 : {
1053 : OSL_FAIL("The parent window pointer pParent is null");
1054 0 : return 1;
1055 : }
1056 0 : if( aMultiTextWnd.GetNumLines() > 1 )
1057 : {
1058 0 : aMultiTextWnd.SetNumLines( 1 );
1059 : }
1060 : else
1061 : {
1062 0 : aMultiTextWnd.SetNumLines( aMultiTextWnd.GetLastNumExpandedLines() );
1063 : }
1064 0 : TriggerToolboxLayout();
1065 : // Restore focus to input line(s) if necessary
1066 0 : if ( SC_MOD()->GetInputHdl()->IsTopMode() )
1067 0 : aMultiTextWnd.GrabFocus();
1068 0 : return 0;
1069 : }
1070 :
1071 0 : void ScInputBarGroup::TriggerToolboxLayout()
1072 : {
1073 0 : Window *w=GetParent();
1074 : ScInputWindow *pParent;
1075 0 : pParent=dynamic_cast<ScInputWindow*>(w);
1076 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1077 :
1078 : // Capture the vertical position of this window in the toolbar, when we increase
1079 : // the size of the toolbar to accomadate expanded line input we need to take this
1080 : // into account
1081 0 : if ( !nVertOffset )
1082 0 : nVertOffset = pParent->GetItemPosRect( pParent->GetItemCount() - 1 ).Top();
1083 :
1084 0 : if ( pViewFrm )
1085 : {
1086 0 : Reference< com::sun::star::beans::XPropertySet > xPropSet( pViewFrm->GetFrame().GetFrameInterface(), UNO_QUERY );
1087 0 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1088 :
1089 0 : if ( xPropSet.is() )
1090 : {
1091 0 : com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
1092 0 : aValue >>= xLayoutManager;
1093 : }
1094 :
1095 0 : if ( xLayoutManager.is() )
1096 : {
1097 0 : if ( aMultiTextWnd.GetNumLines() > 1)
1098 0 : pParent->SetToolbarLayoutMode( TBX_LAYOUT_LOCKVERT );
1099 : else
1100 0 : pParent->SetToolbarLayoutMode( TBX_LAYOUT_NORMAL );
1101 0 : xLayoutManager->lock();
1102 0 : DataChangedEvent aFakeUpdate( DATACHANGED_SETTINGS, NULL, SETTINGS_STYLE );
1103 : // this basically will trigger the reposititioning of the
1104 : // items in the toolbar from ImplFormat ( which is controlled by
1105 : // mnWinHeight ) which in turn is updated in ImplCalcItem which is
1106 : // controlled by mbCalc. Additionally the ImplFormat above is
1107 : // controlled via mbFormat. It seems the easiest way to get these
1108 : // booleans set is to send in the fake event below.
1109 0 : pParent->DataChanged( aFakeUpdate);
1110 : // highest item in toolbar will have been calculated via the
1111 : // event above. Call resize on InputBar to pick up the height
1112 : // change
1113 0 : pParent->Resize();
1114 : // unlock relayouts the toolbars in the 4 quadrants
1115 0 : xLayoutManager->unlock();
1116 0 : }
1117 : }
1118 0 : }
1119 :
1120 0 : IMPL_LINK_NOARG(ScInputBarGroup, Impl_ScrollHdl)
1121 : {
1122 0 : aMultiTextWnd.DoScroll();
1123 0 : return 0;
1124 : }
1125 :
1126 0 : void ScInputBarGroup::TextGrabFocus()
1127 : {
1128 0 : aMultiTextWnd.TextGrabFocus();
1129 0 : }
1130 :
1131 : //========================================================================
1132 : // ScMultiTextWnd
1133 : //========================================================================
1134 :
1135 0 : ScMultiTextWnd::ScMultiTextWnd( ScInputBarGroup* pParen, ScTabViewShell* pViewSh )
1136 : :
1137 : ScTextWnd( pParen, pViewSh ),
1138 : mrGroupBar(* pParen ),
1139 : mnLines( 1 ),
1140 : mnLastExpandedLines( INPUTWIN_MULTILINES ),
1141 0 : mbInvalidate( false )
1142 : {
1143 0 : Size aBorder;
1144 0 : aBorder = CalcWindowSize( aBorder);
1145 0 : mnBorderHeight = aBorder.Height();
1146 0 : }
1147 :
1148 0 : ScMultiTextWnd::~ScMultiTextWnd()
1149 : {
1150 0 : }
1151 :
1152 0 : void ScMultiTextWnd::Paint( const Rectangle& rRec )
1153 : {
1154 0 : EditView* pView = GetEditView();
1155 0 : if ( pView )
1156 : {
1157 0 : if ( mbInvalidate )
1158 : {
1159 0 : pView->Invalidate();
1160 0 : mbInvalidate = false;
1161 : }
1162 0 : pEditView->Paint( rRec );
1163 : }
1164 0 : }
1165 :
1166 0 : EditView* ScMultiTextWnd::GetEditView()
1167 : {
1168 0 : if ( !pEditView )
1169 0 : InitEditEngine();
1170 0 : return pEditView;
1171 : }
1172 :
1173 0 : long ScMultiTextWnd::GetPixelHeightForLines( long nLines )
1174 : {
1175 : // add padding ( for the borders of the window )
1176 0 : return ( nLines * LogicToPixel( Size( 0, GetTextHeight() ) ).Height() ) + mnBorderHeight;
1177 : }
1178 :
1179 0 : void ScMultiTextWnd::SetNumLines( long nLines )
1180 : {
1181 0 : mnLines = nLines;
1182 0 : if ( nLines > 1 )
1183 : {
1184 0 : mnLastExpandedLines = nLines;
1185 0 : Resize();
1186 : }
1187 0 : }
1188 :
1189 0 : void ScMultiTextWnd::Resize()
1190 : {
1191 : // Only Height is recalculated here, Width is applied from
1192 : // parent/container window
1193 0 : Size aTextBoxSize = GetSizePixel();
1194 :
1195 0 : aTextBoxSize.Height() = GetPixelHeightForLines( mnLines );
1196 0 : SetSizePixel( aTextBoxSize );
1197 :
1198 0 : if(pEditView)
1199 : {
1200 0 : Size aOutputSize = GetOutputSizePixel();
1201 0 : Rectangle aOutputArea = PixelToLogic( Rectangle( Point(), aOutputSize ));
1202 0 : pEditView->SetOutputArea( aOutputArea );
1203 :
1204 : // Don't leave an empty area at the bottom if we can move the text down.
1205 0 : long nMaxVisAreaTop = pEditEngine->GetTextHeight() - aOutputArea.GetHeight();
1206 0 : if (pEditView->GetVisArea().Top() > nMaxVisAreaTop)
1207 : {
1208 0 : pEditView->Scroll(0, pEditView->GetVisArea().Top() - nMaxVisAreaTop);
1209 : }
1210 :
1211 0 : pEditEngine->SetPaperSize( PixelToLogic( Size( aOutputSize.Width(), 10000 ) ) );
1212 : }
1213 :
1214 0 : SetScrollBarRange();
1215 0 : }
1216 :
1217 0 : IMPL_LINK(ScMultiTextWnd, ModifyHdl, EENotify*, pNotify)
1218 : {
1219 0 : ScTextWnd::NotifyHdl( pNotify );
1220 0 : return 0;
1221 : }
1222 :
1223 0 : IMPL_LINK(ScMultiTextWnd, NotifyHdl, EENotify*, pNotify)
1224 : {
1225 : // need to process EE_NOTIFY_TEXTVIEWSCROLLED here
1226 : // sometimes we don't seem to get EE_NOTIFY_TEXTVIEWSCROLLED e.g. when
1227 : // we insert text at the begining of the text so the cursor never moves
1228 : // down to generate a scroll event
1229 :
1230 0 : if ( pNotify && ( pNotify->eNotificationType == EE_NOTIFY_TEXTVIEWSCROLLED
1231 : || pNotify->eNotificationType == EE_NOTIFY_TEXTHEIGHTCHANGED ) )
1232 0 : SetScrollBarRange();
1233 0 : return 0;
1234 : }
1235 :
1236 0 : long ScMultiTextWnd::GetEditEngTxtHeight()
1237 : {
1238 0 : return pEditView ? pEditView->GetEditEngine()->GetTextHeight() : 0;
1239 : }
1240 :
1241 0 : void ScMultiTextWnd::SetScrollBarRange()
1242 : {
1243 0 : if ( pEditView )
1244 : {
1245 0 : ScrollBar& rVBar = mrGroupBar.GetScrollBar();
1246 0 : rVBar.SetRange( Range( 0, GetEditEngTxtHeight() ) );
1247 0 : long currentDocPos = pEditView->GetVisArea().TopLeft().Y();
1248 0 : rVBar.SetThumbPos( currentDocPos );
1249 : }
1250 0 : }
1251 :
1252 : void
1253 0 : ScMultiTextWnd::DoScroll()
1254 : {
1255 0 : if ( pEditView )
1256 : {
1257 0 : ScrollBar& rVBar = mrGroupBar.GetScrollBar();
1258 0 : long currentDocPos = pEditView->GetVisArea().TopLeft().Y();
1259 0 : long nDiff = currentDocPos - rVBar.GetThumbPos();
1260 0 : pEditView->Scroll( 0, nDiff );
1261 0 : currentDocPos = pEditView->GetVisArea().TopLeft().Y();
1262 0 : rVBar.SetThumbPos( currentDocPos );
1263 : }
1264 0 : }
1265 :
1266 0 : void ScMultiTextWnd::StartEditEngine()
1267 : {
1268 : // Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1269 0 : SfxObjectShell* pObjSh = SfxObjectShell::Current();
1270 0 : if ( pObjSh && pObjSh->IsInModalMode() )
1271 0 : return;
1272 :
1273 0 : if ( !pEditView || !pEditEngine )
1274 : {
1275 0 : InitEditEngine();
1276 : }
1277 :
1278 0 : SC_MOD()->SetInputMode( SC_INPUT_TOP );
1279 :
1280 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1281 0 : if (pViewFrm)
1282 0 : pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
1283 : }
1284 :
1285 0 : static void lcl_ExtendEditFontAttribs( SfxItemSet& rSet )
1286 : {
1287 0 : const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO );
1288 0 : rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK );
1289 0 : rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL );
1290 0 : const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT );
1291 0 : rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK );
1292 0 : rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL );
1293 0 : const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT );
1294 0 : rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
1295 0 : rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
1296 0 : const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC );
1297 0 : rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
1298 0 : rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
1299 0 : const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE );
1300 0 : rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
1301 0 : rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
1302 0 : }
1303 :
1304 0 : static void lcl_ModifyRTLDefaults( SfxItemSet& rSet )
1305 : {
1306 0 : rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1307 :
1308 : // always using rtl writing direction would break formulas
1309 : //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1310 :
1311 : // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
1312 : // sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be
1313 : // increased to not see the beginning of the next line.
1314 0 : SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
1315 0 : aItem.SetPropLineSpace( 200 );
1316 0 : rSet.Put( aItem );
1317 0 : }
1318 :
1319 0 : static void lcl_ModifyRTLVisArea( EditView* pEditView )
1320 : {
1321 0 : Rectangle aVisArea = pEditView->GetVisArea();
1322 0 : Size aPaper = pEditView->GetEditEngine()->GetPaperSize();
1323 0 : long nDiff = aPaper.Width() - aVisArea.Right();
1324 0 : aVisArea.Left() += nDiff;
1325 0 : aVisArea.Right() += nDiff;
1326 0 : pEditView->SetVisArea(aVisArea);
1327 0 : }
1328 :
1329 :
1330 0 : void ScMultiTextWnd::InitEditEngine()
1331 : {
1332 : ScFieldEditEngine* pNew;
1333 0 : ScTabViewShell* pViewSh = GetViewShell();
1334 0 : ScDocShell* pDocSh = NULL;
1335 0 : if ( pViewSh )
1336 : {
1337 0 : pDocSh = pViewSh->GetViewData()->GetDocShell();
1338 0 : ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
1339 0 : pNew = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
1340 : }
1341 : else
1342 0 : pNew = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
1343 0 : pNew->SetExecuteURL( false );
1344 0 : pEditEngine = pNew;
1345 :
1346 0 : Size barSize=GetSizePixel();
1347 0 : pEditEngine->SetUpdateMode( false );
1348 0 : pEditEngine->SetPaperSize( PixelToLogic(Size(barSize.Width(),10000)) );
1349 : pEditEngine->SetWordDelimiters(
1350 0 : ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1351 :
1352 0 : UpdateAutoCorrFlag();
1353 :
1354 : {
1355 0 : SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1356 0 : pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
1357 0 : lcl_ExtendEditFontAttribs( *pSet );
1358 : // turn off script spacing to match DrawText output
1359 0 : pSet->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
1360 0 : if ( bIsRTL )
1361 0 : lcl_ModifyRTLDefaults( *pSet );
1362 0 : pEditEngine->SetDefaults( pSet );
1363 : }
1364 :
1365 : // Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1366 : // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1367 :
1368 0 : sal_Bool bFilled = false;
1369 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1370 0 : if ( pHdl ) //! Testen, ob's der richtige InputHdl ist?
1371 0 : bFilled = pHdl->GetTextAndFields( *pEditEngine );
1372 :
1373 0 : pEditEngine->SetUpdateMode( sal_True );
1374 :
1375 : // aString ist die Wahrheit...
1376 0 : if ( bFilled && pEditEngine->GetText() == aString )
1377 0 : Invalidate(); // Repaint fuer (hinterlegte) Felder
1378 : else
1379 0 : pEditEngine->SetText(aString); // dann wenigstens den richtigen Text
1380 :
1381 0 : pEditView = new EditView( pEditEngine, this );
1382 0 : pEditView->SetInsertMode(bIsInsertMode);
1383 :
1384 : // Text aus Clipboard wird als ASCII einzeilig uebernommen
1385 0 : sal_uLong n = pEditView->GetControlWord();
1386 0 : pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );
1387 :
1388 0 : pEditEngine->InsertView( pEditView, EE_APPEND );
1389 :
1390 0 : Resize();
1391 :
1392 0 : if ( bIsRTL )
1393 0 : lcl_ModifyRTLVisArea( pEditView );
1394 :
1395 0 : pEditEngine->SetModifyHdl(LINK(this, ScMultiTextWnd, ModifyHdl));
1396 0 : pEditEngine->SetNotifyHdl(LINK(this, ScMultiTextWnd, NotifyHdl));
1397 :
1398 0 : if (!maAccTextDatas.empty())
1399 0 : maAccTextDatas.back()->StartEdit();
1400 :
1401 : // as long as EditEngine and DrawText sometimes differ for CTL text,
1402 : // repaint now to have the EditEngine's version visible
1403 0 : if (pDocSh)
1404 : {
1405 0 : ScDocument* pDoc = pDocSh->GetDocument(); // any document
1406 0 : sal_uInt8 nScript = pDoc->GetStringScriptType( aString );
1407 0 : if ( nScript & SCRIPTTYPE_COMPLEX )
1408 0 : Invalidate();
1409 : }
1410 0 : }
1411 :
1412 0 : void ScMultiTextWnd::StopEditEngine( sal_Bool bAll )
1413 : {
1414 0 : if ( pEditEngine )
1415 0 : pEditEngine->SetNotifyHdl(Link());
1416 0 : ScTextWnd::StopEditEngine( bAll );
1417 0 : }
1418 :
1419 0 : void ScMultiTextWnd::SetTextString( const String& rNewString )
1420 : {
1421 : // Ideally it would be best to create on demand the EditEngine/EditView here, but... for
1422 : // the initialisation scenario where a cell is first clicked on we end up with the text in the
1423 : // inputbar window scrolled to the bottom if we do that here ( because the tableview and topview
1424 : // are synced I guess ).
1425 : // should fix that I suppose :-/ need to look a bit further into that
1426 0 : mbInvalidate = true; // ensure next Paint ( that uses editengine ) call will call Invalidate first
1427 0 : ScTextWnd::SetTextString( rNewString );
1428 0 : SetScrollBarRange();
1429 0 : DoScroll();
1430 0 : }
1431 : //========================================================================
1432 : // ScTextWnd
1433 : //========================================================================
1434 :
1435 0 : ScTextWnd::ScTextWnd( Window* pParent, ScTabViewShell* pViewSh )
1436 : : ScTextWndBase ( pParent, WinBits(WB_HIDE | WB_BORDER) ),
1437 : DragSourceHelper( this ),
1438 : pEditEngine ( NULL ),
1439 : pEditView ( NULL ),
1440 : bIsInsertMode( sal_True ),
1441 : bFormulaMode ( false ),
1442 : bInputMode ( false ),
1443 0 : mpViewShell(pViewSh)
1444 : {
1445 0 : EnableRTL( false ); // EditEngine can't be used with VCL EnableRTL
1446 :
1447 0 : bIsRTL = GetSettings().GetLayoutRTL();
1448 :
1449 : // always use application font, so a font with cjk chars can be installed
1450 0 : Font aAppFont = GetFont();
1451 0 : aTextFont = aAppFont;
1452 0 : aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln
1453 :
1454 0 : const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1455 :
1456 0 : Color aBgColor= rStyleSettings.GetWindowColor();
1457 0 : Color aTxtColor= rStyleSettings.GetWindowTextColor();
1458 :
1459 0 : aTextFont.SetTransparent ( sal_True );
1460 0 : aTextFont.SetFillColor ( aBgColor );
1461 : //aTextFont.SetColor ( COL_FIELDTEXT );
1462 0 : aTextFont.SetColor (aTxtColor);
1463 0 : aTextFont.SetWeight ( WEIGHT_NORMAL );
1464 :
1465 0 : Size aSize(1,TBX_WINDOW_HEIGHT);
1466 0 : Size aMinEditSize( Edit::GetMinimumEditSize() );
1467 0 : if( aMinEditSize.Height() > aSize.Height() )
1468 0 : aSize.Height() = aMinEditSize.Height();
1469 0 : SetSizePixel ( aSize );
1470 0 : SetBackground ( aBgColor );
1471 0 : SetLineColor ( COL_BLACK );
1472 0 : SetMapMode ( MAP_TWIP );
1473 0 : SetPointer ( POINTER_TEXT );
1474 0 : SetFont( aTextFont );
1475 0 : }
1476 :
1477 0 : ScTextWnd::~ScTextWnd()
1478 : {
1479 0 : while (!maAccTextDatas.empty()) {
1480 0 : maAccTextDatas.back()->Dispose();
1481 : }
1482 0 : delete pEditView;
1483 0 : delete pEditEngine;
1484 0 : }
1485 :
1486 0 : void ScTextWnd::Paint( const Rectangle& rRec )
1487 : {
1488 0 : if (pEditView)
1489 0 : pEditView->Paint( rRec );
1490 : else
1491 : {
1492 0 : SetFont( aTextFont );
1493 :
1494 0 : long nDiff = GetOutputSizePixel().Height()
1495 0 : - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
1496 : // if (nDiff<2) nDiff=2; // mind. 1 Pixel
1497 :
1498 0 : long nStartPos = 0;
1499 0 : if ( bIsRTL )
1500 : {
1501 : // right-align
1502 0 : nStartPos += GetOutputSizePixel().Width() -
1503 0 : LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width();
1504 :
1505 : // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem
1506 : }
1507 :
1508 0 : DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString );
1509 : }
1510 0 : }
1511 :
1512 0 : void ScTextWnd::Resize()
1513 : {
1514 0 : if (pEditView)
1515 : {
1516 0 : Size aSize = GetOutputSizePixel();
1517 0 : long nDiff = aSize.Height()
1518 0 : - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
1519 :
1520 : pEditView->SetOutputArea(
1521 : PixelToLogic( Rectangle( Point( 0, (nDiff > 0) ? nDiff/2 : 1 ),
1522 0 : aSize ) ) );
1523 : }
1524 0 : }
1525 :
1526 0 : void ScTextWnd::MouseMove( const MouseEvent& rMEvt )
1527 : {
1528 0 : if (pEditView)
1529 0 : pEditView->MouseMove( rMEvt );
1530 0 : }
1531 :
1532 0 : void ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt )
1533 : {
1534 0 : if (!HasFocus())
1535 : {
1536 0 : StartEditEngine();
1537 0 : if ( SC_MOD()->IsEditMode() )
1538 0 : GrabFocus();
1539 : }
1540 :
1541 0 : if (pEditView)
1542 : {
1543 0 : pEditView->SetEditEngineUpdateMode( sal_True );
1544 0 : pEditView->MouseButtonDown( rMEvt );
1545 : }
1546 0 : }
1547 :
1548 0 : void ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt )
1549 : {
1550 0 : if (pEditView)
1551 0 : if (pEditView->MouseButtonUp( rMEvt ))
1552 : {
1553 0 : if ( rMEvt.IsMiddle() &&
1554 0 : GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
1555 : {
1556 : // EditView may have pasted from selection
1557 0 : SC_MOD()->InputChanged( pEditView );
1558 : }
1559 : else
1560 0 : SC_MOD()->InputSelection( pEditView );
1561 : }
1562 0 : }
1563 :
1564 0 : void ScTextWnd::Command( const CommandEvent& rCEvt )
1565 : {
1566 0 : bInputMode = sal_True;
1567 0 : sal_uInt16 nCommand = rCEvt.GetCommand();
1568 0 : if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ )
1569 : {
1570 0 : ScModule* pScMod = SC_MOD();
1571 0 : ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell();
1572 :
1573 : // don't modify the font defaults here - the right defaults are
1574 : // already set in StartEditEngine when the EditEngine is created
1575 :
1576 : // verhindern, dass die EditView beim View-Umschalten wegkommt
1577 0 : pScMod->SetInEditCommand( true );
1578 0 : pEditView->Command( rCEvt );
1579 0 : pScMod->SetInEditCommand( false );
1580 :
1581 : // COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
1582 : // darum in dem Fall kein InputChanged
1583 : //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten
1584 :
1585 0 : if ( nCommand == COMMAND_STARTDRAG )
1586 : {
1587 : // ist auf eine andere View gedraggt worden?
1588 0 : ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell();
1589 0 : if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL )
1590 : {
1591 0 : ScViewData* pViewData = pStartViewSh->GetViewData();
1592 0 : ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh );
1593 0 : if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) )
1594 : {
1595 0 : pHdl->CancelHandler();
1596 0 : pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv
1597 : }
1598 : }
1599 : }
1600 0 : else if ( nCommand == COMMAND_CURSORPOS )
1601 : {
1602 : // don't call InputChanged for COMMAND_CURSORPOS
1603 : }
1604 0 : else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE )
1605 : {
1606 : // #i55929# Font and font size state depends on input language if nothing is selected,
1607 : // so the slots have to be invalidated when the input language is changed.
1608 :
1609 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1610 0 : if (pViewFrm)
1611 : {
1612 0 : SfxBindings& rBindings = pViewFrm->GetBindings();
1613 0 : rBindings.Invalidate( SID_ATTR_CHAR_FONT );
1614 0 : rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
1615 : }
1616 : }
1617 0 : else if ( nCommand == COMMAND_WHEEL )
1618 : {
1619 : //don't call InputChanged for COMMAND_WHEEL
1620 : }
1621 : else
1622 0 : SC_MOD()->InputChanged( pEditView );
1623 : }
1624 : else
1625 0 : Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern...
1626 :
1627 0 : bInputMode = false;
1628 0 : }
1629 :
1630 0 : void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
1631 : {
1632 0 : if ( pEditView )
1633 : {
1634 0 : CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
1635 0 : pEditView->Command( aDragEvent );
1636 :
1637 : // handling of d&d to different view (CancelHandler) can't be done here,
1638 : // because the call returns before d&d is complete.
1639 : }
1640 0 : }
1641 :
1642 0 : void ScTextWnd::KeyInput(const KeyEvent& rKEvt)
1643 : {
1644 0 : bInputMode = sal_True;
1645 0 : if (!SC_MOD()->InputKeyEvent( rKEvt ))
1646 : {
1647 0 : sal_Bool bUsed = false;
1648 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1649 0 : if ( pViewSh )
1650 0 : bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe
1651 0 : if (!bUsed)
1652 0 : Window::KeyInput( rKEvt );
1653 : }
1654 0 : bInputMode = false;
1655 0 : }
1656 :
1657 0 : void ScTextWnd::GetFocus()
1658 : {
1659 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1660 0 : if ( pViewSh )
1661 0 : pViewSh->SetFormShellAtTop( false ); // focus in input line -> FormShell no longer on top
1662 0 : }
1663 :
1664 0 : void ScTextWnd::LoseFocus()
1665 : {
1666 0 : }
1667 :
1668 0 : String ScTextWnd::GetText() const
1669 : {
1670 : // ueberladen, um per Testtool an den Text heranzukommen
1671 :
1672 0 : if ( pEditEngine )
1673 0 : return pEditEngine->GetText();
1674 : else
1675 0 : return GetTextString();
1676 : }
1677 :
1678 0 : void ScTextWnd::SetFormulaMode( sal_Bool bSet )
1679 : {
1680 0 : if ( bSet != bFormulaMode )
1681 : {
1682 0 : bFormulaMode = bSet;
1683 0 : UpdateAutoCorrFlag();
1684 : }
1685 0 : }
1686 :
1687 0 : void ScTextWnd::UpdateAutoCorrFlag()
1688 : {
1689 0 : if ( pEditEngine )
1690 : {
1691 0 : sal_uLong nControl = pEditEngine->GetControlWord();
1692 0 : sal_uLong nOld = nControl;
1693 0 : if ( bFormulaMode )
1694 0 : nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln
1695 : else
1696 0 : nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon
1697 0 : if ( nControl != nOld )
1698 0 : pEditEngine->SetControlWord( nControl );
1699 : }
1700 0 : }
1701 :
1702 0 : ScTabViewShell* ScTextWnd::GetViewShell()
1703 : {
1704 0 : return mpViewShell;
1705 : }
1706 :
1707 0 : void ScTextWnd::StartEditEngine()
1708 : {
1709 : // Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
1710 0 : SfxObjectShell* pObjSh = SfxObjectShell::Current();
1711 0 : if ( pObjSh && pObjSh->IsInModalMode() )
1712 0 : return;
1713 :
1714 0 : if ( !pEditView || !pEditEngine )
1715 : {
1716 : ScFieldEditEngine* pNew;
1717 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1718 0 : if ( pViewSh )
1719 : {
1720 0 : ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
1721 0 : pNew = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
1722 : }
1723 : else
1724 0 : pNew = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
1725 0 : pNew->SetExecuteURL( false );
1726 0 : pEditEngine = pNew;
1727 :
1728 0 : pEditEngine->SetUpdateMode( false );
1729 0 : pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
1730 : pEditEngine->SetWordDelimiters(
1731 0 : ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1732 :
1733 0 : UpdateAutoCorrFlag();
1734 :
1735 : {
1736 0 : SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1737 0 : pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
1738 0 : lcl_ExtendEditFontAttribs( *pSet );
1739 : // turn off script spacing to match DrawText output
1740 0 : pSet->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
1741 0 : if ( bIsRTL )
1742 0 : lcl_ModifyRTLDefaults( *pSet );
1743 0 : pEditEngine->SetDefaults( pSet );
1744 : }
1745 :
1746 : // Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
1747 : // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
1748 :
1749 0 : sal_Bool bFilled = false;
1750 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1751 0 : if ( pHdl ) //! Testen, ob's der richtige InputHdl ist?
1752 0 : bFilled = pHdl->GetTextAndFields( *pEditEngine );
1753 :
1754 0 : pEditEngine->SetUpdateMode( sal_True );
1755 :
1756 : // aString ist die Wahrheit...
1757 0 : if ( bFilled && pEditEngine->GetText() == aString )
1758 0 : Invalidate(); // Repaint fuer (hinterlegte) Felder
1759 : else
1760 0 : pEditEngine->SetText(aString); // dann wenigstens den richtigen Text
1761 :
1762 0 : pEditView = new EditView( pEditEngine, this );
1763 0 : pEditView->SetInsertMode(bIsInsertMode);
1764 :
1765 : // Text aus Clipboard wird als ASCII einzeilig uebernommen
1766 0 : sal_uLong n = pEditView->GetControlWord();
1767 0 : pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );
1768 :
1769 0 : pEditEngine->InsertView( pEditView, EE_APPEND );
1770 :
1771 0 : Resize();
1772 :
1773 0 : if ( bIsRTL )
1774 0 : lcl_ModifyRTLVisArea( pEditView );
1775 :
1776 0 : pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl));
1777 :
1778 0 : if (!maAccTextDatas.empty())
1779 0 : maAccTextDatas.back()->StartEdit();
1780 :
1781 : // as long as EditEngine and DrawText sometimes differ for CTL text,
1782 : // repaint now to have the EditEngine's version visible
1783 : // SfxObjectShell* pObjSh = SfxObjectShell::Current();
1784 0 : if ( pObjSh && pObjSh->ISA(ScDocShell) )
1785 : {
1786 0 : ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document
1787 0 : sal_uInt8 nScript = pDoc->GetStringScriptType( aString );
1788 0 : if ( nScript & SCRIPTTYPE_COMPLEX )
1789 0 : Invalidate();
1790 : }
1791 : }
1792 :
1793 0 : SC_MOD()->SetInputMode( SC_INPUT_TOP );
1794 :
1795 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1796 0 : if (pViewFrm)
1797 0 : pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
1798 : }
1799 :
1800 0 : IMPL_LINK_NOARG(ScTextWnd, NotifyHdl)
1801 : {
1802 0 : if (pEditView && !bInputMode)
1803 : {
1804 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1805 :
1806 : // Use the InputHandler's InOwnChange flag to prevent calling InputChanged
1807 : // while an InputHandler method is modifying the EditEngine content
1808 :
1809 0 : if ( pHdl && !pHdl->IsInOwnChange() )
1810 0 : pHdl->InputChanged( pEditView, sal_True ); // #i20282# InputChanged must know if called from modify handler
1811 : }
1812 :
1813 0 : return 0;
1814 : }
1815 :
1816 0 : void ScTextWnd::StopEditEngine( sal_Bool bAll )
1817 : {
1818 0 : if (pEditView)
1819 : {
1820 0 : if (!maAccTextDatas.empty())
1821 0 : maAccTextDatas.back()->EndEdit();
1822 :
1823 0 : ScModule* pScMod = SC_MOD();
1824 :
1825 0 : if (!bAll)
1826 0 : pScMod->InputSelection( pEditView );
1827 0 : aString = pEditEngine->GetText();
1828 0 : bIsInsertMode = pEditView->IsInsertMode();
1829 0 : sal_Bool bSelection = pEditView->HasSelection();
1830 0 : pEditEngine->SetModifyHdl(Link());
1831 0 : DELETEZ(pEditView);
1832 0 : DELETEZ(pEditEngine);
1833 :
1834 0 : if ( pScMod->IsEditMode() && !bAll )
1835 0 : pScMod->SetInputMode(SC_INPUT_TABLE);
1836 :
1837 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1838 0 : if (pViewFrm)
1839 0 : pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
1840 :
1841 0 : if (bSelection)
1842 0 : Invalidate(); // damit Selektion nicht stehenbleibt
1843 : }
1844 0 : }
1845 :
1846 0 : void ScTextWnd::SetTextString( const String& rNewString )
1847 : {
1848 0 : if ( rNewString != aString )
1849 : {
1850 0 : bInputMode = sal_True;
1851 :
1852 : // Position der Aenderung suchen, nur Rest painten
1853 :
1854 0 : if (!pEditEngine)
1855 : {
1856 : sal_Bool bPaintAll;
1857 0 : if ( bIsRTL )
1858 0 : bPaintAll = sal_True;
1859 : else
1860 : {
1861 : // test if CTL script type is involved
1862 0 : sal_uInt8 nOldScript = 0;
1863 0 : sal_uInt8 nNewScript = 0;
1864 0 : SfxObjectShell* pObjSh = SfxObjectShell::Current();
1865 0 : if ( pObjSh && pObjSh->ISA(ScDocShell) )
1866 : {
1867 : // any document can be used (used only for its break iterator)
1868 0 : ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
1869 0 : nOldScript = pDoc->GetStringScriptType( aString );
1870 0 : nNewScript = pDoc->GetStringScriptType( rNewString );
1871 : }
1872 0 : bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX );
1873 : }
1874 :
1875 0 : if ( bPaintAll )
1876 : {
1877 : // if CTL is involved, the whole text has to be redrawn
1878 0 : Invalidate();
1879 : }
1880 : else
1881 : {
1882 0 : long nTextSize = 0;
1883 : xub_StrLen nDifPos;
1884 0 : if (rNewString.Len() > aString.Len())
1885 0 : nDifPos = rNewString.Match(aString);
1886 : else
1887 0 : nDifPos = aString.Match(rNewString);
1888 :
1889 0 : long nSize1 = GetTextWidth(aString);
1890 0 : long nSize2 = GetTextWidth(rNewString);
1891 0 : if ( nSize1>0 && nSize2>0 )
1892 0 : nTextSize = Max( nSize1, nSize2 );
1893 : else
1894 0 : nTextSize = GetOutputSize().Width(); // Ueberlauf
1895 :
1896 0 : if (nDifPos == STRING_MATCH)
1897 0 : nDifPos = 0;
1898 :
1899 : // -1 wegen Rundung und "A"
1900 0 : Point aLogicStart = PixelToLogic(Point(0,0));
1901 0 : long nStartPos = aLogicStart.X();
1902 0 : long nInvPos = nStartPos;
1903 0 : if (nDifPos)
1904 0 : nInvPos += GetTextWidth(aString,0,nDifPos);
1905 :
1906 0 : sal_uInt16 nFlags = 0;
1907 0 : if ( nDifPos == aString.Len() ) // only new characters appended
1908 0 : nFlags = INVALIDATE_NOERASE; // then background is already clear
1909 : Invalidate( Rectangle( nInvPos, 0,
1910 0 : nStartPos+nTextSize, GetOutputSize().Height()-1 ),
1911 0 : nFlags );
1912 : }
1913 : }
1914 : else
1915 : {
1916 0 : pEditEngine->SetText(rNewString);
1917 : }
1918 :
1919 0 : aString = rNewString;
1920 :
1921 0 : if (!maAccTextDatas.empty())
1922 0 : maAccTextDatas.back()->TextChanged();
1923 :
1924 0 : bInputMode = false;
1925 : }
1926 0 : }
1927 :
1928 0 : const String& ScTextWnd::GetTextString() const
1929 : {
1930 0 : return aString;
1931 : }
1932 :
1933 0 : sal_Bool ScTextWnd::IsInputActive()
1934 : {
1935 0 : return HasFocus();
1936 : }
1937 :
1938 0 : EditView* ScTextWnd::GetEditView()
1939 : {
1940 0 : return pEditView;
1941 : }
1942 :
1943 0 : void ScTextWnd::MakeDialogEditView()
1944 : {
1945 0 : if ( pEditView ) return;
1946 :
1947 : ScFieldEditEngine* pNew;
1948 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
1949 0 : if ( pViewSh )
1950 : {
1951 0 : ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
1952 0 : pNew = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
1953 : }
1954 : else
1955 0 : pNew = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
1956 0 : pNew->SetExecuteURL( false );
1957 0 : pEditEngine = pNew;
1958 :
1959 0 : pEditEngine->SetUpdateMode( false );
1960 0 : pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' );
1961 0 : pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
1962 :
1963 0 : SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1964 0 : pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
1965 0 : lcl_ExtendEditFontAttribs( *pSet );
1966 0 : if ( bIsRTL )
1967 0 : lcl_ModifyRTLDefaults( *pSet );
1968 0 : pEditEngine->SetDefaults( pSet );
1969 0 : pEditEngine->SetUpdateMode( sal_True );
1970 :
1971 0 : pEditView = new EditView( pEditEngine, this );
1972 0 : pEditEngine->InsertView( pEditView, EE_APPEND );
1973 :
1974 0 : Resize();
1975 :
1976 0 : if ( bIsRTL )
1977 0 : lcl_ModifyRTLVisArea( pEditView );
1978 :
1979 0 : if (!maAccTextDatas.empty())
1980 0 : maAccTextDatas.back()->StartEdit();
1981 : }
1982 :
1983 0 : void ScTextWnd::ImplInitSettings()
1984 : {
1985 0 : bIsRTL = GetSettings().GetLayoutRTL();
1986 :
1987 0 : const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1988 :
1989 0 : Color aBgColor= rStyleSettings.GetWindowColor();
1990 0 : Color aTxtColor= rStyleSettings.GetWindowTextColor();
1991 :
1992 0 : aTextFont.SetFillColor ( aBgColor );
1993 0 : aTextFont.SetColor (aTxtColor);
1994 0 : SetBackground ( aBgColor );
1995 0 : Invalidate();
1996 0 : }
1997 :
1998 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible()
1999 : {
2000 : return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this,
2001 : rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))),
2002 0 : rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), ScAccessibleEditObject::EditLine);
2003 : }
2004 :
2005 0 : void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
2006 : {
2007 : OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == maAccTextDatas.end(),
2008 : "ScTextWnd::InsertAccessibleTextData - passed object already registered" );
2009 0 : maAccTextDatas.push_back( &rTextData );
2010 0 : }
2011 :
2012 0 : void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
2013 : {
2014 0 : AccTextDataVector::iterator aEnd = maAccTextDatas.end();
2015 0 : AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData );
2016 : OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
2017 0 : if( aIt != aEnd )
2018 0 : maAccTextDatas.erase( aIt );
2019 0 : }
2020 :
2021 : // -----------------------------------------------------------------------
2022 :
2023 0 : void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt )
2024 : {
2025 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2026 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2027 : {
2028 0 : ImplInitSettings();
2029 0 : Invalidate();
2030 : }
2031 : else
2032 0 : Window::DataChanged( rDCEvt );
2033 0 : }
2034 :
2035 0 : void ScTextWnd::TextGrabFocus()
2036 : {
2037 0 : GrabFocus();
2038 0 : }
2039 :
2040 : //========================================================================
2041 : // Positionsfenster
2042 : //========================================================================
2043 :
2044 0 : ScPosWnd::ScPosWnd( Window* pParent ) :
2045 : ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ),
2046 : pAccel ( NULL ),
2047 : nTipVisible ( 0 ),
2048 0 : bFormulaMode( false )
2049 : {
2050 : Size aSize( GetTextWidth( rtl::OUString("GW99999:GW99999") ),
2051 0 : GetTextHeight() );
2052 0 : aSize.Width() += 25; // ??
2053 0 : aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..."
2054 0 : SetSizePixel( aSize );
2055 :
2056 0 : FillRangeNames();
2057 :
2058 0 : StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates
2059 0 : }
2060 :
2061 0 : ScPosWnd::~ScPosWnd()
2062 : {
2063 0 : EndListening( *SFX_APP() );
2064 :
2065 0 : HideTip();
2066 :
2067 0 : delete pAccel;
2068 0 : }
2069 :
2070 0 : void ScPosWnd::SetFormulaMode( sal_Bool bSet )
2071 : {
2072 0 : if ( bSet != bFormulaMode )
2073 : {
2074 0 : bFormulaMode = bSet;
2075 :
2076 0 : if ( bSet )
2077 0 : FillFunctions();
2078 : else
2079 0 : FillRangeNames();
2080 :
2081 0 : HideTip();
2082 : }
2083 0 : }
2084 :
2085 0 : void ScPosWnd::SetPos( const String& rPosStr )
2086 : {
2087 0 : if ( aPosStr != rPosStr )
2088 : {
2089 0 : aPosStr = rPosStr;
2090 0 : SetText(aPosStr);
2091 : }
2092 0 : }
2093 :
2094 : namespace {
2095 :
2096 0 : rtl::OUString createLocalRangeName(const rtl::OUString& rName, const rtl::OUString& rTableName)
2097 : {
2098 0 : rtl::OUStringBuffer aString (rName);
2099 0 : aString.append(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (")));
2100 0 : aString.append(rTableName);
2101 0 : aString.append(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
2102 0 : return aString.makeStringAndClear();
2103 : }
2104 :
2105 : }
2106 :
2107 0 : void ScPosWnd::FillRangeNames()
2108 : {
2109 0 : Clear();
2110 :
2111 0 : SfxObjectShell* pObjSh = SfxObjectShell::Current();
2112 0 : if ( pObjSh && pObjSh->ISA(ScDocShell) )
2113 : {
2114 0 : ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
2115 :
2116 0 : InsertEntry(ScGlobal::GetRscString( STR_MANAGE_NAMES ));
2117 0 : SetSeparatorPos(0);
2118 :
2119 0 : ScRange aDummy;
2120 0 : std::set<rtl::OUString> aSet;
2121 0 : ScRangeName* pRangeNames = pDoc->GetRangeName();
2122 0 : if (!pRangeNames->empty())
2123 : {
2124 0 : ScRangeName::const_iterator itrBeg = pRangeNames->begin(), itrEnd = pRangeNames->end();
2125 0 : for (ScRangeName::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
2126 : {
2127 0 : if (itr->second->IsValidReference(aDummy))
2128 0 : aSet.insert(itr->second->GetName());
2129 : }
2130 : }
2131 0 : for (SCTAB i = 0; i < pDoc->GetTableCount(); ++i)
2132 : {
2133 0 : ScRangeName* pLocalRangeName = pDoc->GetRangeName(i);
2134 0 : if (pLocalRangeName && !pLocalRangeName->empty())
2135 : {
2136 0 : rtl::OUString aTableName;
2137 0 : pDoc->GetName(i, aTableName);
2138 0 : for (ScRangeName::const_iterator itr = pLocalRangeName->begin(); itr != pLocalRangeName->end(); ++itr)
2139 : {
2140 0 : if (itr->second->IsValidReference(aDummy))
2141 0 : aSet.insert(createLocalRangeName(itr->second->GetName(), aTableName));
2142 0 : }
2143 : }
2144 : }
2145 :
2146 0 : if (!aSet.empty())
2147 : {
2148 0 : for (std::set<rtl::OUString>::iterator itr = aSet.begin();
2149 0 : itr != aSet.end(); ++itr)
2150 : {
2151 0 : InsertEntry(*itr);
2152 : }
2153 0 : }
2154 : }
2155 0 : SetText(aPosStr);
2156 0 : }
2157 :
2158 0 : void ScPosWnd::FillFunctions()
2159 : {
2160 0 : Clear();
2161 :
2162 0 : String aFirstName;
2163 0 : const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
2164 0 : sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount();
2165 0 : const sal_uInt16* pMRUList = rOpt.GetLRUFuncList();
2166 0 : if (pMRUList)
2167 : {
2168 0 : const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
2169 0 : sal_uLong nListCount = pFuncList->GetCount();
2170 0 : for (sal_uInt16 i=0; i<nMRUCount; i++)
2171 : {
2172 0 : sal_uInt16 nId = pMRUList[i];
2173 0 : for (sal_uLong j=0; j<nListCount; j++)
2174 : {
2175 0 : const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
2176 0 : if ( pDesc->nFIndex == nId && pDesc->pFuncName )
2177 : {
2178 0 : InsertEntry( *pDesc->pFuncName );
2179 0 : if (!aFirstName.Len())
2180 0 : aFirstName = *pDesc->pFuncName;
2181 0 : break; // nicht weitersuchen
2182 : }
2183 : }
2184 : }
2185 : }
2186 :
2187 : //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
2188 : //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!
2189 :
2190 : // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
2191 :
2192 0 : SetText(aFirstName);
2193 0 : }
2194 :
2195 0 : void ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint )
2196 : {
2197 0 : if ( !bFormulaMode )
2198 : {
2199 : // muss die Liste der Bereichsnamen updgedated werden?
2200 :
2201 0 : if ( rHint.ISA(SfxSimpleHint) )
2202 : {
2203 0 : sal_uLong nHintId = ((SfxSimpleHint&)rHint).GetId();
2204 0 : if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL)
2205 0 : FillRangeNames();
2206 : }
2207 0 : else if ( rHint.ISA(SfxEventHint) )
2208 : {
2209 0 : sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId();
2210 0 : if ( nEventId == SFX_EVENT_ACTIVATEDOC )
2211 0 : FillRangeNames();
2212 : }
2213 : }
2214 0 : }
2215 :
2216 0 : void ScPosWnd::HideTip()
2217 : {
2218 0 : if ( nTipVisible )
2219 : {
2220 0 : Help::HideTip( nTipVisible );
2221 0 : nTipVisible = 0;
2222 : }
2223 0 : }
2224 :
2225 0 : static ScNameInputType lcl_GetInputType( const String& rText )
2226 : {
2227 0 : ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error
2228 :
2229 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2230 0 : if ( pViewSh )
2231 : {
2232 0 : ScViewData* pViewData = pViewSh->GetViewData();
2233 0 : ScDocument* pDoc = pViewData->GetDocument();
2234 0 : SCTAB nTab = pViewData->GetTabNo();
2235 0 : formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
2236 :
2237 : // test in same order as in SID_CURRENTCELL execute
2238 :
2239 0 : ScRange aRange;
2240 0 : ScAddress aAddress;
2241 0 : ScRangeUtil aRangeUtil;
2242 : SCTAB nNameTab;
2243 : sal_Int32 nNumeric;
2244 :
2245 0 : if (rText == ScGlobal::GetRscString(STR_MANAGE_NAMES))
2246 0 : eRet = SC_MANAGE_NAMES;
2247 0 : else if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID )
2248 0 : eRet = SC_NAME_INPUT_RANGE;
2249 0 : else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID )
2250 0 : eRet = SC_NAME_INPUT_CELL;
2251 0 : else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) )
2252 0 : eRet = SC_NAME_INPUT_NAMEDRANGE;
2253 0 : else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) )
2254 0 : eRet = SC_NAME_INPUT_DATABASE;
2255 0 : else if ( comphelper::string::isdigitAsciiString( rText ) &&
2256 : ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
2257 0 : eRet = SC_NAME_INPUT_ROW;
2258 0 : else if ( pDoc->GetTable( rText, nNameTab ) )
2259 0 : eRet = SC_NAME_INPUT_SHEET;
2260 0 : else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range?
2261 : {
2262 0 : if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
2263 0 : eRet = SC_NAME_INPUT_DEFINE;
2264 : else
2265 0 : eRet = SC_NAME_INPUT_BAD_SELECTION;
2266 : }
2267 : else
2268 0 : eRet = SC_NAME_INPUT_BAD_NAME;
2269 : }
2270 :
2271 0 : return eRet;
2272 : }
2273 :
2274 0 : void ScPosWnd::Modify()
2275 : {
2276 0 : ComboBox::Modify();
2277 :
2278 0 : HideTip();
2279 :
2280 0 : if ( !IsTravelSelect() && !bFormulaMode )
2281 : {
2282 : // determine the action that would be taken for the current input
2283 :
2284 0 : ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view
2285 0 : sal_uInt16 nStrId = 0;
2286 0 : switch ( eType )
2287 : {
2288 : case SC_NAME_INPUT_CELL:
2289 0 : nStrId = STR_NAME_INPUT_CELL;
2290 0 : break;
2291 : case SC_NAME_INPUT_RANGE:
2292 : case SC_NAME_INPUT_NAMEDRANGE:
2293 0 : nStrId = STR_NAME_INPUT_RANGE; // named range or range reference
2294 0 : break;
2295 : case SC_NAME_INPUT_DATABASE:
2296 0 : nStrId = STR_NAME_INPUT_DBRANGE;
2297 0 : break;
2298 : case SC_NAME_INPUT_ROW:
2299 0 : nStrId = STR_NAME_INPUT_ROW;
2300 0 : break;
2301 : case SC_NAME_INPUT_SHEET:
2302 0 : nStrId = STR_NAME_INPUT_SHEET;
2303 0 : break;
2304 : case SC_NAME_INPUT_DEFINE:
2305 0 : nStrId = STR_NAME_INPUT_DEFINE;
2306 0 : break;
2307 : default:
2308 : // other cases (error): no tip help
2309 0 : break;
2310 : }
2311 :
2312 0 : if ( nStrId )
2313 : {
2314 : // show the help tip at the text cursor position
2315 :
2316 0 : Window* pWin = GetSubEdit();
2317 0 : if (!pWin)
2318 0 : pWin = this;
2319 0 : Point aPos;
2320 0 : Cursor* pCur = pWin->GetCursor();
2321 0 : if (pCur)
2322 0 : aPos = pWin->LogicToPixel( pCur->GetPos() );
2323 0 : aPos = pWin->OutputToScreenPixel( aPos );
2324 0 : Rectangle aRect( aPos, aPos );
2325 :
2326 0 : String aText = ScGlobal::GetRscString( nStrId );
2327 0 : sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
2328 0 : nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign);
2329 : }
2330 : }
2331 0 : }
2332 :
2333 0 : void ScPosWnd::Select()
2334 : {
2335 0 : ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag
2336 :
2337 0 : HideTip();
2338 :
2339 0 : if (!IsTravelSelect())
2340 0 : DoEnter();
2341 0 : }
2342 :
2343 0 : void ScPosWnd::DoEnter()
2344 : {
2345 0 : String aText = GetText();
2346 0 : if ( aText.Len() )
2347 : {
2348 0 : if ( bFormulaMode )
2349 : {
2350 0 : ScModule* pScMod = SC_MOD();
2351 0 : if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) )
2352 : {
2353 : // Funktions-Autopilot
2354 : //! mit dem bisher eingegebenen Text weiterarbeiten !!!
2355 :
2356 : //! new method at ScModule to query if function autopilot is open
2357 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
2358 0 : if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
2359 : pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
2360 0 : SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
2361 : }
2362 : else
2363 : {
2364 0 : ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
2365 0 : ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
2366 0 : if (pHdl)
2367 0 : pHdl->InsertFunction( aText );
2368 : }
2369 : }
2370 : else
2371 : {
2372 : // depending on the input, select something or create a new named range
2373 :
2374 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2375 0 : if ( pViewSh )
2376 : {
2377 0 : ScViewData* pViewData = pViewSh->GetViewData();
2378 0 : ScDocShell* pDocShell = pViewData->GetDocShell();
2379 0 : ScDocument* pDoc = pDocShell->GetDocument();
2380 :
2381 0 : ScNameInputType eType = lcl_GetInputType( aText );
2382 0 : if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION )
2383 : {
2384 0 : sal_uInt16 nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION;
2385 0 : pViewSh->ErrorMessage( nId );
2386 : }
2387 0 : else if ( eType == SC_NAME_INPUT_DEFINE )
2388 : {
2389 0 : ScRangeName* pNames = pDoc->GetRangeName();
2390 0 : ScRange aSelection;
2391 0 : if ( pNames && !pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aText)) &&
2392 0 : (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) )
2393 : {
2394 0 : ScRangeName aNewRanges( *pNames );
2395 0 : ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
2396 0 : String aContent;
2397 0 : aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
2398 0 : ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
2399 0 : if ( aNewRanges.insert(pNew) )
2400 : {
2401 0 : pDocShell->GetDocFunc().ModifyRangeNames( aNewRanges );
2402 0 : pViewSh->UpdateInputHandler(true);
2403 0 : }
2404 : }
2405 : }
2406 0 : else if (eType == SC_MANAGE_NAMES)
2407 : {
2408 0 : sal_uInt16 nId = ScNameDlgWrapper::GetChildWindowId();
2409 0 : SfxViewFrame* pViewFrm = pViewSh->GetViewFrame();
2410 0 : SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
2411 :
2412 0 : SC_MOD()->SetRefDialog( nId, pWnd ? false : sal_True );
2413 : }
2414 : else
2415 : {
2416 : // for all selection types, excecute the SID_CURRENTCELL slot.
2417 0 : if (eType == SC_NAME_INPUT_CELL || eType == SC_NAME_INPUT_RANGE)
2418 : {
2419 : // Note that SID_CURRENTCELL always expects address to
2420 : // be in Calc A1 format. Convert the text.
2421 0 : ScRange aRange(0,0,pViewData->GetTabNo());
2422 0 : aRange.ParseAny(aText, pDoc, pDoc->GetAddressConvention());
2423 0 : aRange.Format(aText, SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
2424 : }
2425 :
2426 0 : SfxStringItem aPosItem( SID_CURRENTCELL, aText );
2427 0 : SfxBoolItem aUnmarkItem( FN_PARAM_1, sal_True ); // remove existing selection
2428 :
2429 0 : pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL,
2430 : SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
2431 0 : &aPosItem, &aUnmarkItem, 0L );
2432 : }
2433 : }
2434 : }
2435 : }
2436 : else
2437 0 : SetText( aPosStr );
2438 :
2439 0 : ReleaseFocus_Impl();
2440 0 : }
2441 :
2442 0 : long ScPosWnd::Notify( NotifyEvent& rNEvt )
2443 : {
2444 0 : long nHandled = 0;
2445 :
2446 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
2447 : {
2448 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2449 :
2450 0 : switch ( pKEvt->GetKeyCode().GetCode() )
2451 : {
2452 : case KEY_RETURN:
2453 0 : DoEnter();
2454 0 : nHandled = 1;
2455 0 : break;
2456 :
2457 : case KEY_ESCAPE:
2458 0 : if (nTipVisible)
2459 : {
2460 : // escape when the tip help is shown: only hide the tip
2461 0 : HideTip();
2462 : }
2463 : else
2464 : {
2465 0 : if (!bFormulaMode)
2466 0 : SetText( aPosStr );
2467 0 : ReleaseFocus_Impl();
2468 : }
2469 0 : nHandled = 1;
2470 0 : break;
2471 : }
2472 : }
2473 :
2474 0 : if ( !nHandled )
2475 0 : nHandled = ComboBox::Notify( rNEvt );
2476 :
2477 0 : if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
2478 0 : HideTip();
2479 :
2480 0 : return nHandled;
2481 : }
2482 :
2483 0 : void ScPosWnd::ReleaseFocus_Impl()
2484 : {
2485 0 : HideTip();
2486 :
2487 0 : SfxViewShell* pCurSh = SfxViewShell::Current();
2488 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) );
2489 0 : if ( pHdl && pHdl->IsTopMode() )
2490 : {
2491 : // Focus wieder in die Eingabezeile?
2492 :
2493 0 : ScInputWindow* pInputWin = pHdl->GetInputWindow();
2494 0 : if (pInputWin)
2495 : {
2496 0 : pInputWin->TextGrabFocus();
2497 0 : return;
2498 : }
2499 : }
2500 :
2501 : // Focus auf die aktive View
2502 :
2503 0 : if ( pCurSh )
2504 : {
2505 0 : Window* pShellWnd = pCurSh->GetWindow();
2506 :
2507 0 : if ( pShellWnd )
2508 0 : pShellWnd->GrabFocus();
2509 : }
2510 15 : }
2511 :
2512 :
2513 :
2514 :
2515 :
2516 :
2517 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|