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