Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "scitems.hxx"
30 : : #include <editeng/eeitem.hxx>
31 : :
32 : : #include <sfx2/app.hxx>
33 : : #include <editeng/acorrcfg.hxx>
34 : : #include <svx/algitem.hxx>
35 : : #include <editeng/adjitem.hxx>
36 : : #include <editeng/brshitem.hxx>
37 : : #include <svtools/colorcfg.hxx>
38 : : #include <editeng/colritem.hxx>
39 : : #include <editeng/editobj.hxx>
40 : : #include <editeng/editstat.hxx>
41 : : #include <editeng/editview.hxx>
42 : : #include <editeng/escpitem.hxx>
43 : : #include <editeng/forbiddencharacterstable.hxx>
44 : : #include <editeng/langitem.hxx>
45 : : #include <editeng/svxacorr.hxx>
46 : : #include <editeng/unolingu.hxx>
47 : : #include <editeng/wghtitem.hxx>
48 : : #include <editeng/justifyitem.hxx>
49 : : #include <sfx2/bindings.hxx>
50 : : #include <sfx2/viewfrm.hxx>
51 : : #include <sfx2/dispatch.hxx>
52 : : #include <sfx2/docfile.hxx>
53 : : #include <sfx2/printer.hxx>
54 : : #include <svl/zforlist.hxx>
55 : : #include <unotools/localedatawrapper.hxx>
56 : : #include <vcl/help.hxx>
57 : : #include <vcl/cursor.hxx>
58 : : #include <tools/urlobj.hxx>
59 : : #include <comphelper/string.hxx>
60 : : #include <formula/formulahelper.hxx>
61 : :
62 : : #include "inputwin.hxx"
63 : : #include "tabvwsh.hxx"
64 : : #include "docsh.hxx"
65 : : #include "scmod.hxx"
66 : : #include "uiitems.hxx"
67 : : #include "global.hxx"
68 : : #include "sc.hrc"
69 : : #include "globstr.hrc"
70 : : #include "patattr.hxx"
71 : : #include "viewdata.hxx"
72 : : #include "document.hxx"
73 : : #include "docpool.hxx"
74 : : #include "editutil.hxx"
75 : : #include "appoptio.hxx"
76 : : #include "docoptio.hxx"
77 : : #include "validat.hxx"
78 : : #include "userlist.hxx"
79 : : #include "rfindlst.hxx"
80 : : #include "inputopt.hxx"
81 : : #include "cell.hxx" // fuer Formel-Preview
82 : : #include "compiler.hxx" // fuer Formel-Preview
83 : : #include "editable.hxx"
84 : : #include "funcdesc.hxx"
85 : : #include "markdata.hxx"
86 : :
87 : : #define _INPUTHDL_CXX
88 : : #include "inputhdl.hxx"
89 : :
90 : : // max. Ranges im RangeFinder
91 : : #define RANGEFIND_MAX 32
92 : :
93 : : using namespace formula;
94 : :
95 : : // STATIC DATA -----------------------------------------------------------
96 : :
97 : : bool ScInputHandler::bOptLoaded = false; // App-Optionen ausgewertet
98 : : bool ScInputHandler::bAutoComplete = false; // wird in KeyInput gesetzt
99 : :
100 : : extern sal_uInt16 nEditAdjust; //! Member an ViewData
101 : :
102 : : namespace {
103 : :
104 : : // delimiters (in addition to ScEditUtil) needed for range finder:
105 : : // only characters that are allowed in formulas next to references
106 : : // and the quotation mark (so string constants can be skipped)
107 : : const sal_Char pMinDelimiters[] = " !\"";
108 : :
109 : 0 : sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc)
110 : : {
111 [ # # ]: 0 : ScCompiler aComp(pDoc, ScAddress());
112 [ # # ][ # # ]: 0 : aComp.SetGrammar(pDoc->GetGrammar());
113 [ # # ][ # # ]: 0 : return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR);
114 : : }
115 : :
116 : 0 : ScTypedCaseStrSet::const_iterator findText(
117 : : const ScTypedCaseStrSet& rDataSet, ScTypedCaseStrSet::const_iterator itPos,
118 : : const rtl::OUString& rStart, rtl::OUString& rResult, bool bBack)
119 : : {
120 [ # # ]: 0 : if (bBack) // rueckwaerts
121 : : {
122 : 0 : ScTypedCaseStrSet::const_reverse_iterator it = rDataSet.rbegin(), itEnd = rDataSet.rend();
123 [ # # ]: 0 : if (itPos != rDataSet.end())
124 : : {
125 [ # # ]: 0 : size_t nPos = std::distance(rDataSet.begin(), itPos);
126 : 0 : size_t nRPos = rDataSet.size() - 1 - nPos;
127 [ # # ]: 0 : std::advance(it, nRPos);
128 [ # # ]: 0 : ++it;
129 : : }
130 : :
131 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
132 : : {
133 [ # # ]: 0 : const ScTypedStrData& rData = *it;
134 [ # # ][ # # ]: 0 : if (rData.GetStringType() == ScTypedStrData::Value)
135 : : // skip values.
136 : 0 : continue;
137 : :
138 [ # # ][ # # ]: 0 : if (!ScGlobal::GetpTransliteration()->isMatch(rStart, rData.GetString()))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
139 : : // not a match.
140 : 0 : continue;
141 : :
142 [ # # ]: 0 : rResult = rData.GetString();
143 [ # # ]: 0 : return (++it).base(); // convert the reverse iterator back to iterator.
144 : : }
145 : : }
146 : : else // vorwaerts
147 : : {
148 : 0 : ScTypedCaseStrSet::const_iterator it = rDataSet.begin(), itEnd = rDataSet.end();
149 [ # # ]: 0 : if (itPos != rDataSet.end())
150 : : {
151 : 0 : it = itPos;
152 : 0 : ++it;
153 : : }
154 : :
155 [ # # ]: 0 : for (; it != itEnd; ++it)
156 : : {
157 : 0 : const ScTypedStrData& rData = *it;
158 [ # # ][ # # ]: 0 : if (rData.GetStringType() == ScTypedStrData::Value)
159 : : // skip values.
160 : 0 : continue;
161 : :
162 [ # # ][ # # ]: 0 : if (!ScGlobal::GetpTransliteration()->isMatch(rStart, rData.GetString()))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
163 : : // not a match.
164 : 0 : continue;
165 : :
166 [ # # ]: 0 : rResult = rData.GetString();
167 : 0 : return it;
168 : : }
169 : : }
170 : :
171 : 0 : return rDataSet.end(); // no matching text found.
172 : : }
173 : :
174 : 0 : rtl::OUString getExactMatch(const ScTypedCaseStrSet& rDataSet, const rtl::OUString& rString)
175 : : {
176 : 0 : ScTypedCaseStrSet::const_iterator it = rDataSet.begin(), itEnd = rDataSet.end();
177 [ # # ]: 0 : for (; it != itEnd; ++it)
178 : : {
179 : 0 : const ScTypedStrData& rData = *it;
180 [ # # ][ # # ]: 0 : if (rData.GetStringType() == ScTypedStrData::Value)
181 : 0 : continue;
182 : :
183 [ # # ][ # # ]: 0 : if (!ScGlobal::GetpTransliteration()->isEqual(rData.GetString(), rString))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
184 : 0 : continue;
185 : :
186 [ # # ]: 0 : return rData.GetString();
187 : : }
188 : 0 : return rString;
189 : : }
190 : :
191 : 547 : void removeChars(rtl::OUString& rStr, sal_Unicode c)
192 : : {
193 [ + - ]: 547 : rtl::OUStringBuffer aBuf(rStr);
194 [ + + ]: 1147 : for (sal_Int32 i = 0, n = aBuf.getLength(); i < n; ++i)
195 : : {
196 [ - + ]: 600 : if (aBuf[i] == c)
197 : 0 : aBuf[i] = sal_Unicode(' ');
198 : : }
199 [ + - ]: 547 : rStr = aBuf.makeStringAndClear();
200 : 547 : }
201 : :
202 : : }
203 : :
204 : 0 : void ScInputHandler::InitRangeFinder( const String& rFormula )
205 : : {
206 [ # # ]: 0 : DeleteRangeFinder();
207 : 0 : ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
208 : 0 : ScDocument* pDoc = pDocSh->GetDocument();
209 [ # # ]: 0 : const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDoc);
210 : :
211 [ # # ][ # # ]: 0 : if ( !pActiveViewSh || !SC_MOD()->GetInputOptions().GetRangeFinder() )
[ # # ][ # # ]
[ # # ]
212 : 0 : return;
213 : :
214 : : String aDelimiters = ScEditUtil::ModifyDelimiters(
215 [ # # ][ # # ]: 0 : rtl::OUString::createFromAscii( pMinDelimiters ) );
[ # # ]
216 : :
217 [ # # ]: 0 : xub_StrLen nColon = aDelimiters.Search(':');
218 [ # # ]: 0 : if ( nColon != STRING_NOTFOUND )
219 [ # # ]: 0 : aDelimiters.Erase( nColon, 1 ); // Delimiter ohne Doppelpunkt
220 [ # # ]: 0 : xub_StrLen nDot = aDelimiters.Search(cSheetSep);
221 [ # # ]: 0 : if ( nDot != STRING_NOTFOUND )
222 [ # # ]: 0 : aDelimiters.Erase( nDot, 1 ); // Delimiter ohne Punkt
223 : :
224 : 0 : const sal_Unicode* pChar = rFormula.GetBuffer();
225 : 0 : xub_StrLen nLen = rFormula.Len();
226 : 0 : xub_StrLen nPos = 0;
227 : 0 : xub_StrLen nStart = 0;
228 : 0 : sal_uInt16 nCount = 0;
229 : 0 : ScRange aRange;
230 [ # # ][ # # ]: 0 : while ( nPos < nLen && nCount < RANGEFIND_MAX )
[ # # ]
231 : : {
232 : : // Trenner ueberlesen
233 [ # # ][ # # ]: 0 : while ( nPos<nLen && ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
[ # # ][ # # ]
234 : : {
235 [ # # ]: 0 : if ( pChar[nPos] == '"' ) // String
236 : : {
237 : 0 : ++nPos;
238 [ # # ][ # # ]: 0 : while (nPos<nLen && pChar[nPos] != '"') // bis zum Ende ueberlesen
[ # # ]
239 : 0 : ++nPos;
240 : : }
241 : 0 : ++nPos; // Trennzeichen oder schliessender Quote
242 : : }
243 : :
244 : : // Text zwischen Trennern
245 : 0 : nStart = nPos;
246 : : handle_r1c1:
247 [ # # ][ # # ]: 0 : while ( nPos<nLen && !ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
[ # # ][ # # ]
248 : 0 : ++nPos;
249 : :
250 : : // for R1C1 '-' in R[-]... or C[-]... are not delimiters
251 : : // Nothing heroic here to ensure that there are '[]' around a negative
252 : : // integer. we need to clean up this code.
253 [ # # ][ # # ]: 0 : if( nPos < nLen && nPos > 0 &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
254 : 0 : '-' == pChar[nPos] && '[' == pChar[nPos-1] &&
255 : : NULL != pDoc &&
256 [ # # ]: 0 : formula::FormulaGrammar::CONV_XL_R1C1 == pDoc->GetAddressConvention() )
257 : : {
258 : 0 : nPos++;
259 : 0 : goto handle_r1c1;
260 : : }
261 : :
262 [ # # ]: 0 : if ( nPos > nStart )
263 : : {
264 [ # # ]: 0 : String aTest = rFormula.Copy( nStart, nPos-nStart );
265 [ # # ]: 0 : const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
266 [ # # ]: 0 : sal_uInt16 nFlags = aRange.ParseAny( aTest, pDoc, aAddrDetails );
267 [ # # ]: 0 : if ( nFlags & SCA_VALID )
268 : : {
269 : : // Tabelle setzen, wenn nicht angegeben
270 [ # # ]: 0 : if ( (nFlags & SCA_TAB_3D) == 0 )
271 : 0 : aRange.aStart.SetTab( pActiveViewSh->GetViewData()->GetTabNo() );
272 [ # # ]: 0 : if ( (nFlags & SCA_TAB2_3D) == 0 )
273 : 0 : aRange.aEnd.SetTab( aRange.aStart.Tab() );
274 : :
275 [ # # ]: 0 : if ( ( nFlags & ( SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2 ) ) == 0 )
276 : : {
277 : : // #i73766# if a single ref was parsed, set the same "abs" flags for ref2,
278 : : // so Format doesn't output a double ref because of different flags.
279 : 0 : sal_uInt16 nAbsFlags = nFlags & ( SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE );
280 : 0 : nFlags |= nAbsFlags << 4;
281 : : }
282 : :
283 [ # # ]: 0 : if (!nCount)
284 : : {
285 [ # # ]: 0 : pEngine->SetUpdateMode( false );
286 [ # # ][ # # ]: 0 : pRangeFindList = new ScRangeFindList( pDocSh->GetTitle() );
[ # # ][ # # ]
287 : : }
288 : :
289 [ # # ]: 0 : pRangeFindList->Insert( ScRangeFindData( aRange, nFlags, nStart, nPos ) );
290 : :
291 : 0 : ESelection aSel( 0, nStart, 0, nPos );
292 [ # # ][ # # ]: 0 : SfxItemSet aSet( pEngine->GetEmptyItemSet() );
293 : : aSet.Put( SvxColorItem( Color( ScRangeFindList::GetColorName( nCount ) ),
294 [ # # ][ # # ]: 0 : EE_CHAR_COLOR ) );
[ # # ][ # # ]
295 [ # # ]: 0 : pEngine->QuickSetAttribs( aSet, aSel );
296 [ # # ]: 0 : ++nCount;
297 [ # # ]: 0 : }
298 : : }
299 : :
300 : : // letzten Trenner nicht ueberlesen, koennte ja ein Quote sein (?)
301 : : }
302 : :
303 [ # # ]: 0 : if (nCount)
304 : : {
305 [ # # ]: 0 : pEngine->SetUpdateMode( true );
306 : :
307 [ # # ][ # # ]: 0 : pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) );
[ # # ]
308 [ # # ]: 0 : }
309 : : }
310 : :
311 : 0 : void lcl_Replace( EditView* pView, const String& rNewStr, const ESelection& rOldSel )
312 : : {
313 [ # # ]: 0 : if ( pView )
314 : : {
315 [ # # ]: 0 : ESelection aOldSel = pView->GetSelection();
316 [ # # ]: 0 : if (aOldSel.HasRange())
317 : : pView->SetSelection( ESelection( aOldSel.nEndPara, aOldSel.nEndPos,
318 [ # # ]: 0 : aOldSel.nEndPara, aOldSel.nEndPos ) );
319 : :
320 [ # # ]: 0 : EditEngine* pEngine = pView->GetEditEngine();
321 [ # # ]: 0 : pEngine->QuickInsertText( rNewStr, rOldSel );
322 : :
323 : : // Dummy-InsertText fuer Update und Paint
324 : : // dafuer muss oben die Selektion aufgehoben werden (vor QuickInsertText)
325 [ # # ][ # # ]: 0 : pView->InsertText( EMPTY_STRING, false );
326 : :
327 [ # # ]: 0 : xub_StrLen nLen = pEngine->GetTextLen(0);
328 : 0 : ESelection aSel( 0, nLen, 0, nLen );
329 [ # # ]: 0 : pView->SetSelection( aSel ); // Cursor ans Ende
330 : : }
331 : 0 : }
332 : :
333 : 0 : void ScInputHandler::UpdateRange( sal_uInt16 nIndex, const ScRange& rNew )
334 : : {
335 [ # # ]: 0 : ScTabViewShell* pDocView = pRefViewSh ? pRefViewSh : pActiveViewSh;
336 [ # # ][ # # ]: 0 : if ( pDocView && pRangeFindList && nIndex < pRangeFindList->Count() )
[ # # ][ # # ]
337 : : {
338 [ # # ]: 0 : ScRangeFindData* pData = pRangeFindList->GetObject( nIndex );
339 : 0 : xub_StrLen nOldStart = pData->nSelStart;
340 : 0 : xub_StrLen nOldEnd = pData->nSelEnd;
341 : :
342 : 0 : ScRange aJustified = rNew;
343 [ # # ]: 0 : aJustified.Justify(); // Ref in der Formel immer richtigherum anzeigen
344 [ # # ]: 0 : String aNewStr;
345 [ # # ]: 0 : ScDocument* pDoc = pDocView->GetViewData()->GetDocument();
346 [ # # ]: 0 : const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
347 [ # # ]: 0 : aJustified.Format( aNewStr, pData->nFlags, pDoc, aAddrDetails );
348 : 0 : ESelection aOldSel( 0, nOldStart, 0, nOldEnd );
349 : :
350 [ # # ]: 0 : DataChanging();
351 : :
352 [ # # ]: 0 : lcl_Replace( pTopView, aNewStr, aOldSel );
353 [ # # ]: 0 : lcl_Replace( pTableView, aNewStr, aOldSel );
354 : :
355 : 0 : bInRangeUpdate = true;
356 [ # # ]: 0 : DataChanged();
357 : 0 : bInRangeUpdate = false;
358 : :
359 : 0 : long nDiff = aNewStr.Len() - (long)(nOldEnd-nOldStart);
360 : :
361 : 0 : pData->aRef = rNew;
362 : 0 : pData->nSelEnd = (xub_StrLen)(pData->nSelEnd + nDiff);
363 : :
364 : 0 : sal_uInt16 nCount = (sal_uInt16) pRangeFindList->Count();
365 [ # # ]: 0 : for (sal_uInt16 i=nIndex+1; i<nCount; i++)
366 : : {
367 [ # # ]: 0 : ScRangeFindData* pNext = pRangeFindList->GetObject( i );
368 : 0 : pNext->nSelStart = (xub_StrLen)(pNext->nSelStart + nDiff);
369 : 0 : pNext->nSelEnd = (xub_StrLen)(pNext->nSelEnd + nDiff);
370 [ # # ]: 0 : }
371 : : }
372 : : else
373 : : {
374 : : OSL_FAIL("UpdateRange: da fehlt was");
375 : : }
376 : 0 : }
377 : :
378 : 519 : void ScInputHandler::DeleteRangeFinder()
379 : : {
380 [ - + ]: 519 : ScTabViewShell* pPaintView = pRefViewSh ? pRefViewSh : pActiveViewSh;
381 [ - + ][ # # ]: 519 : if ( pRangeFindList && pPaintView )
382 : : {
383 : 0 : ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
384 : 0 : pRangeFindList->SetHidden(true);
385 [ # # ]: 0 : pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) ); // wegnehmen
386 [ # # ]: 0 : DELETEZ(pRangeFindList);
387 : : }
388 : 519 : }
389 : :
390 : : //==================================================================
391 : :
392 : 519 : inline String GetEditText(EditEngine* pEng)
393 : : {
394 : 519 : return ScEditUtil::GetSpaceDelimitedString(*pEng);
395 : : }
396 : :
397 : 547 : void lcl_RemoveTabs(rtl::OUString& rStr)
398 : : {
399 : 547 : removeChars(rStr, sal_Unicode('\t'));
400 : 547 : }
401 : :
402 : 0 : void lcl_RemoveLineEnd(rtl::OUString& rStr)
403 : : {
404 : 0 : rStr = convertLineEnd(rStr, LINEEND_LF);
405 : 0 : removeChars(rStr, sal_Unicode('\n'));
406 : 0 : }
407 : :
408 : 0 : xub_StrLen lcl_MatchParenthesis( const String& rStr, xub_StrLen nPos )
409 : : {
410 : : int nDir;
411 : 0 : sal_Unicode c1, c2 = 0;
412 : 0 : c1 = rStr.GetChar( nPos );
413 [ # # # # : 0 : switch ( c1 )
# # # #
# ]
414 : : {
415 : : case '(' :
416 : 0 : c2 = ')';
417 : 0 : nDir = 1;
418 : 0 : break;
419 : : case ')' :
420 : 0 : c2 = '(';
421 : 0 : nDir = -1;
422 : 0 : break;
423 : : case '<' :
424 : 0 : c2 = '>';
425 : 0 : nDir = 1;
426 : 0 : break;
427 : : case '>' :
428 : 0 : c2 = '<';
429 : 0 : nDir = -1;
430 : 0 : break;
431 : : case '{' :
432 : 0 : c2 = '}';
433 : 0 : nDir = 1;
434 : 0 : break;
435 : : case '}' :
436 : 0 : c2 = '{';
437 : 0 : nDir = -1;
438 : 0 : break;
439 : : case '[' :
440 : 0 : c2 = ']';
441 : 0 : nDir = 1;
442 : 0 : break;
443 : : case ']' :
444 : 0 : c2 = '[';
445 : 0 : nDir = -1;
446 : 0 : break;
447 : : default:
448 : 0 : nDir = 0;
449 : : }
450 [ # # ]: 0 : if ( !nDir )
451 : 0 : return STRING_NOTFOUND;
452 : 0 : xub_StrLen nLen = rStr.Len();
453 : 0 : const sal_Unicode* p0 = rStr.GetBuffer();
454 : : register const sal_Unicode* p;
455 : : const sal_Unicode* p1;
456 : 0 : sal_uInt16 nQuotes = 0;
457 [ # # ]: 0 : if ( nPos < nLen / 2 )
458 : : {
459 : 0 : p = p0;
460 : 0 : p1 = p0 + nPos;
461 : : }
462 : : else
463 : : {
464 : 0 : p = p0 + nPos;
465 : 0 : p1 = p0 + nLen;
466 : : }
467 [ # # ]: 0 : while ( p < p1 )
468 : : {
469 [ # # ]: 0 : if ( *p++ == '\"' )
470 : 0 : nQuotes++;
471 : : }
472 : : // Odd number of quotes that we find ourselves in a string
473 : 0 : bool bLookInString = ((nQuotes % 2) != 0);
474 : 0 : bool bInString = bLookInString;
475 : 0 : p = p0 + nPos;
476 [ # # ]: 0 : p1 = (nDir < 0 ? p0 : p0 + nLen) ;
477 : 0 : sal_uInt16 nLevel = 1;
478 [ # # ][ # # ]: 0 : while ( p != p1 && nLevel )
[ # # ]
479 : : {
480 : 0 : p += nDir;
481 [ # # ]: 0 : if ( *p == '\"' )
482 : : {
483 : 0 : bInString = !bInString;
484 [ # # ][ # # ]: 0 : if ( bLookInString && !bInString )
485 : 0 : p = p1; //That's it then
486 : : }
487 [ # # ]: 0 : else if ( bInString == bLookInString )
488 : : {
489 [ # # ]: 0 : if ( *p == c1 )
490 : 0 : nLevel++;
491 [ # # ]: 0 : else if ( *p == c2 )
492 : 0 : nLevel--;
493 : : }
494 : : }
495 [ # # ]: 0 : if ( nLevel )
496 : 0 : return STRING_NOTFOUND;
497 : 0 : return (xub_StrLen) (p - p0);
498 : : }
499 : :
500 : : //==================================================================
501 : :
502 : 229 : ScInputHandler::ScInputHandler()
503 : : : pInputWin( NULL ),
504 : : pEngine( NULL ),
505 : : pTableView( NULL ),
506 : : pTopView( NULL ),
507 : : pColumnData( NULL ),
508 : : pFormulaData( NULL ),
509 : : pFormulaDataPara( NULL ),
510 : : pTipVisibleParent( NULL ),
511 : : nTipVisible( 0 ),
512 : : pTipVisibleSecParent( NULL ),
513 : : nTipVisibleSec( 0 ),
514 : : nFormSelStart( 0 ),
515 : : nFormSelEnd( 0 ),
516 : : nAutoPar( 0 ),
517 : : eMode( SC_INPUT_NONE ),
518 : : bUseTab( false ),
519 : : bTextValid( true ),
520 : : bModified( false ),
521 : : bSelIsRef( false ),
522 : : bFormulaMode( false ),
523 : : bInRangeUpdate( false ),
524 : : bParenthesisShown( false ),
525 : : bCreatingFuncView( false ),
526 : : bInEnterHandler( false ),
527 : : bCommandErrorShown( false ),
528 : : bInOwnChange( false ),
529 : : bProtected( false ),
530 : : bCellHasPercentFormat( false ),
531 : : bLastIsSymbol( false ),
532 : : nValidation( 0 ),
533 : : eAttrAdjust( SVX_HOR_JUSTIFY_STANDARD ),
534 : : aScaleX( 1,1 ),
535 : : aScaleY( 1,1 ),
536 : : pRefViewSh( NULL ),
537 : : pLastPattern( NULL ),
538 : : pEditDefaults( NULL ),
539 : : pLastState( NULL ),
540 : : pDelayTimer( NULL ),
541 [ + - ][ + - ]: 229 : pRangeFindList( NULL )
542 : : {
543 : : // The InputHandler is constructed with the view, so SfxViewShell::Current
544 : : // doesn't have the right view yet. pActiveViewSh is updated in NotifyChange.
545 : 229 : pActiveViewSh = NULL;
546 : :
547 : : // Bindings (nur noch fuer Invalidate benutzt) werden bei Bedarf aktuell geholt
548 : 229 : }
549 : :
550 : 225 : ScInputHandler::~ScInputHandler()
551 : : {
552 : : // Wenn dies der Applikations-InputHandler ist, wird der dtor erst nach SfxApplication::Main
553 : : // gerufen, darf sich also auf keine Sfx-Funktionen mehr verlassen
554 : :
555 [ + - ][ + - ]: 225 : if ( !SFX_APP()->IsDowning() ) // inplace
[ + - ]
556 [ + - ]: 225 : EnterHandler(); // Eingabe noch abschliessen
557 : :
558 [ + - ][ + - ]: 225 : if (SC_MOD()->GetRefInputHdl()==this)
[ - + ]
559 [ # # ][ # # ]: 0 : SC_MOD()->SetRefInputHdl(NULL);
560 : :
561 [ - + ][ # # ]: 225 : if ( pInputWin && pInputWin->GetInputHandler() == this )
[ - + ]
562 [ # # ]: 0 : pInputWin->SetInputHandler( NULL );
563 : :
564 [ - + ][ # # ]: 225 : delete pRangeFindList;
565 [ + - ][ + - ]: 225 : delete pEditDefaults;
566 [ + - ][ + - ]: 225 : delete pEngine;
567 [ + + ][ + - ]: 225 : delete pLastState;
568 [ + + ][ + - ]: 225 : delete pDelayTimer;
569 [ - + ]: 225 : delete pColumnData;
570 [ - + ]: 225 : delete pFormulaData;
571 [ - + ]: 225 : delete pFormulaDataPara;
572 [ - + ]: 450 : }
573 : :
574 : 990 : void ScInputHandler::SetRefScale( const Fraction& rX, const Fraction& rY )
575 : : {
576 [ + + ][ - + ]: 990 : if ( rX != aScaleX || rY != aScaleY )
[ + + ]
577 : : {
578 : 26 : aScaleX = rX;
579 : 26 : aScaleY = rY;
580 [ - + ]: 26 : if (pEngine)
581 : : {
582 [ # # ]: 0 : MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
583 [ # # ][ # # ]: 0 : pEngine->SetRefMapMode( aMode );
584 : : }
585 : : }
586 : 990 : }
587 : :
588 : 229 : void ScInputHandler::UpdateRefDevice()
589 : : {
590 [ + - ]: 229 : if (!pEngine)
591 : 229 : return;
592 : :
593 [ + - ][ + - ]: 229 : bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
594 [ + - ][ + - ]: 229 : bool bInPlace = pActiveViewSh && pActiveViewSh->GetViewFrame()->GetFrame().IsInPlace();
[ - + ][ + - ]
595 [ + - ]: 229 : sal_uLong nCtrl = pEngine->GetControlWord();
596 [ + + ][ - + ]: 229 : if ( bTextWysiwyg || bInPlace )
597 : 26 : nCtrl |= EE_CNTRL_FORMAT100; // EditEngine default: always format for 100%
598 : : else
599 : 203 : nCtrl &= ~EE_CNTRL_FORMAT100; // when formatting for screen, use the actual MapMode
600 [ + - ]: 229 : pEngine->SetControlWord( nCtrl );
601 [ + + ][ + - ]: 229 : if ( bTextWysiwyg && pActiveViewSh )
602 [ + - ][ + - ]: 26 : pEngine->SetRefDevice( pActiveViewSh->GetViewData()->GetDocument()->GetPrinter() );
[ + - ]
603 : : else
604 [ + - ]: 203 : pEngine->SetRefDevice( NULL );
605 : :
606 [ + - ]: 229 : MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
607 [ + - ]: 229 : pEngine->SetRefMapMode( aMode );
608 : :
609 : : // SetRefDevice(NULL) uses VirtualDevice, SetRefMapMode forces creation of a local VDev,
610 : : // so the DigitLanguage can be safely modified (might use an own VDev instead of NULL).
611 [ + + ][ - + ]: 229 : if ( !( bTextWysiwyg && pActiveViewSh ) )
612 : : {
613 [ + - ][ + - ]: 203 : pEngine->GetRefDevice()->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
[ + - ][ + - ]
614 [ + - ]: 229 : }
615 : : }
616 : :
617 : 1384 : void ScInputHandler::ImplCreateEditEngine()
618 : : {
619 [ + + ]: 1384 : if ( !pEngine )
620 : : {
621 [ + - ]: 229 : if ( pActiveViewSh )
622 : : {
623 : 229 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
624 [ + - ]: 229 : pEngine = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
625 : : }
626 : : else
627 [ # # ]: 0 : pEngine = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
628 [ + - ][ + - ]: 229 : pEngine->SetWordDelimiters( ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) );
[ + - ]
629 : 229 : UpdateRefDevice(); // also sets MapMode
630 [ + - ]: 229 : pEngine->SetPaperSize( Size( 1000000, 1000000 ) );
631 [ + - ]: 229 : pEditDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
632 : :
633 : 229 : pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_AUTOCORRECT );
634 [ + - ]: 229 : pEngine->SetModifyHdl( LINK( this, ScInputHandler, ModifyHdl ) );
635 : : }
636 : 1384 : }
637 : :
638 : 0 : void ScInputHandler::UpdateAutoCorrFlag()
639 : : {
640 : 0 : sal_uLong nCntrl = pEngine->GetControlWord();
641 : 0 : sal_uLong nOld = nCntrl;
642 : :
643 : : // don't use pLastPattern here (may be invalid because of AutoStyle)
644 : :
645 [ # # ][ # # ]: 0 : bool bDisable = bLastIsSymbol || bFormulaMode;
646 [ # # ]: 0 : if ( bDisable )
647 : 0 : nCntrl &= ~EE_CNTRL_AUTOCORRECT;
648 : : else
649 : 0 : nCntrl |= EE_CNTRL_AUTOCORRECT;
650 : :
651 [ # # ]: 0 : if ( nCntrl != nOld )
652 : 0 : pEngine->SetControlWord(nCntrl);
653 : 0 : }
654 : :
655 : 0 : void ScInputHandler::UpdateSpellSettings( bool bFromStartTab )
656 : : {
657 [ # # ]: 0 : if ( pActiveViewSh )
658 : : {
659 : 0 : ScViewData* pViewData = pActiveViewSh->GetViewData();
660 : 0 : bool bOnlineSpell = pViewData->GetDocument()->GetDocOptions().IsAutoSpell();
661 : :
662 : : // SetDefaultLanguage is independent of the language attributes,
663 : : // ScGlobal::GetEditDefaultLanguage is always used.
664 : : // It must be set every time in case the office language was changed.
665 : :
666 : 0 : pEngine->SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
667 : :
668 : : // if called for changed options, update flags only if already editing
669 : : // if called from StartTable, always update flags
670 : :
671 [ # # ][ # # ]: 0 : if ( bFromStartTab || eMode != SC_INPUT_NONE )
672 : : {
673 : 0 : sal_uLong nCntrl = pEngine->GetControlWord();
674 : 0 : sal_uLong nOld = nCntrl;
675 [ # # ]: 0 : if( bOnlineSpell )
676 : 0 : nCntrl |= EE_CNTRL_ONLINESPELLING;
677 : : else
678 : 0 : nCntrl &= ~EE_CNTRL_ONLINESPELLING;
679 : : // kein AutoCorrect auf Symbol-Font (EditEngine wertet Default nicht aus)
680 [ # # ][ # # ]: 0 : if ( pLastPattern && pLastPattern->IsSymbolFont() )
[ # # ]
681 : 0 : nCntrl &= ~EE_CNTRL_AUTOCORRECT;
682 : : else
683 : 0 : nCntrl |= EE_CNTRL_AUTOCORRECT;
684 [ # # ]: 0 : if ( nCntrl != nOld )
685 : 0 : pEngine->SetControlWord(nCntrl);
686 : :
687 : 0 : ScDocument* pDoc = pViewData->GetDocument();
688 : 0 : pDoc->ApplyAsianEditSettings( *pEngine );
689 : : pEngine->SetDefaultHorizontalTextDirection(
690 : 0 : (EEHorizontalTextDirection)pDoc->GetEditTextDirection( pViewData->GetTabNo() ) );
691 : 0 : pEngine->SetFirstWordCapitalization( false );
692 : : }
693 : :
694 : : // language is set separately, so the speller is needed only if online
695 : : // spelling is active
696 : :
697 [ # # ]: 0 : if ( bOnlineSpell ) {
698 [ # # ]: 0 : com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
699 [ # # ]: 0 : pEngine->SetSpeller( xXSpellChecker1 );
700 : : }
701 : :
702 [ # # ][ # # ]: 0 : bool bHyphen = pLastPattern && ((const SfxBoolItem&)pLastPattern->GetItem(ATTR_HYPHENATE)).GetValue();
703 [ # # ]: 0 : if ( bHyphen ) {
704 [ # # ]: 0 : com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
705 [ # # ]: 0 : pEngine->SetHyphenator( xXHyphenator );
706 : : }
707 : : }
708 : 0 : }
709 : :
710 : : //
711 : : // Funktionen/Bereichsnamen etc. als Tip-Hilfe
712 : : //
713 : :
714 : : // die anderen Typen sind in ScDocument::GetFormulaEntries festgelegt
715 : :
716 : 0 : void ScInputHandler::GetFormulaData()
717 : : {
718 [ # # ]: 0 : if ( pActiveViewSh )
719 : : {
720 : 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
721 : :
722 [ # # ]: 0 : if ( pFormulaData )
723 : 0 : pFormulaData->clear();
724 : : else
725 : : {
726 [ # # ]: 0 : pFormulaData = new ScTypedCaseStrSet;
727 : 0 : miAutoPosFormula = pFormulaData->end();
728 : : }
729 : :
730 [ # # ]: 0 : if( pFormulaDataPara )
731 : 0 : pFormulaDataPara->clear();
732 : : else
733 [ # # ]: 0 : pFormulaDataPara = new ScTypedCaseStrSet;
734 : :
735 : : // MRU-Funktionen aus dem Funktions-Autopiloten
736 : : // wie in ScPosWnd::FillFunctions (inputwin.cxx)
737 : :
738 : 0 : const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
739 : 0 : sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount();
740 : 0 : const sal_uInt16* pMRUList = rOpt.GetLRUFuncList();
741 : 0 : const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
742 : 0 : sal_uLong nListCount = pFuncList->GetCount();
743 [ # # ]: 0 : if (pMRUList)
744 : : {
745 [ # # ]: 0 : for (sal_uInt16 i=0; i<nMRUCount; i++)
746 : : {
747 : 0 : sal_uInt16 nId = pMRUList[i];
748 [ # # ]: 0 : for (sal_uLong j=0; j<nListCount; j++)
749 : : {
750 : 0 : const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
751 [ # # ][ # # ]: 0 : if ( pDesc->nFIndex == nId && pDesc->pFuncName )
752 : : {
753 [ # # ]: 0 : String aEntry = *pDesc->pFuncName;
754 [ # # ]: 0 : aEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
755 [ # # ][ # # ]: 0 : pFormulaData->insert(ScTypedStrData(aEntry, 0.0, ScTypedStrData::Standard));
[ # # ]
756 [ # # ]: 0 : break; // nicht weitersuchen
757 : : }
758 : : }
759 : : }
760 : : }
761 [ # # ]: 0 : for(sal_uLong i=0;i<nListCount;i++)
762 : : {
763 : 0 : const ScFuncDesc* pDesc = pFuncList->GetFunction( i );
764 [ # # ]: 0 : if ( pDesc->pFuncName )
765 : : {
766 [ # # ]: 0 : pDesc->initArgumentInfo();
767 [ # # ][ # # ]: 0 : String aEntry = pDesc->getSignature();
768 [ # # ][ # # ]: 0 : pFormulaDataPara->insert(ScTypedStrData(aEntry, 0.0, ScTypedStrData::Standard));
[ # # ][ # # ]
769 : : }
770 : : }
771 : 0 : pDoc->GetFormulaEntries( *pFormulaData );
772 : 0 : pDoc->GetFormulaEntries( *pFormulaDataPara );
773 : : }
774 : 0 : }
775 : :
776 : 0 : IMPL_LINK( ScInputHandler, ShowHideTipVisibleParentListener, VclWindowEvent*, pEvent )
777 : : {
778 [ # # ][ # # ]: 0 : if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
[ # # ]
779 : 0 : HideTip();
780 : 0 : return 0;
781 : : }
782 : :
783 : 0 : IMPL_LINK( ScInputHandler, ShowHideTipVisibleSecParentListener, VclWindowEvent*, pEvent )
784 : : {
785 [ # # ][ # # ]: 0 : if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
[ # # ]
786 : 0 : HideTipBelow();
787 : 0 : return 0;
788 : : }
789 : :
790 : 1384 : void ScInputHandler::HideTip()
791 : : {
792 [ - + ]: 1384 : if ( nTipVisible )
793 : : {
794 [ # # ]: 0 : if (pTipVisibleParent)
795 [ # # ]: 0 : pTipVisibleParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
796 : 0 : Help::HideTip( nTipVisible );
797 : 0 : nTipVisible = 0;
798 : 0 : pTipVisibleParent = NULL;
799 : : }
800 : 1384 : aManualTip = rtl::OUString();
801 : 1384 : }
802 : 1384 : void ScInputHandler::HideTipBelow()
803 : : {
804 [ - + ]: 1384 : if ( nTipVisibleSec )
805 : : {
806 [ # # ]: 0 : if (pTipVisibleSecParent)
807 [ # # ]: 0 : pTipVisibleSecParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
808 : 0 : Help::HideTip( nTipVisibleSec );
809 : 0 : nTipVisibleSec = 0;
810 : 0 : pTipVisibleSecParent = NULL;
811 : : }
812 : 1384 : aManualTip = rtl::OUString();
813 : 1384 : }
814 : :
815 : 0 : void ScInputHandler::ShowTipCursor()
816 : : {
817 : 0 : HideTip();
818 : 0 : HideTipBelow();
819 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
820 : 0 : ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
821 : 0 : const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
822 : 0 : const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
823 : :
824 [ # # ][ # # ]: 0 : if ( bFormulaMode && pActiveView && pFormulaDataPara && pEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
[ # # ]
825 : : {
826 [ # # ]: 0 : String aFormula = pEngine->GetText( (sal_uInt16) 0 );
827 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
828 : 0 : aSel.Adjust();
829 [ # # ]: 0 : if( aSel.nEndPos )
830 : : {
831 [ # # ]: 0 : if ( aFormula.Len() < aSel.nEndPos )
832 : 0 : return;
833 : 0 : xub_StrLen nPos = aSel.nEndPos;
834 [ # # ]: 0 : String aSelText = aFormula.Copy( 0, nPos );
835 : 0 : xub_StrLen nNextFStart = 0;
836 : 0 : xub_StrLen nNextFEnd = 0;
837 : 0 : xub_StrLen nArgPos = 0;
838 : : const IFunctionDescription* ppFDesc;
839 [ # # ]: 0 : ::std::vector< ::rtl::OUString> aArgs;
840 : : sal_uInt16 nArgs;
841 : 0 : bool bFound = false;
842 [ # # ][ # # ]: 0 : FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());
843 : :
844 [ # # ]: 0 : while( !bFound )
845 : : {
846 [ # # ]: 0 : aSelText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
847 : 0 : xub_StrLen nLeftParentPos = lcl_MatchParenthesis( aSelText, aSelText.Len()-1 );
848 [ # # ]: 0 : if( nLeftParentPos != STRING_NOTFOUND )
849 : : {
850 [ # # ]: 0 : sal_Unicode c = ( nLeftParentPos > 0 ) ? aSelText.GetChar( nLeftParentPos-1 ) : 0;
851 [ # # ][ # # ]: 0 : if( !(comphelper::string::isalphaAscii(c)) )
852 : 0 : continue;
853 [ # # ]: 0 : nNextFStart = aHelper.GetFunctionStart( aSelText, nLeftParentPos, true);
854 [ # # ][ # # ]: 0 : if( aHelper.GetNextFunc( aSelText, false, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
855 : : {
856 [ # # ][ # # ]: 0 : if( !ppFDesc->getFunctionName().isEmpty() )
857 : : {
858 [ # # ]: 0 : nArgPos = aHelper.GetArgStart( aSelText, nNextFStart, 0 );
859 [ # # ]: 0 : nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount());
860 : :
861 : 0 : bool bFlag = false;
862 : 0 : rtl::OUString aNew;
863 : : ScTypedCaseStrSet::const_iterator it =
864 [ # # ][ # # ]: 0 : findText(*pFormulaDataPara, pFormulaDataPara->end(), ppFDesc->getFunctionName(), aNew, false);
865 [ # # ]: 0 : if (it != pFormulaDataPara->end())
866 : : {
867 : 0 : sal_uInt16 nActive = 0;
868 [ # # ]: 0 : for( sal_uInt16 i=0; i < nArgs; i++ )
869 : : {
870 : 0 : xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
871 [ # # ]: 0 : if( nArgPos <= aSelText.Len()-1 )
872 : : {
873 : 0 : nActive = i+1;
874 : 0 : bFlag = true;
875 : : }
876 : 0 : nArgPos+=nLength+1;
877 : : }
878 [ # # ]: 0 : if( bFlag )
879 : : {
880 [ # # ]: 0 : sal_Int32 nCountSemicolon = comphelper::string::getTokenCount(aNew, cSep) - 1;
881 [ # # ]: 0 : sal_Int32 nCountDot = comphelper::string::getTokenCount(aNew, cSheetSep) - 1;
882 : 0 : sal_Int32 nStartPosition = 0;
883 : 0 : sal_Int32 nEndPosition = 0;
884 : :
885 [ # # ]: 0 : if( !nCountSemicolon )
886 : : {
887 [ # # ]: 0 : for (sal_Int32 i = 0; i < aNew.getLength(); ++i)
888 : : {
889 : 0 : sal_Unicode cNext = aNew.getStr()[i];
890 [ # # ]: 0 : if( cNext == '(' )
891 : : {
892 : 0 : nStartPosition = i+1;
893 : : }
894 : : }
895 : : }
896 [ # # ]: 0 : else if( !nCountDot )
897 : : {
898 : 0 : sal_uInt16 nCount = 0;
899 [ # # ]: 0 : for (sal_Int32 i = 0; i < aNew.getLength(); ++i)
900 : : {
901 : 0 : sal_Unicode cNext = aNew.getStr()[i];
902 [ # # ]: 0 : if( cNext == '(' )
903 : : {
904 : 0 : nStartPosition = i+1;
905 : : }
906 [ # # ]: 0 : else if( cNext == cSep )
907 : : {
908 : 0 : nCount ++;
909 : 0 : nEndPosition = i;
910 [ # # ]: 0 : if( nCount == nActive )
911 : : {
912 : 0 : break;
913 : : }
914 : 0 : nStartPosition = nEndPosition+1;
915 : : }
916 : : }
917 : : }
918 : : else
919 : : {
920 : 0 : sal_uInt16 nCount = 0;
921 [ # # ]: 0 : for (sal_Int32 i = 0; i < aNew.getLength(); ++i)
922 : : {
923 : 0 : sal_Unicode cNext = aNew.getStr()[i];
924 [ # # ]: 0 : if( cNext == '(' )
925 : : {
926 : 0 : nStartPosition = i+1;
927 : : }
928 [ # # ]: 0 : else if( cNext == cSep )
929 : : {
930 : 0 : nCount ++;
931 : 0 : nEndPosition = i;
932 [ # # ]: 0 : if( nCount == nActive )
933 : : {
934 : 0 : break;
935 : : }
936 : 0 : nStartPosition = nEndPosition+1;
937 : : }
938 [ # # ]: 0 : else if( cNext == cSheetSep )
939 : : {
940 : 0 : continue;
941 : : }
942 : : }
943 : : }
944 : :
945 [ # # ]: 0 : if (nStartPosition > 0)
946 : : {
947 : 0 : rtl::OUStringBuffer aBuf;
948 [ # # ]: 0 : aBuf.append(aNew.copy(0, nStartPosition));
949 [ # # ]: 0 : aBuf.append(static_cast<sal_Unicode>(0x25BA));
950 [ # # ]: 0 : aBuf.append(aNew.copy(nStartPosition));
951 [ # # ]: 0 : aNew = aBuf.makeStringAndClear();
952 [ # # ][ # # ]: 0 : ShowTipBelow( aNew );
[ # # ]
953 : 0 : bFound = true;
954 : : }
955 : : }
956 : : else
957 : : {
958 [ # # ][ # # ]: 0 : ShowTipBelow( aNew );
[ # # ]
959 : 0 : bFound = true;
960 : : }
961 : 0 : }
962 : : }
963 : : }
964 : : }
965 : : else
966 : : {
967 : 0 : sal_uInt16 nPosition = 0;
968 [ # # ]: 0 : String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
969 [ # # ]: 0 : if( aText.GetChar( aSel.nEndPos-1 ) == '=' )
970 : : {
971 : : break;
972 : : }
973 : 0 : rtl::OUString aNew;
974 : 0 : nPosition = aText.Len()+1;
975 : : ScTypedCaseStrSet::const_iterator it =
976 [ # # ][ # # ]: 0 : findText(*pFormulaDataPara, pFormulaDataPara->end(), aText, aNew, false);
977 [ # # ]: 0 : if (it != pFormulaDataPara->end())
978 : : {
979 [ # # ]: 0 : if( aFormula.GetChar( nPosition ) =='(' )
980 : : {
981 [ # # ][ # # ]: 0 : ShowTipBelow( aNew );
[ # # ]
982 : 0 : bFound = true;
983 : : }
984 : : else
985 : : break;
986 : : }
987 : : else
988 : : {
989 : : break;
990 [ # # ][ # # ]: 0 : }
[ # # ]
991 : : }
992 [ # # ][ # # ]: 0 : }
993 [ # # ][ # # ]: 0 : }
994 : : }
995 : : }
996 : :
997 : 0 : void ScInputHandler::ShowTip( const String& rText )
998 : : {
999 : : // aManualTip muss hinterher von aussen gesetzt werden
1000 : 0 : HideTip();
1001 : :
1002 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1003 [ # # ]: 0 : if (pActiveView)
1004 : : {
1005 : 0 : Point aPos;
1006 [ # # ]: 0 : pTipVisibleParent = pActiveView->GetWindow();
1007 [ # # ]: 0 : Cursor* pCur = pActiveView->GetCursor();
1008 [ # # ]: 0 : if (pCur)
1009 [ # # ]: 0 : aPos = pTipVisibleParent->LogicToPixel( pCur->GetPos() );
1010 [ # # ]: 0 : aPos = pTipVisibleParent->OutputToScreenPixel( aPos );
1011 [ # # ]: 0 : Rectangle aRect( aPos, aPos );
1012 : :
1013 : 0 : sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
1014 [ # # ]: 0 : nTipVisible = Help::ShowTip(pTipVisibleParent, aRect, rText, nAlign);
1015 [ # # ][ # # ]: 0 : pTipVisibleParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
1016 : : }
1017 : 0 : }
1018 : :
1019 : 0 : void ScInputHandler::ShowTipBelow( const String& rText )
1020 : : {
1021 : 0 : HideTipBelow();
1022 : :
1023 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1024 [ # # ]: 0 : if ( pActiveView )
1025 : : {
1026 : 0 : Point aPos;
1027 [ # # ]: 0 : pTipVisibleSecParent = pActiveView->GetWindow();
1028 [ # # ]: 0 : Cursor* pCur = pActiveView->GetCursor();
1029 [ # # ]: 0 : if ( pCur )
1030 : : {
1031 : 0 : Point aLogicPos = pCur->GetPos();
1032 : 0 : aLogicPos.Y() += pCur->GetHeight();
1033 [ # # ]: 0 : aPos = pTipVisibleSecParent->LogicToPixel( aLogicPos );
1034 : : }
1035 [ # # ]: 0 : aPos = pTipVisibleSecParent->OutputToScreenPixel( aPos );
1036 [ # # ]: 0 : Rectangle aRect( aPos, aPos );
1037 : 0 : sal_uInt16 nAlign = QUICKHELP_LEFT | QUICKHELP_TOP | QUICKHELP_NOEVADEPOINTER;
1038 [ # # ]: 0 : nTipVisibleSec = Help::ShowTip(pTipVisibleSecParent, aRect, rText, nAlign);
1039 [ # # ][ # # ]: 0 : pTipVisibleSecParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
1040 : : }
1041 : 0 : }
1042 : :
1043 : 0 : void ScInputHandler::UseFormulaData()
1044 : : {
1045 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1046 : 0 : ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
1047 : 0 : const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
1048 : 0 : const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
1049 : :
1050 : : // Formeln duerfen nur 1 Absatz haben
1051 [ # # ][ # # ]: 0 : if ( pActiveView && pFormulaData && pEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
1052 : : {
1053 [ # # ]: 0 : String aTotal = pEngine->GetText( (sal_uInt16) 0 );
1054 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
1055 : 0 : aSel.Adjust();
1056 : :
1057 : : // Durch Differenzen zwischen Tabelle und Eingabezeile
1058 : : // (z.B. Clipboard mit Zeilenumbruechen) kann es sein, dass die Selektion
1059 : : // nicht mehr zur EditEngine passt. Dann halt kommentarlos abbrechen:
1060 : :
1061 [ # # ]: 0 : if ( aSel.nEndPos > aTotal.Len() )
1062 : 0 : return;
1063 : :
1064 : : // steht der Cursor am Ende eines Wortes?
1065 : :
1066 [ # # ]: 0 : if ( aSel.nEndPos > 0 )
1067 : : {
1068 : 0 : xub_StrLen nPos = aSel.nEndPos;
1069 [ # # ]: 0 : String aFormula = aTotal.Copy( 0, nPos );;
1070 : 0 : xub_StrLen nLeftParentPos = 0;
1071 : 0 : xub_StrLen nNextFStart = 0;
1072 : 0 : xub_StrLen nNextFEnd = 0;
1073 : 0 : xub_StrLen nArgPos = 0;
1074 : : const IFunctionDescription* ppFDesc;
1075 [ # # ]: 0 : ::std::vector< ::rtl::OUString> aArgs;
1076 : : sal_uInt16 nArgs;
1077 : 0 : bool bFound = false;
1078 : :
1079 [ # # ][ # # ]: 0 : rtl::OUString aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
[ # # ]
1080 [ # # ]: 0 : if (!aText.isEmpty())
1081 : : {
1082 : 0 : rtl::OUString aNew;
1083 : 0 : miAutoPosFormula = pFormulaData->end();
1084 [ # # ]: 0 : miAutoPosFormula = findText(*pFormulaData, miAutoPosFormula, aText, aNew, false);
1085 [ # # ]: 0 : if (miAutoPosFormula != pFormulaData->end())
1086 : : {
1087 [ # # ][ # # ]: 0 : ShowTip( aNew );
[ # # ]
1088 : 0 : aAutoSearch = aText;
1089 : 0 : }
1090 : : }
1091 [ # # ][ # # ]: 0 : FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());
1092 : :
1093 [ # # ]: 0 : while( !bFound )
1094 : : {
1095 [ # # ]: 0 : aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1096 : 0 : nLeftParentPos = lcl_MatchParenthesis( aFormula, aFormula.Len()-1 );
1097 [ # # ]: 0 : if( nLeftParentPos == STRING_NOTFOUND )
1098 : 0 : break;
1099 : :
1100 : : // nLeftParentPos can be 0 if a parenthesis is inserted before the formula
1101 [ # # ]: 0 : sal_Unicode c = ( nLeftParentPos > 0 ) ? aFormula.GetChar( nLeftParentPos-1 ) : 0;
1102 [ # # ][ # # ]: 0 : if( !(comphelper::string::isalphaAscii(c)) )
1103 : 0 : continue;
1104 [ # # ]: 0 : nNextFStart = aHelper.GetFunctionStart( aFormula, nLeftParentPos, true);
1105 [ # # ][ # # ]: 0 : if( aHelper.GetNextFunc( aFormula, false, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
1106 : : {
1107 [ # # ][ # # ]: 0 : if( !ppFDesc->getFunctionName().isEmpty() )
1108 : : {
1109 [ # # ]: 0 : nArgPos = aHelper.GetArgStart( aFormula, nNextFStart, 0 );
1110 [ # # ]: 0 : nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount());
1111 : :
1112 : 0 : bool bFlag = false;
1113 : 0 : rtl::OUString aNew;
1114 : : ScTypedCaseStrSet::const_iterator it =
1115 [ # # ][ # # ]: 0 : findText(*pFormulaDataPara, pFormulaDataPara->end(), ppFDesc->getFunctionName(), aNew, false);
1116 [ # # ]: 0 : if (it != pFormulaDataPara->end())
1117 : : {
1118 : 0 : sal_uInt16 nActive = 0;
1119 [ # # ]: 0 : for( sal_uInt16 i=0; i < nArgs; i++ )
1120 : : {
1121 : 0 : xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
1122 [ # # ]: 0 : if( nArgPos <= aFormula.Len()-1 )
1123 : : {
1124 : 0 : nActive = i+1;
1125 : 0 : bFlag = true;
1126 : : }
1127 : 0 : nArgPos+=nLength+1;
1128 : : }
1129 [ # # ]: 0 : if( bFlag )
1130 : : {
1131 [ # # ]: 0 : sal_Int32 nCountSemicolon = comphelper::string::getTokenCount(aNew, cSep) - 1;
1132 [ # # ]: 0 : sal_Int32 nCountDot = comphelper::string::getTokenCount(aNew, cSheetSep) - 1;
1133 : 0 : sal_Int32 nStartPosition = 0;
1134 : 0 : sal_Int32 nEndPosition = 0;
1135 : :
1136 [ # # ]: 0 : if( !nCountSemicolon )
1137 : : {
1138 [ # # ]: 0 : for (sal_Int32 i = 0; i < aNew.getLength(); ++i)
1139 : : {
1140 : 0 : sal_Unicode cNext = aNew.getStr()[i];
1141 [ # # ]: 0 : if( cNext == '(' )
1142 : : {
1143 : 0 : nStartPosition = i+1;
1144 : : }
1145 : : }
1146 : : }
1147 [ # # ]: 0 : else if( !nCountDot )
1148 : : {
1149 : 0 : sal_uInt16 nCount = 0;
1150 [ # # ]: 0 : for (sal_Int32 i = 0; i < aNew.getLength(); ++i)
1151 : : {
1152 : 0 : sal_Unicode cNext = aNew.getStr()[i];
1153 [ # # ]: 0 : if( cNext == '(' )
1154 : : {
1155 : 0 : nStartPosition = i+1;
1156 : : }
1157 [ # # ]: 0 : else if( cNext == cSep )
1158 : : {
1159 : 0 : nCount ++;
1160 : 0 : nEndPosition = i;
1161 [ # # ]: 0 : if( nCount == nActive )
1162 : : {
1163 : 0 : break;
1164 : : }
1165 : 0 : nStartPosition = nEndPosition+1;
1166 : : }
1167 : : }
1168 : : }
1169 : : else
1170 : : {
1171 : 0 : sal_uInt16 nCount = 0;
1172 [ # # ]: 0 : for (sal_Int32 i = 0; i < aNew.getLength(); ++i)
1173 : : {
1174 : 0 : sal_Unicode cNext = aNew.getStr()[i];
1175 [ # # ]: 0 : if( cNext == '(' )
1176 : : {
1177 : 0 : nStartPosition = i+1;
1178 : : }
1179 [ # # ]: 0 : else if( cNext == cSep )
1180 : : {
1181 : 0 : nCount ++;
1182 : 0 : nEndPosition = i;
1183 [ # # ]: 0 : if( nCount == nActive )
1184 : : {
1185 : 0 : break;
1186 : : }
1187 : 0 : nStartPosition = nEndPosition+1;
1188 : : }
1189 [ # # ]: 0 : else if( cNext == cSheetSep )
1190 : : {
1191 : 0 : continue;
1192 : : }
1193 : : }
1194 : : }
1195 : :
1196 [ # # ]: 0 : if (nStartPosition > 0)
1197 : : {
1198 : 0 : rtl::OUStringBuffer aBuf;
1199 [ # # ]: 0 : aBuf.append(aNew.copy(0, nStartPosition));
1200 [ # # ]: 0 : aBuf.append(static_cast<sal_Unicode>(0x25BA));
1201 [ # # ]: 0 : aBuf.append(aNew.copy(nStartPosition));
1202 [ # # ]: 0 : aNew = aBuf.makeStringAndClear();
1203 [ # # ][ # # ]: 0 : ShowTipBelow( aNew );
[ # # ]
1204 : 0 : bFound = true;
1205 : : }
1206 : : }
1207 : : else
1208 : : {
1209 [ # # ][ # # ]: 0 : ShowTipBelow( aNew );
[ # # ]
1210 : 0 : bFound = true;
1211 : : }
1212 : 0 : }
1213 : : }
1214 : : }
1215 [ # # ][ # # ]: 0 : }
1216 [ # # ][ # # ]: 0 : }
1217 : : }
1218 : : }
1219 : :
1220 : 0 : void ScInputHandler::NextFormulaEntry( bool bBack )
1221 : : {
1222 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1223 [ # # ][ # # ]: 0 : if ( pActiveView && pFormulaData )
1224 : : {
1225 : 0 : rtl::OUString aNew;
1226 [ # # ]: 0 : ScTypedCaseStrSet::const_iterator itNew = findText(*pFormulaData, miAutoPosFormula, aAutoSearch, aNew, bBack);
1227 [ # # ]: 0 : if (itNew != pFormulaData->end())
1228 : : {
1229 : 0 : miAutoPosFormula = itNew;
1230 [ # # ][ # # ]: 0 : ShowTip(aNew); // Display a quick help.
[ # # ]
1231 : 0 : }
1232 : : }
1233 : :
1234 : : // bei Tab wird vorher immer HideCursor gerufen
1235 : :
1236 [ # # ]: 0 : if (pActiveView)
1237 : 0 : pActiveView->ShowCursor();
1238 : 0 : }
1239 : :
1240 : 0 : void lcl_CompleteFunction( EditView* pView, const String& rInsert, bool& rParInserted )
1241 : : {
1242 [ # # ]: 0 : if (pView)
1243 : : {
1244 [ # # ]: 0 : ESelection aSel = pView->GetSelection();
1245 : 0 : --aSel.nStartPos;
1246 : 0 : --aSel.nEndPos;
1247 [ # # ]: 0 : pView->SetSelection(aSel);
1248 [ # # ]: 0 : pView->SelectCurrentWord();
1249 : :
1250 [ # # ]: 0 : String aInsStr = rInsert;
1251 : 0 : xub_StrLen nInsLen = aInsStr.Len();
1252 : 0 : bool bDoParen = ( nInsLen > 1 && aInsStr.GetChar(nInsLen-2) == '('
1253 [ # # ]: 0 : && aInsStr.GetChar(nInsLen-1) == ')' );
[ # # # # ]
1254 [ # # ]: 0 : if ( bDoParen )
1255 : : {
1256 : : // Klammern hinter Funktionsnamen nicht einfuegen, wenn direkt dahinter
1257 : : // schon eine Klammer steht (z.B. wenn der Funktionsname geaendert wurde).
1258 : :
1259 [ # # ]: 0 : ESelection aWordSel = pView->GetSelection();
1260 [ # # ][ # # ]: 0 : String aOld = pView->GetEditEngine()->GetText((sal_uInt16)0);
1261 : 0 : sal_Unicode cNext = aOld.GetChar(aWordSel.nEndPos);
1262 [ # # ]: 0 : if ( cNext == '(' )
1263 : : {
1264 : 0 : bDoParen = false;
1265 [ # # ]: 0 : aInsStr.Erase( nInsLen - 2 ); // Klammern weglassen
1266 [ # # ]: 0 : }
1267 : : }
1268 : :
1269 [ # # ]: 0 : pView->InsertText( aInsStr, false );
1270 : :
1271 [ # # ]: 0 : if ( bDoParen ) // Cursor zwischen die Klammern setzen
1272 : : {
1273 [ # # ]: 0 : aSel = pView->GetSelection();
1274 : 0 : --aSel.nStartPos;
1275 : 0 : --aSel.nEndPos;
1276 [ # # ]: 0 : pView->SetSelection(aSel);
1277 : :
1278 : 0 : rParInserted = true;
1279 [ # # ]: 0 : }
1280 : : }
1281 : 0 : }
1282 : :
1283 : 0 : void ScInputHandler::PasteFunctionData()
1284 : : {
1285 [ # # ][ # # ]: 0 : if (pFormulaData && miAutoPosFormula != pFormulaData->end())
[ # # ][ # # ]
1286 : : {
1287 : 0 : const ScTypedStrData& rData = *miAutoPosFormula;
1288 [ # # ]: 0 : const rtl::OUString& aInsert = rData.GetString();
1289 : 0 : bool bParInserted = false;
1290 : :
1291 [ # # ]: 0 : DataChanging(); // kann nicht neu sein
1292 [ # # ][ # # ]: 0 : lcl_CompleteFunction( pTopView, aInsert, bParInserted );
[ # # ]
1293 [ # # ][ # # ]: 0 : lcl_CompleteFunction( pTableView, aInsert, bParInserted );
[ # # ]
1294 [ # # ]: 0 : DataChanged();
1295 [ # # ]: 0 : ShowTipCursor();
1296 : :
1297 [ # # ]: 0 : if (bParInserted)
1298 : 0 : AutoParAdded();
1299 : : }
1300 : :
1301 : 0 : HideTip();
1302 : :
1303 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1304 [ # # ]: 0 : if (pActiveView)
1305 : 0 : pActiveView->ShowCursor();
1306 : 0 : }
1307 : :
1308 : : //
1309 : : // Selektion berechnen und als Tip-Hilfe anzeigen
1310 : : //
1311 : :
1312 : 0 : String lcl_Calculate( const String& rFormula, ScDocument* pDoc, const ScAddress &rPos )
1313 : : {
1314 : : //! mit ScFormulaDlg::CalcValue zusammenfassen und ans Dokument verschieben !!!!
1315 : : //! (Anfuehrungszeichen bei Strings werden nur hier eingefuegt)
1316 : :
1317 : 0 : String aValue;
1318 : :
1319 [ # # ]: 0 : if (rFormula.Len())
1320 : : {
1321 [ # # ][ # # ]: 0 : ScFormulaCell* pCell = new ScFormulaCell( pDoc, rPos, rFormula );
[ # # ]
1322 : :
1323 : : // HACK! um bei ColRowNames kein #REF! zu bekommen,
1324 : : // wenn ein Name eigentlich als Bereich in die Gesamt-Formel
1325 : : // eingefuegt wird, bei der Einzeldarstellung aber als
1326 : : // single-Zellbezug interpretiert wird
1327 [ # # ]: 0 : bool bColRowName = pCell->HasColRowName();
1328 [ # # ]: 0 : if ( bColRowName )
1329 : : {
1330 : : // ColRowName im RPN-Code?
1331 [ # # ]: 0 : if ( pCell->GetCode()->GetCodeLen() <= 1 )
1332 : : { // ==1: einzelner ist als Parameter immer Bereich
1333 : : // ==0: es waere vielleicht einer, wenn..
1334 : 0 : rtl::OUStringBuffer aBraced;
1335 [ # # ]: 0 : aBraced.append('(');
1336 [ # # ][ # # ]: 0 : aBraced.append(rFormula);
1337 [ # # ]: 0 : aBraced.append(')');
1338 [ # # ][ # # ]: 0 : delete pCell;
1339 [ # # ][ # # ]: 0 : pCell = new ScFormulaCell( pDoc, rPos, aBraced.makeStringAndClear() );
[ # # ]
1340 : : }
1341 : : else
1342 : 0 : bColRowName = false;
1343 : : }
1344 : :
1345 [ # # ]: 0 : sal_uInt16 nErrCode = pCell->GetErrCode();
1346 [ # # ]: 0 : if ( nErrCode == 0 )
1347 : : {
1348 [ # # ]: 0 : SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable());
1349 : : Color* pColor;
1350 [ # # ][ # # ]: 0 : if ( pCell->IsValue() )
1351 : : {
1352 [ # # ]: 0 : double n = pCell->GetValue();
1353 : : sal_uLong nFormat = aFormatter.GetStandardFormat( n, 0,
1354 [ # # ]: 0 : pCell->GetFormatType(), ScGlobal::eLnge );
1355 [ # # ]: 0 : aFormatter.GetInputLineString( n, nFormat, aValue );
1356 : : //! display OutputString but insert InputLineString
1357 : : }
1358 : : else
1359 : : {
1360 [ # # ][ # # ]: 0 : String aStr = pCell->GetString();
1361 : : sal_uLong nFormat = aFormatter.GetStandardFormat(
1362 [ # # ]: 0 : pCell->GetFormatType(), ScGlobal::eLnge);
1363 : : aFormatter.GetOutputString( aStr, nFormat,
1364 [ # # ]: 0 : aValue, &pColor );
1365 : :
1366 [ # # ]: 0 : aValue.Insert('"',0); // in Anfuehrungszeichen
1367 [ # # ][ # # ]: 0 : aValue+='"';
1368 : : //! Anfuehrungszeichen im String escapen ????
1369 : : }
1370 : :
1371 : 0 : ScRange aTestRange;
1372 [ # # ][ # # ]: 0 : if ( bColRowName || (aTestRange.Parse(rFormula) & SCA_VALID) )
[ # # ][ # # ]
1373 [ # # ]: 0 : aValue.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." )); // Bereich
1374 : : }
1375 : : else
1376 [ # # ][ # # ]: 0 : aValue = ScGlobal::GetErrorString(nErrCode);
[ # # ]
1377 [ # # ][ # # ]: 0 : delete pCell;
1378 : : }
1379 : :
1380 : 0 : return aValue;
1381 : : }
1382 : :
1383 : 0 : void ScInputHandler::FormulaPreview()
1384 : : {
1385 : 0 : rtl::OUString aValue;
1386 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1387 [ # # ][ # # ]: 0 : if ( pActiveView && pActiveViewSh )
1388 : : {
1389 [ # # ]: 0 : String aPart = pActiveView->GetSelected();
1390 [ # # ]: 0 : if (!aPart.Len())
1391 [ # # ][ # # ]: 0 : aPart = pEngine->GetText((sal_uInt16)0);
[ # # ]
1392 : 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1393 [ # # ][ # # ]: 0 : aValue = lcl_Calculate( aPart, pDoc, aCursorPos );
[ # # ][ # # ]
1394 : : }
1395 : :
1396 [ # # ]: 0 : if (!aValue.isEmpty())
1397 : : {
1398 [ # # ][ # # ]: 0 : ShowTip( aValue ); // als QuickHelp anzeigen
[ # # ]
1399 : 0 : aManualTip = aValue; // nach ShowTip setzen
1400 [ # # ]: 0 : if (pFormulaData)
1401 : 0 : miAutoPosFormula = pFormulaData->end();
1402 [ # # ]: 0 : if (pColumnData)
1403 : 0 : miAutoPosColumn = pColumnData->end();
1404 : 0 : }
1405 : 0 : }
1406 : :
1407 : 0 : void ScInputHandler::PasteManualTip()
1408 : : {
1409 : : // drei Punkte am Ende -> Bereichsreferenz -> nicht einfuegen
1410 : : // (wenn wir mal Matrix-Konstanten haben, kann das geaendert werden)
1411 : :
1412 : 0 : sal_Int32 nTipLen = aManualTip.getLength();
1413 : 0 : sal_uInt32 const nTipLen2(sal::static_int_cast<sal_uInt32>(nTipLen));
1414 [ # # ][ # # ]: 0 : if ( nTipLen && ( nTipLen < 3 || aManualTip.copy( nTipLen2-3 ) != "..." ) )
[ # # ][ # # ]
[ # # ]
1415 : : {
1416 [ # # ]: 0 : DataChanging(); // kann nicht neu sein
1417 : :
1418 [ # # ]: 0 : String aInsert = aManualTip;
1419 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1420 [ # # ][ # # ]: 0 : if (!pActiveView->HasSelection())
1421 : : {
1422 : : // nichts selektiert -> alles selektieren
1423 [ # # ]: 0 : xub_StrLen nOldLen = pEngine->GetTextLen(0);
1424 : 0 : ESelection aAllSel( 0, 0, 0, nOldLen );
1425 [ # # ]: 0 : if ( pTopView )
1426 [ # # ]: 0 : pTopView->SetSelection( aAllSel );
1427 [ # # ]: 0 : if ( pTableView )
1428 [ # # ]: 0 : pTableView->SetSelection( aAllSel );
1429 : : }
1430 : :
1431 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
1432 : 0 : aSel.Adjust();
1433 : : OSL_ENSURE( !aSel.nStartPara && !aSel.nEndPara, "Zuviele Absaetze in Formel" );
1434 [ # # ]: 0 : if ( !aSel.nStartPos ) // Selektion ab Anfang?
1435 : : {
1436 [ # # ][ # # ]: 0 : if ( aSel.nEndPos == pEngine->GetTextLen(0) )
1437 : : {
1438 : : // alles selektiert -> Anfuehrungszeichen weglassen
1439 [ # # ]: 0 : if ( aInsert.GetChar(0) == '"' )
1440 [ # # ]: 0 : aInsert.Erase(0,1);
1441 : 0 : xub_StrLen nInsLen = aInsert.Len();
1442 [ # # ][ # # ]: 0 : if ( nInsLen && aInsert.GetChar(nInsLen-1) == '"' )
[ # # ]
1443 [ # # ]: 0 : aInsert.Erase( nInsLen-1 );
1444 : : }
1445 [ # # ]: 0 : else if ( aSel.nEndPos )
1446 : : {
1447 : : // nicht alles selektiert -> Gleichheitszeichen nicht ueberschreiben
1448 : : //! doppelte Gleichheitszeichen auch ???
1449 : :
1450 : 0 : aSel.nStartPos = 1;
1451 [ # # ]: 0 : if ( pTopView )
1452 [ # # ]: 0 : pTopView->SetSelection( aSel );
1453 [ # # ]: 0 : if ( pTableView )
1454 [ # # ]: 0 : pTableView->SetSelection( aSel );
1455 : : }
1456 : : }
1457 [ # # ]: 0 : if ( pTopView )
1458 [ # # ]: 0 : pTopView->InsertText( aInsert, true );
1459 [ # # ]: 0 : if ( pTableView )
1460 [ # # ]: 0 : pTableView->InsertText( aInsert, true );
1461 : :
1462 [ # # ][ # # ]: 0 : DataChanged();
1463 : : }
1464 : :
1465 : 0 : HideTip();
1466 : 0 : }
1467 : :
1468 : 519 : void ScInputHandler::ResetAutoPar()
1469 : : {
1470 : 519 : nAutoPar = 0;
1471 : 519 : }
1472 : :
1473 : 0 : void ScInputHandler::AutoParAdded()
1474 : : {
1475 : 0 : ++nAutoPar; // closing parenthesis can be overwritten
1476 : 0 : }
1477 : :
1478 : 0 : bool ScInputHandler::CursorAtClosingPar()
1479 : : {
1480 : : // test if the cursor is before a closing parenthesis
1481 : :
1482 : : // selection from SetReference has been removed before
1483 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1484 [ # # ][ # # ]: 0 : if ( pActiveView && !pActiveView->HasSelection() && bFormulaMode )
[ # # ][ # # ]
1485 : : {
1486 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
1487 : 0 : xub_StrLen nPos = aSel.nStartPos;
1488 [ # # ]: 0 : String aFormula = pEngine->GetText((sal_uInt16)0);
1489 [ # # ][ # # ]: 0 : if ( nPos < aFormula.Len() && aFormula.GetChar(nPos) == ')' )
[ # # ]
1490 [ # # ][ # # ]: 0 : return true;
1491 : : }
1492 : 0 : return false;
1493 : : }
1494 : :
1495 : 0 : void ScInputHandler::SkipClosingPar()
1496 : : {
1497 : : // this is called when a ')' is typed and the cursor is before a ')'
1498 : : // that can be overwritten -> just set the cursor behind the ')'
1499 : :
1500 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1501 [ # # ]: 0 : if (pActiveView)
1502 : : {
1503 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
1504 : 0 : ++aSel.nStartPos;
1505 : 0 : ++aSel.nEndPos;
1506 : :
1507 : : // this is in a formula (only one paragraph), so the selection
1508 : : // can be used directly for the TopView
1509 : :
1510 [ # # ]: 0 : if ( pTopView )
1511 [ # # ]: 0 : pTopView->SetSelection( aSel );
1512 [ # # ]: 0 : if ( pTableView )
1513 [ # # ]: 0 : pTableView->SetSelection( aSel );
1514 : : }
1515 : :
1516 : : OSL_ENSURE(nAutoPar, "SkipClosingPar: count is wrong");
1517 : 0 : --nAutoPar;
1518 : 0 : }
1519 : :
1520 : : //
1521 : : // Auto-Eingabe
1522 : : //
1523 : :
1524 : 0 : void ScInputHandler::GetColData()
1525 : : {
1526 [ # # ]: 0 : if ( pActiveViewSh )
1527 : : {
1528 : 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1529 : :
1530 [ # # ]: 0 : if ( pColumnData )
1531 : 0 : pColumnData->clear();
1532 : : else
1533 : : {
1534 [ # # ][ # # ]: 0 : pColumnData = new ScTypedCaseStrSet;
1535 : 0 : miAutoPosColumn = pColumnData->end();
1536 : : }
1537 : :
1538 [ # # ]: 0 : std::vector<ScTypedStrData> aEntries;
1539 : : pDoc->GetDataEntries(
1540 [ # # ]: 0 : aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), true, aEntries, true);
1541 [ # # ]: 0 : if (!aEntries.empty())
1542 [ # # ]: 0 : pColumnData->insert(aEntries.begin(), aEntries.end());
1543 : : }
1544 : 0 : }
1545 : :
1546 : 0 : void ScInputHandler::UseColData() // beim Tippen
1547 : : {
1548 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1549 [ # # ][ # # ]: 0 : if ( pActiveView && pColumnData )
1550 : : {
1551 : : // nur anpassen, wenn Cursor am Ende steht
1552 : :
1553 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
1554 : 0 : aSel.Adjust();
1555 : :
1556 [ # # ]: 0 : sal_uInt16 nParCnt = pEngine->GetParagraphCount();
1557 [ # # ]: 0 : if ( aSel.nEndPara+1 == nParCnt )
1558 : : {
1559 [ # # ]: 0 : xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
1560 [ # # ]: 0 : if ( aSel.nEndPos == nParLen )
1561 : : {
1562 [ # # ][ # # ]: 0 : rtl::OUString aText = GetEditText(pEngine);
[ # # ][ # # ]
1563 [ # # ]: 0 : if (!aText.isEmpty())
1564 : : {
1565 : 0 : rtl::OUString aNew;
1566 : 0 : miAutoPosColumn = pColumnData->end();
1567 [ # # ]: 0 : miAutoPosColumn = findText(*pColumnData, miAutoPosColumn, aText, aNew, false);
1568 [ # # ]: 0 : if (miAutoPosColumn != pColumnData->end())
1569 : : {
1570 : : // durch dBase Import etc. koennen Umbrueche im String sein,
1571 : : // das wuerde hier mehrere Absaetze ergeben -> nicht gut
1572 : : //! GetExactMatch funktioniert dann auch nicht
1573 [ # # ]: 0 : lcl_RemoveLineEnd( aNew );
1574 : :
1575 : : // Absaetze beibehalten, nur den Rest anfuegen
1576 : : //! genaue Ersetzung im EnterHandler !!!
1577 : :
1578 : : // ein Space zwischen Absaetzen:
1579 [ # # ]: 0 : sal_Int32 nEdLen = pEngine->GetTextLen() + nParCnt - 1;
1580 : 0 : rtl::OUString aIns = aNew.copy(nEdLen);
1581 : :
1582 : : // selection must be "backwards", so the cursor stays behind the last
1583 : : // typed character
1584 : 0 : ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.getLength(),
1585 : 0 : aSel.nEndPara, aSel.nEndPos );
1586 : :
1587 : : // when editing in input line, apply to both edit views
1588 [ # # ]: 0 : if ( pTableView )
1589 : : {
1590 [ # # ][ # # ]: 0 : pTableView->InsertText( aIns, false );
[ # # ]
1591 [ # # ]: 0 : pTableView->SetSelection( aSelection );
1592 : : }
1593 [ # # ]: 0 : if ( pTopView )
1594 : : {
1595 [ # # ][ # # ]: 0 : pTopView->InsertText( aIns, false );
[ # # ]
1596 [ # # ]: 0 : pTopView->SetSelection( aSelection );
1597 : : }
1598 : :
1599 : 0 : aAutoSearch = aText; // zum Weitersuchen - nAutoPos ist gesetzt
1600 : :
1601 [ # # ]: 0 : if (aText.getLength() == aNew.getLength())
1602 : : {
1603 : : // Wenn der eingegebene Text gefunden wurde, TAB nur dann
1604 : : // verschlucken, wenn noch etwas kommt
1605 : :
1606 : 0 : rtl::OUString aDummy;
1607 : : ScTypedCaseStrSet::const_iterator itNextPos =
1608 [ # # ]: 0 : findText(*pColumnData, miAutoPosColumn, aText, aDummy, false);
1609 : 0 : bUseTab = itNextPos != pColumnData->end();
1610 : : }
1611 : : else
1612 : 0 : bUseTab = true;
1613 : 0 : }
1614 : 0 : }
1615 : : }
1616 : : }
1617 : : }
1618 : 0 : }
1619 : :
1620 : 0 : void ScInputHandler::NextAutoEntry( bool bBack )
1621 : : {
1622 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1623 [ # # ][ # # ]: 0 : if ( pActiveView && pColumnData )
1624 : : {
1625 [ # # ][ # # ]: 0 : if (miAutoPosColumn != pColumnData->end() && !aAutoSearch.isEmpty())
[ # # ][ # # ]
1626 : : {
1627 : : // stimmt die Selektion noch? (kann per Maus geaendert sein)
1628 : :
1629 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
1630 : 0 : aSel.Adjust();
1631 [ # # ]: 0 : sal_uInt16 nParCnt = pEngine->GetParagraphCount();
1632 [ # # ][ # # ]: 0 : if ( aSel.nEndPara+1 == nParCnt && aSel.nStartPara == aSel.nEndPara )
1633 : : {
1634 [ # # ][ # # ]: 0 : rtl::OUString aText = GetEditText(pEngine);
[ # # ][ # # ]
1635 : 0 : xub_StrLen nSelLen = aSel.nEndPos - aSel.nStartPos;
1636 [ # # ]: 0 : xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
1637 [ # # ][ # # ]: 0 : if ( aSel.nEndPos == nParLen && aText.getLength() == aAutoSearch.getLength() + nSelLen )
[ # # ]
1638 : : {
1639 : 0 : rtl::OUString aNew;
1640 : : ScTypedCaseStrSet::const_iterator itNew =
1641 [ # # ]: 0 : findText(*pColumnData, miAutoPosColumn, aAutoSearch, aNew, bBack);
1642 : :
1643 [ # # ]: 0 : if (itNew != pColumnData->end())
1644 : : {
1645 : : // match found!
1646 : 0 : miAutoPosColumn = itNew;
1647 : 0 : bInOwnChange = true; // disable ModifyHdl (reset below)
1648 : :
1649 [ # # ]: 0 : lcl_RemoveLineEnd( aNew );
1650 : 0 : rtl::OUString aIns = aNew.copy(aAutoSearch.getLength());
1651 : :
1652 : : // when editing in input line, apply to both edit views
1653 [ # # ]: 0 : if ( pTableView )
1654 : : {
1655 [ # # ]: 0 : pTableView->DeleteSelected();
1656 [ # # ][ # # ]: 0 : pTableView->InsertText( aIns, false );
[ # # ]
1657 : : pTableView->SetSelection( ESelection(
1658 : 0 : aSel.nEndPara, aSel.nStartPos + aIns.getLength(),
1659 [ # # ]: 0 : aSel.nEndPara, aSel.nStartPos ) );
1660 : : }
1661 [ # # ]: 0 : if ( pTopView )
1662 : : {
1663 [ # # ]: 0 : pTopView->DeleteSelected();
1664 [ # # ][ # # ]: 0 : pTopView->InsertText( aIns, false );
[ # # ]
1665 : : pTopView->SetSelection( ESelection(
1666 : 0 : aSel.nEndPara, aSel.nStartPos + aIns.getLength(),
1667 [ # # ]: 0 : aSel.nEndPara, aSel.nStartPos ) );
1668 : : }
1669 : :
1670 : 0 : bInOwnChange = false;
1671 : 0 : }
1672 : 0 : }
1673 : : }
1674 : : }
1675 : : }
1676 : :
1677 : : // bei Tab wird vorher immer HideCursor gerufen
1678 : :
1679 [ # # ]: 0 : if (pActiveView)
1680 : 0 : pActiveView->ShowCursor();
1681 : 0 : }
1682 : :
1683 : : //
1684 : : // Klammern hervorheben
1685 : : //
1686 : :
1687 : 0 : void ScInputHandler::UpdateParenthesis()
1688 : : {
1689 : : // Klammern suchen
1690 : :
1691 : : //! Klammer-Hervorhebung einzeln abschaltbar ????
1692 : :
1693 : 0 : bool bFound = false;
1694 [ # # ][ # # ]: 0 : if ( bFormulaMode && eMode != SC_INPUT_TOP )
1695 : : {
1696 [ # # ][ # # ]: 0 : if ( pTableView && !pTableView->HasSelection() ) // Selektion ist immer unten
[ # # ]
1697 : : {
1698 [ # # ]: 0 : ESelection aSel = pTableView->GetSelection();
1699 [ # # ]: 0 : if (aSel.nStartPos)
1700 : : {
1701 : : // Das Zeichen links vom Cursor wird angeschaut
1702 : :
1703 : 0 : xub_StrLen nPos = aSel.nStartPos - 1;
1704 [ # # ]: 0 : String aFormula = pEngine->GetText((sal_uInt16)0);
1705 : 0 : sal_Unicode c = aFormula.GetChar(nPos);
1706 [ # # ][ # # ]: 0 : if ( c == '(' || c == ')' )
1707 : : {
1708 : 0 : xub_StrLen nOther = lcl_MatchParenthesis( aFormula, nPos );
1709 [ # # ]: 0 : if ( nOther != STRING_NOTFOUND )
1710 : : {
1711 [ # # ][ # # ]: 0 : SfxItemSet aSet( pEngine->GetEmptyItemSet() );
1712 [ # # ][ # # ]: 0 : aSet.Put( SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
[ # # ]
1713 : : //! Unterscheidung, wenn die Zelle schon fett ist !!!!
1714 : :
1715 [ # # ]: 0 : if (bParenthesisShown)
1716 : : {
1717 : : // alte Hervorhebung wegnehmen
1718 [ # # ]: 0 : sal_uInt16 nCount = pEngine->GetParagraphCount();
1719 [ # # ]: 0 : for (sal_uInt16 i=0; i<nCount; i++)
1720 [ # # ]: 0 : pEngine->QuickRemoveCharAttribs( i, EE_CHAR_WEIGHT );
1721 : : }
1722 : :
1723 : 0 : ESelection aSelThis( 0,nPos, 0,nPos+1 );
1724 [ # # ]: 0 : pEngine->QuickSetAttribs( aSet, aSelThis );
1725 : 0 : ESelection aSelOther( 0,nOther, 0,nOther+1 );
1726 [ # # ]: 0 : pEngine->QuickSetAttribs( aSet, aSelOther );
1727 : :
1728 : : // Dummy-InsertText fuer Update und Paint (Selektion ist leer)
1729 [ # # ][ # # ]: 0 : pTableView->InsertText( EMPTY_STRING, false );
1730 : :
1731 [ # # ]: 0 : bFound = true;
1732 : : }
1733 [ # # ]: 0 : }
1734 : : }
1735 : :
1736 : : // mark parenthesis right of cursor if it will be overwritten (nAutoPar)
1737 : : // with different color (COL_LIGHTBLUE) ??
1738 : : }
1739 : : }
1740 : :
1741 : : // alte Hervorhebung wegnehmen, wenn keine neue gesetzt
1742 : :
1743 [ # # ][ # # ]: 0 : if ( bParenthesisShown && !bFound && pTableView )
[ # # ]
1744 : : {
1745 : 0 : sal_uInt16 nCount = pEngine->GetParagraphCount();
1746 [ # # ]: 0 : for (sal_uInt16 i=0; i<nCount; i++)
1747 : 0 : pTableView->RemoveCharAttribs( i, EE_CHAR_WEIGHT );
1748 : : }
1749 : :
1750 : 0 : bParenthesisShown = bFound;
1751 : 0 : }
1752 : :
1753 : 9 : void ScInputHandler::ViewShellGone(ScTabViewShell* pViewSh) // wird synchron aufgerufen!
1754 : : {
1755 [ - + ]: 9 : if ( pViewSh == pActiveViewSh )
1756 : : {
1757 [ # # ]: 0 : delete pLastState;
1758 : 0 : pLastState = NULL;
1759 : 0 : pLastPattern = NULL;
1760 : : }
1761 : :
1762 [ - + ]: 9 : if ( pViewSh == pRefViewSh )
1763 : : {
1764 : : //! Die Eingabe kommt aus dem EnterHandler nicht mehr an
1765 : : // Trotzdem wird immerhin der Editmodus beendet
1766 : :
1767 : 0 : EnterHandler();
1768 : 0 : bFormulaMode = false;
1769 : 0 : pRefViewSh = NULL;
1770 [ # # ][ # # ]: 0 : SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
1771 : 0 : SC_MOD()->SetRefInputHdl(NULL);
1772 [ # # ]: 0 : if (pInputWin)
1773 : 0 : pInputWin->SetFormulaMode(false);
1774 : 0 : UpdateAutoCorrFlag();
1775 : : }
1776 : :
1777 [ + - ][ + - ]: 9 : pActiveViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
1778 : :
1779 [ + - ][ - + ]: 9 : if ( pActiveViewSh && pActiveViewSh == pViewSh )
1780 : : {
1781 : : OSL_FAIL("pActiveViewSh weg");
1782 : 0 : pActiveViewSh = NULL;
1783 : : }
1784 : :
1785 [ - + ]: 9 : if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
1786 : 0 : UpdateRefDevice(); // don't keep old document's printer as RefDevice
1787 : 9 : }
1788 : :
1789 : 0 : void ScInputHandler::UpdateActiveView()
1790 : : {
1791 : 0 : ImplCreateEditEngine();
1792 : :
1793 : : // #i20588# Don't rely on focus to find the active edit view. Instead, the
1794 : : // active pane at the start of editing is now stored (GetEditActivePart).
1795 : : // GetActiveWin (the currently active pane) fails for ref input across the
1796 : : // panes of a split view.
1797 : :
1798 : : Window* pShellWin = pActiveViewSh ?
1799 : 0 : pActiveViewSh->GetWindowByPos( pActiveViewSh->GetViewData()->GetEditActivePart() ) :
1800 [ # # ]: 0 : NULL;
1801 : :
1802 : 0 : sal_uInt16 nCount = pEngine->GetViewCount();
1803 [ # # ]: 0 : if (nCount > 0)
1804 : : {
1805 : 0 : pTableView = pEngine->GetView(0);
1806 [ # # ]: 0 : for (sal_uInt16 i=1; i<nCount; i++)
1807 : : {
1808 : 0 : EditView* pThis = pEngine->GetView(i);
1809 : 0 : Window* pWin = pThis->GetWindow();
1810 [ # # ]: 0 : if ( pWin==pShellWin )
1811 : 0 : pTableView = pThis;
1812 : : }
1813 : : }
1814 : : else
1815 : 0 : pTableView = NULL;
1816 : :
1817 [ # # ][ # # ]: 0 : if (pInputWin && eMode == SC_INPUT_TOP )
1818 : 0 : pTopView = pInputWin->GetEditView();
1819 : : else
1820 : 0 : pTopView = NULL;
1821 : 0 : }
1822 : :
1823 : 744 : void ScInputHandler::StopInputWinEngine( bool bAll )
1824 : : {
1825 [ + + ]: 744 : if (pInputWin)
1826 : 94 : pInputWin->StopEditEngine( bAll );
1827 : :
1828 : 744 : pTopView = NULL; // invalid now
1829 : 744 : }
1830 : :
1831 : 0 : EditView* ScInputHandler::GetActiveView()
1832 : : {
1833 : 0 : UpdateActiveView();
1834 [ # # ]: 0 : return pTopView ? pTopView : pTableView;
1835 : : }
1836 : :
1837 : 0 : void ScInputHandler::ForgetLastPattern()
1838 : : {
1839 : 0 : pLastPattern = NULL;
1840 [ # # ][ # # ]: 0 : if ( !pLastState && pActiveViewSh )
1841 : 0 : pActiveViewSh->UpdateInputHandler( true ); // Status neu holen
1842 : : else
1843 : 0 : NotifyChange( pLastState, true );
1844 : 0 : }
1845 : :
1846 : 0 : void ScInputHandler::UpdateAdjust( sal_Unicode cTyped )
1847 : : {
1848 : : SvxAdjust eSvxAdjust;
1849 [ # # # # : 0 : switch (eAttrAdjust)
# ]
1850 : : {
1851 : : case SVX_HOR_JUSTIFY_STANDARD:
1852 : : {
1853 : 0 : bool bNumber = false;
1854 [ # # ]: 0 : if (cTyped) // neu angefangen
1855 [ # # ][ # # ]: 0 : bNumber = (cTyped>='0' && cTyped<='9'); // nur Ziffern sind Zahlen
1856 [ # # ]: 0 : else if ( pActiveViewSh )
1857 : : {
1858 : 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1859 : 0 : bNumber = ( pDoc->GetCellType( aCursorPos ) == CELLTYPE_VALUE );
1860 : : }
1861 [ # # ]: 0 : eSvxAdjust = bNumber ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
1862 : : }
1863 : 0 : break;
1864 : : case SVX_HOR_JUSTIFY_BLOCK:
1865 : 0 : eSvxAdjust = SVX_ADJUST_BLOCK;
1866 : 0 : break;
1867 : : case SVX_HOR_JUSTIFY_CENTER:
1868 : 0 : eSvxAdjust = SVX_ADJUST_CENTER;
1869 : 0 : break;
1870 : : case SVX_HOR_JUSTIFY_RIGHT:
1871 : 0 : eSvxAdjust = SVX_ADJUST_RIGHT;
1872 : 0 : break;
1873 : : default: // SVX_HOR_JUSTIFY_LEFT
1874 : 0 : eSvxAdjust = SVX_ADJUST_LEFT;
1875 : 0 : break;
1876 : : }
1877 : :
1878 : : bool bAsianVertical = pLastPattern &&
1879 : 0 : ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_STACKED )).GetValue() &&
1880 [ # # # # ]: 0 : ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
[ # # ]
1881 [ # # ]: 0 : if ( bAsianVertical )
1882 : : {
1883 : : // always edit at top of cell -> LEFT when editing vertically
1884 : 0 : eSvxAdjust = SVX_ADJUST_LEFT;
1885 : : }
1886 : :
1887 [ # # ]: 0 : pEditDefaults->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
1888 : 0 : pEngine->SetDefaults( *pEditDefaults );
1889 : :
1890 : 0 : nEditAdjust = sal::static_int_cast<sal_uInt16>(eSvxAdjust); //! set at ViewData or with PostEditView
1891 : :
1892 : 0 : pEngine->SetVertical( bAsianVertical );
1893 : 0 : }
1894 : :
1895 : 0 : void ScInputHandler::RemoveAdjust()
1896 : : {
1897 : : // harte Ausrichtungs-Attribute loeschen
1898 : :
1899 : 0 : bool bUndo = pEngine->IsUndoEnabled();
1900 [ # # ]: 0 : if ( bUndo )
1901 : 0 : pEngine->EnableUndo( false );
1902 : :
1903 : : // non-default paragraph attributes (e.g. from clipboard)
1904 : : // must be turned into character attributes
1905 : 0 : pEngine->RemoveParaAttribs();
1906 : :
1907 [ # # ]: 0 : if ( bUndo )
1908 : 0 : pEngine->EnableUndo( true );
1909 : :
1910 : 0 : }
1911 : :
1912 : 0 : void ScInputHandler::RemoveRangeFinder()
1913 : : {
1914 : : // pRangeFindList und Farben loeschen
1915 : :
1916 : 0 : pEngine->SetUpdateMode(false);
1917 : 0 : sal_uInt16 nCount = pEngine->GetParagraphCount(); // koennte gerade neu eingefuegt worden sein
1918 [ # # ]: 0 : for (sal_uInt16 i=0; i<nCount; i++)
1919 : 0 : pEngine->QuickRemoveCharAttribs( i, EE_CHAR_COLOR );
1920 : 0 : pEngine->SetUpdateMode(true);
1921 : :
1922 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
1923 : 0 : pActiveView->ShowCursor( false, true );
1924 : :
1925 : 0 : DeleteRangeFinder(); // loescht die Liste und die Markierungen auf der Tabelle
1926 : 0 : }
1927 : :
1928 : 0 : bool ScInputHandler::StartTable( sal_Unicode cTyped, bool bFromCommand, bool bInputActivated )
1929 : : {
1930 : 0 : bool bNewTable = false;
1931 : :
1932 [ # # ][ # # ]: 0 : if (bModified || !ValidCol(aCursorPos.Col()))
[ # # ]
1933 : 0 : return false;
1934 : :
1935 [ # # ]: 0 : if (pActiveViewSh)
1936 : : {
1937 [ # # ]: 0 : ImplCreateEditEngine();
1938 [ # # ]: 0 : UpdateActiveView();
1939 [ # # ]: 0 : SyncViews();
1940 : :
1941 : 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1942 : :
1943 [ # # ]: 0 : const ScMarkData& rMark = pActiveViewSh->GetViewData()->GetMarkData();
1944 [ # # ]: 0 : ScEditableTester aTester;
1945 [ # # ][ # # ]: 0 : if ( rMark.IsMarked() || rMark.IsMultiMarked() )
[ # # ]
1946 [ # # ]: 0 : aTester.TestSelection( pDoc, rMark );
1947 : : else
1948 : : aTester.TestSelectedBlock(
1949 [ # # ]: 0 : pDoc, aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Col(), aCursorPos.Row(), rMark );
1950 : :
1951 : 0 : bool bStartInputMode = true;
1952 : :
1953 [ # # ]: 0 : if (!aTester.IsEditable())
1954 : : {
1955 : 0 : bProtected = true;
1956 : : // We allow read-only input mode activation when explicit cell
1957 : : // activation is requested (double-click or F2) and if it's not
1958 : : // part of an array.
1959 [ # # ][ # # ]: 0 : bool bShowError = !bInputActivated || aTester.GetMessageId() != STR_PROTECTIONERR;
[ # # ]
1960 [ # # ]: 0 : if (bShowError)
1961 : : {
1962 : 0 : eMode = SC_INPUT_NONE;
1963 [ # # ]: 0 : StopInputWinEngine( true );
1964 [ # # ]: 0 : UpdateFormulaMode();
1965 [ # # ][ # # ]: 0 : if ( pActiveViewSh && ( !bFromCommand || !bCommandErrorShown ) )
[ # # ]
1966 : : {
1967 : : // Prevent repeated error messages for the same cell from command events
1968 : : // (for keyboard events, multiple messages are wanted).
1969 : : // Set the flag before showing the error message because the command handler
1970 : : // for the next IME command may be called when showing the dialog.
1971 [ # # ]: 0 : if ( bFromCommand )
1972 : 0 : bCommandErrorShown = true;
1973 : :
1974 [ # # ][ # # ]: 0 : pActiveViewSh->GetActiveWin()->GrabFocus();
1975 [ # # ][ # # ]: 0 : pActiveViewSh->ErrorMessage(aTester.GetMessageId());
1976 : : }
1977 : 0 : bStartInputMode = false;
1978 : : }
1979 : : }
1980 : :
1981 [ # # ]: 0 : if (bStartInputMode)
1982 : : {
1983 : : // UpdateMode is enabled again in ScViewData::SetEditEngine (and not needed otherwise)
1984 [ # # ]: 0 : pEngine->SetUpdateMode( false );
1985 : :
1986 : : // Attribute in EditEngine uebernehmen
1987 : :
1988 : 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(),
1989 : : aCursorPos.Row(),
1990 [ # # ]: 0 : aCursorPos.Tab() );
1991 [ # # ]: 0 : if (pPattern != pLastPattern)
1992 : : {
1993 : : // Prozent-Format?
1994 : :
1995 : 0 : const SfxItemSet& rAttrSet = pPattern->GetItemSet();
1996 : : const SfxPoolItem* pItem;
1997 : :
1998 [ # # ][ # # ]: 0 : if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALUE_FORMAT, true, &pItem ) )
1999 : : {
2000 : 0 : sal_uLong nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
2001 : : bCellHasPercentFormat = ( NUMBERFORMAT_PERCENT ==
2002 [ # # ][ # # ]: 0 : pDoc->GetFormatTable()->GetType( nFormat ) );
2003 : : }
2004 : : else
2005 : 0 : bCellHasPercentFormat = false; // Default: kein Prozent
2006 : :
2007 : : // Gueltigkeit angegeben?
2008 : :
2009 [ # # ][ # # ]: 0 : if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALIDDATA, true, &pItem ) )
2010 : 0 : nValidation = ((const SfxUInt32Item*)pItem)->GetValue();
2011 : : else
2012 : 0 : nValidation = 0;
2013 : :
2014 : : // EditEngine Defaults
2015 : :
2016 : : // Hier auf keinen Fall SetParaAttribs, weil die EditEngine evtl.
2017 : : // schon gefuellt ist (bei Edit-Zellen).
2018 : : // SetParaAttribs wuerde dann den Inhalt aendern
2019 : :
2020 : : //! The SetDefaults is now (since MUST/src602
2021 : : //! EditEngine changes) implemented as a SetParaAttribs.
2022 : : //! Any problems?
2023 : :
2024 [ # # ]: 0 : pPattern->FillEditItemSet( pEditDefaults );
2025 [ # # ]: 0 : pEngine->SetDefaults( *pEditDefaults );
2026 : 0 : pLastPattern = pPattern;
2027 [ # # ]: 0 : bLastIsSymbol = pPattern->IsSymbolFont();
2028 : :
2029 : : // Background color must be known for automatic font color.
2030 : : // For transparent cell background, the document background color must be used.
2031 : :
2032 : : Color aBackCol = ((const SvxBrushItem&)
2033 [ # # ]: 0 : pPattern->GetItem( ATTR_BACKGROUND )).GetColor();
2034 [ # # ]: 0 : ScModule* pScMod = SC_MOD();
2035 [ # # # # ]: 0 : if ( aBackCol.GetTransparency() > 0 ||
[ # # ]
2036 [ # # ]: 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
2037 [ # # ][ # # ]: 0 : aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
2038 [ # # ]: 0 : pEngine->SetBackgroundColor( aBackCol );
2039 : :
2040 : : // Ausrichtung
2041 : :
2042 : : eAttrAdjust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
2043 [ # # ]: 0 : GetItem(ATTR_HOR_JUSTIFY)).GetValue();
2044 [ # # ]: 0 : if ( eAttrAdjust == SVX_HOR_JUSTIFY_REPEAT &&
[ # # # # ]
2045 [ # # ]: 0 : static_cast<const SfxBoolItem&>(pPattern->GetItem(ATTR_LINEBREAK)).GetValue() )
2046 : : {
2047 : : // #i31843# "repeat" with "line breaks" is treated as default alignment
2048 : 0 : eAttrAdjust = SVX_HOR_JUSTIFY_STANDARD;
2049 : : }
2050 : : }
2051 : :
2052 : : // UpdateSpellSettings enables online spelling if needed
2053 : : // -> also call if attributes are unchanged
2054 : :
2055 [ # # ]: 0 : UpdateSpellSettings( true ); // uses pLastPattern
2056 : :
2057 : : // Edit-Engine fuellen
2058 : :
2059 [ # # ]: 0 : String aStr;
2060 [ # # ]: 0 : if (bTextValid)
2061 : : {
2062 [ # # ][ # # ]: 0 : pEngine->SetText(aCurrentText);
[ # # ]
2063 [ # # ]: 0 : aStr = aCurrentText;
2064 : 0 : bTextValid = false;
2065 : 0 : aCurrentText = rtl::OUString();
2066 : : }
2067 : : else
2068 [ # # ][ # # ]: 0 : aStr = GetEditText(pEngine);
[ # # ][ # # ]
2069 : :
2070 [ # # # # : 0 : if (aStr.Len() > 3 && // Matrix-Formel ?
# # # # ]
[ # # ]
2071 : 0 : aStr.GetChar(0) == '{' &&
2072 : 0 : aStr.GetChar(1) == '=' &&
2073 : 0 : aStr.GetChar(aStr.Len()-1) == '}')
2074 : : {
2075 [ # # ]: 0 : aStr.Erase(0,1);
2076 [ # # ]: 0 : aStr.Erase(aStr.Len()-1,1);
2077 [ # # ]: 0 : pEngine->SetText(aStr);
2078 [ # # ]: 0 : if ( pInputWin )
2079 [ # # ]: 0 : pInputWin->SetTextString(aStr);
2080 : : }
2081 : :
2082 [ # # ]: 0 : UpdateAdjust( cTyped );
2083 : :
2084 [ # # ]: 0 : if ( bAutoComplete )
2085 [ # # ]: 0 : GetColData();
2086 : :
2087 [ # # ][ # # ]: 0 : if ( ( aStr.GetChar(0) == '=' || aStr.GetChar(0) == '+' || aStr.GetChar(0) == '-' ) &&
[ # # ][ # # ]
[ # # ][ # # ]
2088 : 0 : !cTyped && !bCreatingFuncView )
2089 [ # # ]: 0 : InitRangeFinder(aStr); // Formel wird editiert -> RangeFinder
2090 : :
2091 [ # # ]: 0 : bNewTable = true; // -> PostEditView-Aufruf
2092 : 0 : }
2093 : : }
2094 : :
2095 [ # # ][ # # ]: 0 : if (!bProtected && pInputWin)
2096 : 0 : pInputWin->SetOkCancelMode();
2097 : :
2098 : 0 : return bNewTable;
2099 : : }
2100 : :
2101 : 0 : void lcl_SetTopSelection( EditView* pEditView, ESelection& rSel )
2102 : : {
2103 : : OSL_ENSURE( rSel.nStartPara==0 && rSel.nEndPara==0, "SetTopSelection: Para != 0" );
2104 : :
2105 [ # # ]: 0 : EditEngine* pEngine = pEditView->GetEditEngine();
2106 [ # # ]: 0 : sal_uInt16 nCount = pEngine->GetParagraphCount();
2107 [ # # ]: 0 : if (nCount > 1)
2108 : : {
2109 [ # # ]: 0 : xub_StrLen nParLen = pEngine->GetTextLen(rSel.nStartPara);
2110 [ # # ][ # # ]: 0 : while (rSel.nStartPos > nParLen && rSel.nStartPara+1 < nCount)
[ # # ]
2111 : : {
2112 : 0 : rSel.nStartPos -= nParLen + 1; // incl. Leerzeichen vom Umbruch
2113 [ # # ]: 0 : nParLen = pEngine->GetTextLen(++rSel.nStartPara);
2114 : : }
2115 : :
2116 [ # # ]: 0 : nParLen = pEngine->GetTextLen(rSel.nEndPara);
2117 [ # # ][ # # ]: 0 : while (rSel.nEndPos > nParLen && rSel.nEndPara+1 < nCount)
[ # # ]
2118 : : {
2119 : 0 : rSel.nEndPos -= nParLen + 1; // incl. Leerzeichen vom Umbruch
2120 [ # # ]: 0 : nParLen = pEngine->GetTextLen(++rSel.nEndPara);
2121 : : }
2122 : : }
2123 : :
2124 [ # # ]: 0 : ESelection aSel = pEditView->GetSelection();
2125 : :
2126 [ # # ][ # # ]: 0 : if ( rSel.nStartPara != aSel.nStartPara || rSel.nEndPara != aSel.nEndPara
[ # # ][ # # ]
2127 : : || rSel.nStartPos != aSel.nStartPos || rSel.nEndPos != aSel.nEndPos )
2128 [ # # ]: 0 : pEditView->SetSelection( rSel );
2129 : 0 : }
2130 : :
2131 : 0 : void ScInputHandler::SyncViews( EditView* pSourceView )
2132 : : {
2133 : 0 : ESelection aSel;
2134 : :
2135 [ # # ]: 0 : if (pSourceView)
2136 : : {
2137 [ # # ]: 0 : aSel = pSourceView->GetSelection();
2138 [ # # ][ # # ]: 0 : if (pTopView && pTopView != pSourceView)
2139 [ # # ]: 0 : pTopView->SetSelection( aSel );
2140 [ # # ][ # # ]: 0 : if (pTableView && pTableView != pSourceView)
2141 [ # # ]: 0 : lcl_SetTopSelection( pTableView, aSel );
2142 : : }
2143 : : // Only sync selection from topView if we are actually editiing there
2144 [ # # ][ # # ]: 0 : else if (pTopView && pTableView)
2145 : : {
2146 [ # # ]: 0 : aSel = pTopView->GetSelection();
2147 [ # # ]: 0 : lcl_SetTopSelection( pTableView, aSel );
2148 : : }
2149 : 0 : }
2150 : :
2151 : 89 : IMPL_LINK_NOARG(ScInputHandler, ModifyHdl)
2152 : : {
2153 [ - + ][ # # ]: 89 : if ( !bInOwnChange && ( eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE ) &&
[ # # ]
[ # # # # ]
[ # # ][ - + ]
2154 : 0 : pEngine && pEngine->GetUpdateMode() && pInputWin )
2155 : : {
2156 : : // update input line from ModifyHdl for changes that are not
2157 : : // wrapped by DataChanging/DataChanged calls (like Drag&Drop)
2158 : :
2159 : 0 : rtl::OUString aText;
2160 [ # # ]: 0 : if ( pInputWin->IsMultiLineInput() )
2161 [ # # ][ # # ]: 0 : aText = ScEditUtil::GetMultilineString(*pEngine);
[ # # ]
2162 : : else
2163 [ # # ][ # # ]: 0 : aText = GetEditText(pEngine);
[ # # ][ # # ]
2164 [ # # ]: 0 : lcl_RemoveTabs(aText);
2165 [ # # ][ # # ]: 0 : pInputWin->SetTextString(aText);
[ # # ]
2166 : : }
2167 : 89 : return 0;
2168 : : }
2169 : :
2170 : 0 : bool ScInputHandler::DataChanging( sal_Unicode cTyped, bool bFromCommand ) // return true = new view created
2171 : : {
2172 [ # # ]: 0 : if (pActiveViewSh)
2173 : 0 : pActiveViewSh->GetViewData()->SetPasteMode( SC_PASTE_NONE );
2174 : 0 : bInOwnChange = true; // disable ModifyHdl (reset in DataChanged)
2175 : :
2176 [ # # ]: 0 : if ( eMode == SC_INPUT_NONE )
2177 : 0 : return StartTable( cTyped, bFromCommand, false );
2178 : : else
2179 : 0 : return false;
2180 : : }
2181 : :
2182 : 0 : void ScInputHandler::DataChanged( bool bFromTopNotify )
2183 : : {
2184 : 0 : ImplCreateEditEngine();
2185 : :
2186 [ # # ]: 0 : if (eMode==SC_INPUT_NONE)
2187 : 0 : eMode = SC_INPUT_TYPE;
2188 : :
2189 [ # # ][ # # ]: 0 : if ( eMode == SC_INPUT_TOP && pTopView && !bFromTopNotify )
[ # # ]
2190 : : {
2191 : : // table EditEngine is formatted below, input line needs formatting after paste
2192 : : // #i20282# not when called from the input line's modify handler
2193 : 0 : pTopView->GetEditEngine()->QuickFormatDoc( true );
2194 : :
2195 : : // #i23720# QuickFormatDoc hides the cursor, but can't show it again because it
2196 : : // can't safely access the EditEngine's current view, so the cursor has to be
2197 : : // shown again here.
2198 : 0 : pTopView->ShowCursor();
2199 : : }
2200 : :
2201 : 0 : bModified = true;
2202 : 0 : bSelIsRef = false;
2203 : :
2204 [ # # ][ # # ]: 0 : if ( pRangeFindList && !bInRangeUpdate )
2205 : 0 : RemoveRangeFinder(); // Attribute und Markierung loeschen
2206 : :
2207 : 0 : UpdateParenthesis(); // Hervorhebung der Klammern neu
2208 : :
2209 [ # # ][ # # ]: 0 : if (eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE)
2210 : : {
2211 : 0 : rtl::OUString aText;
2212 [ # # ][ # # ]: 0 : if ( pInputWin && pInputWin->IsMultiLineInput() )
[ # # ]
2213 [ # # ][ # # ]: 0 : aText = ScEditUtil::GetMultilineString(*pEngine);
[ # # ]
2214 : : else
2215 [ # # ][ # # ]: 0 : aText = GetEditText(pEngine);
[ # # ][ # # ]
2216 [ # # ]: 0 : lcl_RemoveTabs(aText);
2217 : :
2218 [ # # ]: 0 : if ( pInputWin )
2219 [ # # ][ # # ]: 0 : pInputWin->SetTextString( aText );
[ # # ]
2220 : : }
2221 : :
2222 : : // wenn der Cursor vor dem Absatzende steht, werden Teile rechts rausgeschoben
2223 : : // (unabhaengig von eMode) -> View anpassen!
2224 : : // wenn der Cursor am Ende steht, reicht der Status-Handler an der ViewData
2225 : :
2226 : : // first make sure the status handler is called now if the cursor
2227 : : // is outside the visible area
2228 : 0 : pEngine->QuickFormatDoc();
2229 : :
2230 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
2231 [ # # ][ # # ]: 0 : if (pActiveView && pActiveViewSh)
2232 : : {
2233 : 0 : ScViewData* pViewData = pActiveViewSh->GetViewData();
2234 : :
2235 : 0 : bool bNeedGrow = ( nEditAdjust != SVX_ADJUST_LEFT ); // rechtsbuendig immer
2236 [ # # ]: 0 : if (!bNeedGrow)
2237 : : {
2238 : : // Cursor vor dem Ende?
2239 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
2240 : 0 : aSel.Adjust();
2241 [ # # ]: 0 : bNeedGrow = ( aSel.nEndPos != pEngine->GetTextLen(aSel.nEndPara) );
2242 : : }
2243 [ # # ]: 0 : if (!bNeedGrow)
2244 : : {
2245 : 0 : bNeedGrow = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
2246 : : }
2247 [ # # ]: 0 : if (bNeedGrow)
2248 : : {
2249 : : // adjust inplace view
2250 : 0 : pViewData->EditGrowY();
2251 : 0 : pViewData->EditGrowX();
2252 : : }
2253 : : }
2254 : :
2255 : 0 : UpdateFormulaMode();
2256 : 0 : bTextValid = false; // Aenderungen sind nur in der Edit-Engine
2257 : 0 : bInOwnChange = false;
2258 : 0 : }
2259 : :
2260 : 0 : void ScInputHandler::UpdateFormulaMode()
2261 : : {
2262 : 0 : SfxApplication* pSfxApp = SFX_APP();
2263 : :
2264 [ # # # # : 0 : if ( pEngine->GetParagraphCount() == 1 &&
# # # # ]
[ # # ][ # # ]
[ # # ]
2265 [ # # ][ # # ]: 0 : ( pEngine->GetText((sal_uInt16)0).GetChar(0) == '=' ||
[ # # ]
2266 [ # # ][ # # ]: 0 : pEngine->GetText((sal_uInt16)0).GetChar(0) == '+' ||
[ # # ][ # # ]
2267 [ # # ][ # # ]: 0 : pEngine->GetText((sal_uInt16)0).GetChar(0) == '-' ) &&
[ # # ][ # # ]
2268 : 0 : !bProtected )
2269 : : {
2270 [ # # ]: 0 : if (!bFormulaMode)
2271 : : {
2272 : 0 : bFormulaMode = true;
2273 : 0 : pRefViewSh = pActiveViewSh;
2274 [ # # ]: 0 : pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2275 : 0 : SC_MOD()->SetRefInputHdl(this);
2276 [ # # ]: 0 : if (pInputWin)
2277 : 0 : pInputWin->SetFormulaMode(true);
2278 : :
2279 [ # # ]: 0 : if ( bAutoComplete )
2280 : 0 : GetFormulaData();
2281 : :
2282 : 0 : UpdateParenthesis();
2283 : 0 : UpdateAutoCorrFlag();
2284 : : }
2285 : : }
2286 : : else // ausschalten
2287 : : {
2288 [ # # ]: 0 : if (bFormulaMode)
2289 : : {
2290 : 0 : ShowRefFrame();
2291 : 0 : bFormulaMode = false;
2292 : 0 : pRefViewSh = NULL;
2293 [ # # ]: 0 : pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2294 : 0 : SC_MOD()->SetRefInputHdl(NULL);
2295 [ # # ]: 0 : if (pInputWin)
2296 : 0 : pInputWin->SetFormulaMode(false);
2297 : 0 : UpdateAutoCorrFlag();
2298 : : }
2299 : : }
2300 : 0 : }
2301 : :
2302 : 0 : void ScInputHandler::ShowRefFrame()
2303 : : {
2304 : : // Modifying pActiveViewSh here would interfere with the bInEnterHandler / bRepeat
2305 : : // checks in NotifyChange, and lead to keeping the wrong value in pActiveViewSh.
2306 : : // A local variable is used instead.
2307 [ # # ][ # # ]: 0 : ScTabViewShell* pVisibleSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
2308 [ # # ][ # # ]: 0 : if ( pRefViewSh && pRefViewSh != pVisibleSh )
2309 : : {
2310 : 0 : bool bFound = false;
2311 : 0 : SfxViewFrame* pRefFrame = pRefViewSh->GetViewFrame();
2312 : 0 : SfxViewFrame* pOneFrame = SfxViewFrame::GetFirst();
2313 [ # # ][ # # ]: 0 : while ( pOneFrame && !bFound )
[ # # ]
2314 : : {
2315 [ # # ]: 0 : if ( pOneFrame == pRefFrame )
2316 : 0 : bFound = true;
2317 : 0 : pOneFrame = SfxViewFrame::GetNext( *pOneFrame );
2318 : : }
2319 : :
2320 [ # # ]: 0 : if (bFound)
2321 : : {
2322 : : // Hier wird sich darauf verlassen, dass Activate synchron funktioniert
2323 : : // (dabei wird pActiveViewSh umgesetzt)
2324 : :
2325 : 0 : pRefViewSh->SetActive(); // Appear und SetViewFrame
2326 : :
2327 : : // pLastState wird im NotifyChange aus dem Activate richtig gesetzt
2328 : : }
2329 : : else
2330 : : {
2331 : : OSL_FAIL("ViewFrame fuer Referenzeingabe ist nicht mehr da");
2332 : : }
2333 : : }
2334 : 0 : }
2335 : :
2336 : 0 : void ScInputHandler::RemoveSelection()
2337 : : {
2338 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
2339 [ # # ]: 0 : if (!pActiveView)
2340 : 0 : return;
2341 : :
2342 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
2343 : 0 : aSel.nStartPara = aSel.nEndPara;
2344 : 0 : aSel.nStartPos = aSel.nEndPos;
2345 [ # # ]: 0 : if (pTableView)
2346 [ # # ]: 0 : pTableView->SetSelection( aSel );
2347 [ # # ]: 0 : if (pTopView)
2348 [ # # ]: 0 : pTopView->SetSelection( aSel );
2349 : : }
2350 : :
2351 : 0 : void ScInputHandler::InvalidateAttribs()
2352 : : {
2353 : 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
2354 [ # # ]: 0 : if (pViewFrm)
2355 : : {
2356 : 0 : SfxBindings& rBindings = pViewFrm->GetBindings();
2357 : :
2358 : 0 : rBindings.Invalidate( SID_ATTR_CHAR_FONT );
2359 : 0 : rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
2360 : 0 : rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
2361 : :
2362 : 0 : rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
2363 : 0 : rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
2364 : 0 : rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
2365 : 0 : rBindings.Invalidate( SID_ULINE_VAL_NONE );
2366 : 0 : rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
2367 : 0 : rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
2368 : 0 : rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
2369 : :
2370 : 0 : rBindings.Invalidate( SID_HYPERLINK_GETLINK );
2371 : : }
2372 : 0 : }
2373 : :
2374 : : //
2375 : : // --------------- public Methoden --------------------------------------------
2376 : : //
2377 : :
2378 : 0 : void ScInputHandler::SetMode( ScInputMode eNewMode )
2379 : : {
2380 [ # # ]: 0 : if ( eMode == eNewMode )
2381 : 0 : return;
2382 : :
2383 : 0 : ImplCreateEditEngine();
2384 : :
2385 [ # # ]: 0 : if (bProtected)
2386 : : {
2387 : 0 : eMode = SC_INPUT_NONE;
2388 : 0 : StopInputWinEngine( true );
2389 [ # # ]: 0 : if (pActiveViewSh)
2390 : 0 : pActiveViewSh->GetActiveWin()->GrabFocus();
2391 : 0 : return;
2392 : : }
2393 : :
2394 [ # # ][ # # ]: 0 : if (eNewMode != SC_INPUT_NONE && pActiveViewSh)
2395 : : // Disable paste mode when edit mode starts.
2396 : 0 : pActiveViewSh->GetViewData()->SetPasteMode( SC_PASTE_NONE );
2397 : :
2398 : 0 : bInOwnChange = true; // disable ModifyHdl (reset below)
2399 : :
2400 : 0 : ScInputMode eOldMode = eMode;
2401 : 0 : eMode = eNewMode;
2402 [ # # ][ # # ]: 0 : if (eOldMode == SC_INPUT_TOP && eNewMode != eOldMode)
2403 : 0 : StopInputWinEngine( false );
2404 : :
2405 [ # # ][ # # ]: 0 : if (eMode==SC_INPUT_TOP || eMode==SC_INPUT_TABLE)
2406 : : {
2407 [ # # ]: 0 : if (eOldMode == SC_INPUT_NONE) // not when switching between modes
2408 : : {
2409 [ # # ]: 0 : if (StartTable(0, false, eMode == SC_INPUT_TABLE))
2410 : : {
2411 [ # # ]: 0 : if (pActiveViewSh)
2412 : 0 : pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
2413 : : }
2414 : : }
2415 : :
2416 : 0 : sal_uInt16 nPara = pEngine->GetParagraphCount()-1;
2417 : 0 : xub_StrLen nLen = pEngine->GetText(nPara).Len();
2418 : 0 : sal_uInt16 nCount = pEngine->GetViewCount();
2419 : :
2420 [ # # ]: 0 : for (sal_uInt16 i=0; i<nCount; i++)
2421 : : {
2422 [ # # ][ # # ]: 0 : if ( eMode == SC_INPUT_TABLE && eOldMode == SC_INPUT_TOP )
2423 : : {
2424 : : // Selektion bleibt
2425 : : }
2426 : : else
2427 : : {
2428 : : pEngine->GetView(i)->
2429 [ # # ][ # # ]: 0 : SetSelection( ESelection( nPara, nLen, nPara, nLen ) );
2430 : : }
2431 : 0 : pEngine->GetView(i)->ShowCursor(false);
2432 : : }
2433 : : }
2434 : :
2435 : 0 : UpdateActiveView();
2436 [ # # ][ # # ]: 0 : if (eMode==SC_INPUT_TABLE || eMode==SC_INPUT_TYPE)
2437 : : {
2438 [ # # ]: 0 : if (pTableView)
2439 : 0 : pTableView->SetEditEngineUpdateMode(true);
2440 : : }
2441 : : else
2442 : : {
2443 [ # # ]: 0 : if (pTopView)
2444 : 0 : pTopView->SetEditEngineUpdateMode(true);
2445 : : }
2446 : :
2447 [ # # ]: 0 : if (eNewMode != eOldMode)
2448 : 0 : UpdateFormulaMode();
2449 : :
2450 : 0 : bInOwnChange = false;
2451 : : }
2452 : :
2453 : : //----------------------------------------------------------------------------------------
2454 : :
2455 : : // lcl_IsNumber - true, wenn nur Ziffern (dann keine Autokorrektur)
2456 : :
2457 : 0 : bool lcl_IsNumber(const String& rString)
2458 : : {
2459 : 0 : xub_StrLen nLen = rString.Len();
2460 [ # # ]: 0 : for (xub_StrLen i=0; i<nLen; i++)
2461 : : {
2462 : 0 : sal_Unicode c = rString.GetChar(i);
2463 [ # # ][ # # ]: 0 : if ( c < '0' || c > '9' )
2464 : 0 : return false;
2465 : : }
2466 : 0 : return true;
2467 : : }
2468 : :
2469 : 0 : void lcl_SelectionToEnd( EditView* pView )
2470 : : {
2471 [ # # ]: 0 : if ( pView )
2472 : : {
2473 [ # # ]: 0 : EditEngine* pEngine = pView->GetEditEngine();
2474 [ # # ]: 0 : sal_uInt16 nParCnt = pEngine->GetParagraphCount();
2475 [ # # ]: 0 : if ( nParCnt == 0 )
2476 : 0 : nParCnt = 1;
2477 [ # # ]: 0 : ESelection aSel( nParCnt-1, pEngine->GetTextLen(nParCnt-1) ); // empty selection, cursor at the end
2478 [ # # ]: 0 : pView->SetSelection( aSel );
2479 : : }
2480 : 0 : }
2481 : :
2482 : 519 : void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
2483 : : {
2484 : : // Bei Makro-Aufrufen fuer Gueltigkeit kann Tod und Teufel passieren,
2485 : : // darum dafuer sorgen, dass EnterHandler nicht verschachtelt gerufen wird:
2486 : :
2487 [ + - ]: 1038 : if (bInEnterHandler) return;
2488 : 519 : bInEnterHandler = true;
2489 : 519 : bInOwnChange = true; // disable ModifyHdl (reset below)
2490 : :
2491 [ + - ]: 519 : ImplCreateEditEngine();
2492 : :
2493 : 519 : bool bMatrix = ( nBlockMode == SC_ENTER_MATRIX );
2494 : :
2495 [ + - ]: 519 : SfxApplication* pSfxApp = SFX_APP();
2496 : 519 : EditTextObject* pObject = NULL;
2497 : 519 : ScPatternAttr* pCellAttrs = NULL;
2498 : 519 : bool bAttrib = false; // Formatierung vorhanden ?
2499 : 519 : bool bForget = false; // wegen Gueltigkeit streichen ?
2500 : :
2501 [ + - ][ + - ]: 519 : rtl::OUString aString = GetEditText(pEngine);
[ + - ][ + - ]
2502 [ - + ]: 519 : EditView* pActiveView = pTopView ? pTopView : pTableView;
2503 [ - + ][ # # ]: 519 : if (bModified && pActiveView && !aString.isEmpty() && !lcl_IsNumber(aString))
[ # # ][ # # ]
[ # # ][ - + ]
[ # # ]
[ - + # # ]
2504 : : {
2505 [ # # ][ # # ]: 0 : if (pColumnData && miAutoPosColumn != pColumnData->end())
[ # # ][ # # ]
2506 : : {
2507 : : // #i47125# If AutoInput appended something, do the final AutoCorrect
2508 : : // with the cursor at the end of the input.
2509 : :
2510 [ # # ]: 0 : lcl_SelectionToEnd(pTopView);
2511 [ # # ]: 0 : lcl_SelectionToEnd(pTableView);
2512 : : }
2513 : :
2514 [ # # ]: 0 : Window* pFrameWin = pActiveViewSh ? pActiveViewSh->GetFrameWin() : NULL;
2515 : :
2516 [ # # ]: 0 : if (pTopView)
2517 [ # # ]: 0 : pTopView->CompleteAutoCorrect(); // CompleteAutoCorrect fuer beide Views
2518 [ # # ]: 0 : if (pTableView)
2519 [ # # ]: 0 : pTableView->CompleteAutoCorrect(pFrameWin);
2520 [ # # ][ # # ]: 0 : aString = GetEditText(pEngine);
[ # # ][ # # ]
2521 : : }
2522 [ + - ]: 519 : lcl_RemoveTabs(aString);
2523 : :
2524 : : // Test, ob zulaessig (immer mit einfachem String)
2525 : :
2526 [ - + ][ # # ]: 519 : if ( bModified && nValidation && pActiveViewSh )
[ # # ]
2527 : : {
2528 [ # # ]: 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2529 [ # # ]: 0 : const ScValidationData* pData = pDoc->GetValidationEntry( nValidation );
2530 [ # # ][ # # ]: 0 : if (pData && pData->HasErrMsg())
[ # # ]
2531 : : {
2532 : : // #i67990# don't use pLastPattern in EnterHandler
2533 [ # # ]: 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
2534 [ # # ][ # # ]: 0 : bool bOk = pData->IsDataValid( aString, *pPattern, aCursorPos );
[ # # ]
2535 : :
2536 [ # # ]: 0 : if (!bOk)
2537 : : {
2538 [ # # ]: 0 : if ( pActiveViewSh ) // falls aus MouseButtonDown gekommen
2539 [ # # ]: 0 : pActiveViewSh->StopMarking(); // (die InfoBox verschluckt das MouseButtonUp)
2540 : :
2541 : : //! es gibt noch Probleme, wenn die Eingabe durch Aktivieren einer
2542 : : //! anderen View ausgeloest wurde
2543 : :
2544 [ # # ]: 0 : Window* pParent = Application::GetDefDialogParent();
2545 [ # # ][ # # ]: 0 : if ( pData->DoError( pParent, aString, aCursorPos ) )
[ # # ][ # # ]
2546 : 0 : bForget = true; // Eingabe nicht uebernehmen
2547 : : }
2548 : : }
2549 : : }
2550 : :
2551 : : // check for input into DataPilot table
2552 : :
2553 [ - + ][ # # ]: 519 : if ( bModified && pActiveViewSh && !bForget )
[ # # ]
2554 : : {
2555 [ # # ]: 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2556 [ # # ]: 0 : ScDPObject* pDPObj = pDoc->GetDPAtCursor( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
2557 [ # # ]: 0 : if ( pDPObj )
2558 : : {
2559 : : // any input within the DataPilot table is either a valid renaming
2560 : : // or an invalid action - normal cell input is always aborted
2561 : :
2562 [ # # ]: 0 : pActiveViewSh->DataPilotInput( aCursorPos, aString );
2563 : 0 : bForget = true;
2564 : : }
2565 : : }
2566 : :
2567 [ + - ]: 519 : pEngine->CompleteOnlineSpelling();
2568 [ + - ][ + - ]: 519 : bool bSpellErrors = !bFormulaMode && pEngine->HasOnlineSpellErrors();
[ - + ]
2569 [ - + ]: 519 : if ( bSpellErrors )
2570 : : {
2571 : : // #i3820# If the spell checker flags numerical input as error,
2572 : : // it still has to be treated as number, not EditEngine object.
2573 : :
2574 [ # # ]: 0 : if ( pActiveViewSh )
2575 : : {
2576 [ # # ]: 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2577 : : // #i67990# don't use pLastPattern in EnterHandler
2578 [ # # ]: 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
2579 [ # # ]: 0 : if (pPattern)
2580 : : {
2581 [ # # ]: 0 : SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
2582 : : // without conditional format, as in ScColumn::SetString
2583 [ # # ]: 0 : sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter );
2584 : : double nVal;
2585 [ # # ][ # # ]: 0 : if ( pFormatter->IsNumberFormat( aString, nFormat, nVal ) )
[ # # ][ # # ]
2586 : : {
2587 : 0 : bSpellErrors = false; // ignore the spelling errors
2588 : : }
2589 : : }
2590 : : }
2591 : : }
2592 : :
2593 : : // After RemoveAdjust, the EditView must not be repainted (has wrong font size etc).
2594 : : // SetUpdateMode must come after CompleteOnlineSpelling.
2595 : : // The view is hidden in any case below (Broadcast).
2596 [ + - ]: 519 : pEngine->SetUpdateMode( false );
2597 : :
2598 [ - + ][ # # ]: 519 : if ( bModified && !bForget ) // was wird eingeben (Text/Objekt) ?
2599 : : {
2600 [ # # ]: 0 : sal_uInt16 nParCnt = pEngine->GetParagraphCount();
2601 [ # # ]: 0 : if ( nParCnt == 0 )
2602 : 0 : nParCnt = 1;
2603 : :
2604 : 0 : bool bUniformAttribs = true;
2605 [ # # ][ # # ]: 0 : SfxItemSet aPara1Attribs = pEngine->GetAttribs(0, 0, pEngine->GetTextLen(0));
2606 [ # # ]: 0 : for (sal_uInt16 nPara = 1; nPara < nParCnt; ++nPara)
2607 : : {
2608 [ # # ][ # # ]: 0 : SfxItemSet aPara2Attribs = pEngine->GetAttribs(nPara, 0, pEngine->GetTextLen(nPara));
2609 [ # # ][ # # ]: 0 : if (!(aPara1Attribs == aPara2Attribs))
2610 : : {
2611 : : // paragraph format different from that of the 1st paragraph.
2612 : 0 : bUniformAttribs = false;
2613 : : break;
2614 : : }
2615 [ # # ][ # # ]: 0 : }
2616 : :
2617 [ # # ]: 0 : ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
2618 [ # # ]: 0 : SfxItemSet aOldAttribs = pEngine->GetAttribs( aSel );
2619 : 0 : const SfxPoolItem* pItem = NULL;
2620 : :
2621 : : // find common (cell) attributes before RemoveAdjust
2622 : :
2623 [ # # ][ # # ]: 0 : if ( pActiveViewSh && bUniformAttribs )
2624 : : {
2625 : 0 : SfxItemSet* pCommonAttrs = NULL;
2626 [ # # ]: 0 : for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END; nId++)
2627 : : {
2628 [ # # ]: 0 : SfxItemState eState = aOldAttribs.GetItemState( nId, false, &pItem );
2629 [ # # ][ # # ]: 0 : if ( eState == SFX_ITEM_SET &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2630 : : nId != EE_CHAR_ESCAPEMENT && nId != EE_CHAR_PAIRKERNING &&
2631 : : nId != EE_CHAR_KERNING && nId != EE_CHAR_XMLATTRIBS &&
2632 [ # # ][ # # ]: 0 : *pItem != pEditDefaults->Get(nId) )
2633 : : {
2634 [ # # ]: 0 : if ( !pCommonAttrs )
2635 [ # # ][ # # ]: 0 : pCommonAttrs = new SfxItemSet( pEngine->GetEmptyItemSet() );
[ # # ]
2636 [ # # ]: 0 : pCommonAttrs->Put( *pItem );
2637 : : }
2638 : : }
2639 : :
2640 [ # # ]: 0 : if ( pCommonAttrs )
2641 : : {
2642 [ # # ]: 0 : ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2643 [ # # ][ # # ]: 0 : pCellAttrs = new ScPatternAttr( pDoc->GetPool() );
[ # # ]
2644 [ # # ]: 0 : pCellAttrs->GetFromEditItemSet( pCommonAttrs );
2645 [ # # ][ # # ]: 0 : delete pCommonAttrs;
2646 : : }
2647 : : }
2648 : :
2649 : : // clear ParaAttribs (including adjustment)
2650 : :
2651 [ # # ]: 0 : RemoveAdjust();
2652 : :
2653 : : // check if EditObject is needed
2654 : :
2655 [ # # ][ # # ]: 0 : if ( bSpellErrors || nParCnt > 1 )
2656 : 0 : bAttrib = true;
2657 : : else
2658 : : {
2659 [ # # ][ # # ]: 0 : for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bAttrib; nId++)
[ # # ]
2660 : : {
2661 [ # # ]: 0 : SfxItemState eState = aOldAttribs.GetItemState( nId, false, &pItem );
2662 [ # # ]: 0 : if (eState == SFX_ITEM_DONTCARE)
2663 : 0 : bAttrib = true;
2664 [ # # ]: 0 : else if (eState == SFX_ITEM_SET)
2665 : : {
2666 : : // keep same items in EditEngine as in ScEditAttrTester
2667 [ # # ][ # # ]: 0 : if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
[ # # ][ # # ]
2668 : : nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
2669 : : {
2670 [ # # ][ # # ]: 0 : if ( *pItem != pEditDefaults->Get(nId) )
[ # # ]
2671 : 0 : bAttrib = true;
2672 : : }
2673 : : }
2674 : : }
2675 : :
2676 : : // Feldbefehle enthalten?
2677 : :
2678 [ # # ]: 0 : SfxItemState eFieldState = aOldAttribs.GetItemState( EE_FEATURE_FIELD, false );
2679 [ # # ][ # # ]: 0 : if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
2680 : 0 : bAttrib = true;
2681 : :
2682 : : // not converted characters?
2683 : :
2684 [ # # ]: 0 : SfxItemState eConvState = aOldAttribs.GetItemState( EE_FEATURE_NOTCONV, false );
2685 [ # # ][ # # ]: 0 : if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
2686 : 0 : bAttrib = true;
2687 : :
2688 : : // Formeln immer als Formeln erkennen (#38309#)
2689 : : // (der Test vorher ist trotzdem noetig wegen Zell-Attributen)
2690 : : }
2691 : :
2692 [ # # ]: 0 : if (bMatrix)
2693 : 0 : bAttrib = false;
2694 : :
2695 [ # # ]: 0 : if (bAttrib)
2696 : : {
2697 [ # # ]: 0 : sal_uLong nCtrl = pEngine->GetControlWord();
2698 [ # # ]: 0 : sal_uLong nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
2699 [ # # ]: 0 : if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
2700 [ # # ]: 0 : pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
2701 [ # # ]: 0 : pObject = pEngine->CreateTextObject();
2702 : : }
2703 [ # # ]: 0 : else if (bAutoComplete) // Gross-/Kleinschreibung anpassen
2704 : : {
2705 : : // Perform case-matching only when the typed text is partial.
2706 [ # # ][ # # ]: 0 : if (pColumnData && aAutoSearch.getLength() < aString.getLength())
[ # # ]
2707 [ # # ]: 0 : aString = getExactMatch(*pColumnData, aString);
2708 [ # # ][ # # ]: 0 : }
2709 : : }
2710 : :
2711 : : // don't rely on ShowRefFrame switching the active view synchronously
2712 : : // execute the function directly on the correct view's bindings instead
2713 : : // pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
2714 [ - + ]: 519 : ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;
2715 : :
2716 [ - + ]: 519 : if (bFormulaMode)
2717 : : {
2718 [ # # ]: 0 : ShowRefFrame();
2719 : :
2720 [ # # ]: 0 : if (pExecuteSh)
2721 : : {
2722 [ # # ]: 0 : pExecuteSh->SetTabNo(aCursorPos.Tab());
2723 [ # # ]: 0 : pExecuteSh->ActiveGrabFocus();
2724 : : }
2725 : :
2726 : 0 : bFormulaMode = false;
2727 [ # # ][ # # ]: 0 : pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
[ # # ]
2728 [ # # ][ # # ]: 0 : SC_MOD()->SetRefInputHdl(NULL);
2729 [ # # ]: 0 : if (pInputWin)
2730 [ # # ]: 0 : pInputWin->SetFormulaMode(false);
2731 [ # # ]: 0 : UpdateAutoCorrFlag();
2732 : : }
2733 : 519 : pRefViewSh = NULL; // auch ohne FormulaMode wegen Funktions-AP
2734 [ + - ]: 519 : DeleteRangeFinder();
2735 : 519 : ResetAutoPar();
2736 : :
2737 : 519 : bool bOldMod = bModified;
2738 : :
2739 : 519 : bModified = false;
2740 : 519 : bSelIsRef = false;
2741 : 519 : eMode = SC_INPUT_NONE;
2742 [ + - ]: 519 : StopInputWinEngine(true);
2743 : :
2744 : : // Text input (through number formats) or ApplySelectionPattern modify
2745 : : // the cell's attributes, so pLastPattern is no longer valid
2746 : 519 : pLastPattern = NULL;
2747 : :
2748 [ - + ][ # # ]: 519 : if (bOldMod && !bProtected && !bForget)
[ # # ]
2749 : : {
2750 : : // keine typographische Anfuehrungszeichen in Formeln
2751 : :
2752 [ # # ]: 0 : if (aString.getStr()[0] == '=')
2753 : : {
2754 [ # # ]: 0 : SvxAutoCorrect* pAuto = SvxAutoCorrCfg::Get().GetAutoCorrect();
2755 [ # # ]: 0 : if ( pAuto )
2756 : : {
2757 : 0 : rtl::OUString aReplace(pAuto->GetStartDoubleQuote());
2758 [ # # ]: 0 : if (aReplace.isEmpty())
2759 [ # # ]: 0 : aReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart();
2760 [ # # ]: 0 : if (!aReplace.equalsAsciiL("\"", 1))
2761 : : aString = aString.replaceAll(
2762 : : aReplace,
2763 [ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"")));
2764 : :
2765 : 0 : aReplace = rtl::OUString(pAuto->GetEndDoubleQuote());
2766 [ # # ]: 0 : if (aReplace.isEmpty())
2767 [ # # ]: 0 : aReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd();
2768 [ # # ]: 0 : if (!aReplace.equalsAsciiL("\"", 1))
2769 : : aString = aString.replaceAll(
2770 : : aReplace,
2771 [ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"")));
2772 : :
2773 : 0 : aReplace = rtl::OUString(pAuto->GetStartSingleQuote());
2774 [ # # ]: 0 : if (aReplace.isEmpty())
2775 [ # # ]: 0 : aReplace = ScGlobal::pLocaleData->getQuotationMarkStart();
2776 [ # # ]: 0 : if (!aReplace.equalsAsciiL("'", 1))
2777 : : aString = aString.replaceAll(
2778 : : aReplace,
2779 [ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'")));
2780 : :
2781 : 0 : aReplace = rtl::OUString(pAuto->GetEndSingleQuote());
2782 [ # # ]: 0 : if (aReplace.isEmpty())
2783 [ # # ]: 0 : aReplace = ScGlobal::pLocaleData->getQuotationMarkEnd();
2784 [ # # ]: 0 : if (!aReplace.equalsAsciiL("'", 1))
2785 : : aString = aString.replaceAll(
2786 : : aReplace,
2787 [ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'")));
2788 : : }
2789 : : }
2790 : :
2791 [ # # ][ # # ]: 0 : pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW_NOPAINT ) );
[ # # ]
2792 : :
2793 [ # # ]: 0 : if ( pExecuteSh )
2794 : : {
2795 : 0 : SfxBindings& rBindings = pExecuteSh->GetViewFrame()->GetBindings();
2796 : :
2797 : 0 : sal_uInt16 nId = FID_INPUTLINE_ENTER;
2798 [ # # ]: 0 : if ( nBlockMode == SC_ENTER_BLOCK )
2799 : 0 : nId = FID_INPUTLINE_BLOCK;
2800 [ # # ]: 0 : else if ( nBlockMode == SC_ENTER_MATRIX )
2801 : 0 : nId = FID_INPUTLINE_MATRIX;
2802 : :
2803 : : ScInputStatusItem aItem( FID_INPUTLINE_STATUS,
2804 : : aCursorPos, aCursorPos, aCursorPos,
2805 [ # # ][ # # ]: 0 : aString, pObject );
[ # # ]
2806 : : const SfxPoolItem* aArgs[2];
2807 : 0 : aArgs[0] = &aItem;
2808 : 0 : aArgs[1] = NULL;
2809 [ # # ][ # # ]: 0 : rBindings.Execute( nId, aArgs );
2810 : : }
2811 : :
2812 [ # # ][ # # ]: 0 : delete pLastState; // pLastState enthaelt noch den alten Text
2813 : 0 : pLastState = NULL;
2814 : : }
2815 : : else
2816 [ + - ][ + - ]: 519 : pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
[ + - ]
2817 : :
2818 [ - + ][ # # ]: 519 : if ( bOldMod && pExecuteSh && pCellAttrs && !bForget )
[ # # ][ # # ]
2819 : : {
2820 : : // mit Eingabe zusammenfassen ?
2821 [ # # ]: 0 : pExecuteSh->ApplySelectionPattern( *pCellAttrs, true, true );
2822 [ # # ]: 0 : pExecuteSh->AdjustBlockHeight();
2823 : : }
2824 : :
2825 [ - + ][ # # ]: 519 : delete pCellAttrs;
2826 [ - + ][ # # ]: 519 : delete pObject;
2827 : :
2828 [ + - ]: 519 : HideTip();
2829 [ + - ]: 519 : HideTipBelow();
2830 : :
2831 : 519 : nFormSelStart = nFormSelEnd = 0;
2832 : 519 : aFormText = rtl::OUString();
2833 : :
2834 : 519 : bInOwnChange = false;
2835 : 519 : bInEnterHandler = false;
2836 : : }
2837 : :
2838 : 0 : void ScInputHandler::CancelHandler()
2839 : : {
2840 : 0 : bInOwnChange = true; // disable ModifyHdl (reset below)
2841 : :
2842 : 0 : ImplCreateEditEngine();
2843 : :
2844 : 0 : bModified = false;
2845 : :
2846 : : // don't rely on ShowRefFrame switching the active view synchronously
2847 : : // execute the function directly on the correct view's bindings instead
2848 : : // pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
2849 [ # # ]: 0 : ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;
2850 : :
2851 [ # # ]: 0 : if (bFormulaMode)
2852 : : {
2853 : 0 : ShowRefFrame();
2854 [ # # ]: 0 : if (pExecuteSh)
2855 : : {
2856 : 0 : pExecuteSh->SetTabNo(aCursorPos.Tab());
2857 : 0 : pExecuteSh->ActiveGrabFocus();
2858 : : }
2859 : 0 : bFormulaMode = false;
2860 [ # # ][ # # ]: 0 : SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2861 : 0 : SC_MOD()->SetRefInputHdl(NULL);
2862 [ # # ]: 0 : if (pInputWin)
2863 : 0 : pInputWin->SetFormulaMode(false);
2864 : 0 : UpdateAutoCorrFlag();
2865 : : }
2866 : 0 : pRefViewSh = NULL; // auch ohne FormulaMode wegen Funktions-AP
2867 : 0 : DeleteRangeFinder();
2868 : 0 : ResetAutoPar();
2869 : :
2870 : 0 : eMode = SC_INPUT_NONE;
2871 : 0 : StopInputWinEngine( true );
2872 [ # # ]: 0 : if (pExecuteSh)
2873 : 0 : pExecuteSh->StopEditShell();
2874 : :
2875 : 0 : aCursorPos.Set(MAXCOL+1,0,0); // Flag, dass ungueltig
2876 [ # # ]: 0 : pEngine->SetText(String());
2877 : :
2878 [ # # ][ # # ]: 0 : if ( !pLastState && pExecuteSh )
2879 : 0 : pExecuteSh->UpdateInputHandler( true ); // Status neu holen
2880 : : else
2881 : 0 : NotifyChange( pLastState, true );
2882 : :
2883 : 0 : nFormSelStart = nFormSelEnd = 0;
2884 : 0 : aFormText = rtl::OUString();
2885 : :
2886 : 0 : bInOwnChange = false;
2887 : 0 : }
2888 : :
2889 : 0 : bool ScInputHandler::IsModalMode( SfxObjectShell* pDocSh )
2890 : : {
2891 : : // Referenzen auf unbenanntes Dokument gehen nicht
2892 : :
2893 : : return bFormulaMode && pRefViewSh
2894 : 0 : && pRefViewSh->GetViewData()->GetDocument()->GetDocumentShell() != pDocSh
2895 [ # # ]: 0 : && !pDocSh->HasName();
[ # # # # ]
[ # # ]
2896 : : }
2897 : :
2898 : 0 : void ScInputHandler::AddRefEntry()
2899 : : {
2900 : 0 : const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
2901 : 0 : UpdateActiveView();
2902 [ # # ][ # # ]: 0 : if (!pTableView && !pTopView)
2903 : 0 : return; // z.B. FillMode
2904 : :
2905 : 0 : DataChanging(); // kann nicht neu sein
2906 : :
2907 : 0 : RemoveSelection();
2908 [ # # ]: 0 : if (pTableView)
2909 [ # # ][ # # ]: 0 : pTableView->InsertText( rtl::OUString(cSep), false );
[ # # ]
2910 [ # # ]: 0 : if (pTopView)
2911 [ # # ][ # # ]: 0 : pTopView->InsertText( rtl::OUString(cSep), false );
[ # # ]
2912 : :
2913 : 0 : DataChanged();
2914 : : }
2915 : :
2916 : 0 : void ScInputHandler::SetReference( const ScRange& rRef, ScDocument* pDoc )
2917 : : {
2918 [ # # ]: 0 : HideTip();
2919 : :
2920 : : bool bOtherDoc = ( pRefViewSh &&
2921 [ # # ][ # # ]: 0 : pRefViewSh->GetViewData()->GetDocument() != pDoc );
[ # # ]
2922 [ # # ]: 0 : if (bOtherDoc)
2923 [ # # ]: 0 : if (!pDoc->GetDocumentShell()->HasName())
2924 : : {
2925 : : // Referenzen auf unbenanntes Dokument gehen nicht
2926 : : // (SetReference sollte dann auch nicht gerufen werden)
2927 : :
2928 : : return;
2929 : : }
2930 : :
2931 [ # # ]: 0 : UpdateActiveView();
2932 [ # # ][ # # ]: 0 : if (!pTableView && !pTopView)
2933 : : return; // z.B. FillMode
2934 : :
2935 : : // nie das "=" ueberschreiben!
2936 [ # # ]: 0 : EditView* pActiveView = pTopView ? pTopView : pTableView;
2937 [ # # ]: 0 : ESelection aSel = pActiveView->GetSelection();
2938 : 0 : aSel.Adjust();
2939 [ # # ][ # # ]: 0 : if ( aSel.nStartPara == 0 && aSel.nStartPos == 0 )
2940 : : return;
2941 : :
2942 [ # # ]: 0 : DataChanging(); // kann nicht neu sein
2943 : :
2944 : : // Selektion umdrehen, falls rueckwaerts (noetig ???)
2945 : :
2946 [ # # ]: 0 : if (pTableView)
2947 : : {
2948 [ # # ]: 0 : ESelection aTabSel = pTableView->GetSelection();
2949 [ # # ][ # # ]: 0 : if (aTabSel.nStartPos > aTabSel.nEndPos && aTabSel.nStartPara == aTabSel.nEndPara)
2950 : : {
2951 : 0 : aTabSel.Adjust();
2952 [ # # ]: 0 : pTableView->SetSelection(aTabSel);
2953 : : }
2954 : : }
2955 [ # # ]: 0 : if (pTopView)
2956 : : {
2957 [ # # ]: 0 : ESelection aTopSel = pTopView->GetSelection();
2958 [ # # ][ # # ]: 0 : if (aTopSel.nStartPos > aTopSel.nEndPos && aTopSel.nStartPara == aTopSel.nEndPara)
2959 : : {
2960 : 0 : aTopSel.Adjust();
2961 [ # # ]: 0 : pTopView->SetSelection(aTopSel);
2962 : : }
2963 : : }
2964 : :
2965 : : // String aus Referenz erzeugen
2966 : :
2967 [ # # ]: 0 : String aRefStr;
2968 [ # # ]: 0 : const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
2969 [ # # ]: 0 : if (bOtherDoc)
2970 : : {
2971 : : // Referenz auf anderes Dokument
2972 : :
2973 : : OSL_ENSURE(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");
2974 : :
2975 [ # # ]: 0 : String aTmp;
2976 [ # # ]: 0 : rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails ); // immer 3d
2977 : :
2978 : 0 : SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
2979 : : // #i75893# convert escaped URL of the document to something user friendly
2980 [ # # ][ # # ]: 0 : String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
[ # # ]
2981 : :
2982 [ # # ]: 0 : aRefStr = '\'';
2983 [ # # ]: 0 : aRefStr += aFileName;
2984 [ # # ]: 0 : aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" ));
2985 [ # # ][ # # ]: 0 : aRefStr += aTmp;
[ # # ]
2986 : : }
2987 : : else
2988 : : {
2989 [ # # # # ]: 0 : if ( ( rRef.aStart.Tab() != aCursorPos.Tab() ||
[ # # ][ # # ]
2990 : 0 : rRef.aStart.Tab() != rRef.aEnd.Tab() ) && pDoc )
2991 [ # # ]: 0 : rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );
2992 : : else
2993 [ # # ]: 0 : rRef.Format( aRefStr, SCA_VALID, pDoc, aAddrDetails );
2994 : : }
2995 : :
2996 [ # # ][ # # ]: 0 : if (pTableView || pTopView)
2997 : : {
2998 [ # # ]: 0 : if (pTableView)
2999 [ # # ]: 0 : pTableView->InsertText( aRefStr, true );
3000 [ # # ]: 0 : if (pTopView)
3001 [ # # ]: 0 : pTopView->InsertText( aRefStr, true );
3002 : :
3003 [ # # ]: 0 : DataChanged();
3004 : : }
3005 : :
3006 [ # # ]: 0 : bSelIsRef = true;
3007 : : }
3008 : :
3009 : 0 : void ScInputHandler::InsertFunction( const String& rFuncName, bool bAddPar )
3010 : : {
3011 [ # # ]: 0 : if ( eMode == SC_INPUT_NONE )
3012 : : {
3013 : : OSL_FAIL("InsertFunction, nicht im Eingabemodus");
3014 : : return;
3015 : : }
3016 : :
3017 [ # # ]: 0 : UpdateActiveView();
3018 [ # # ][ # # ]: 0 : if (!pTableView && !pTopView)
3019 : : return; // z.B. FillMode
3020 : :
3021 [ # # ]: 0 : DataChanging(); // kann nicht neu sein
3022 : :
3023 [ # # ]: 0 : String aText = rFuncName;
3024 [ # # ]: 0 : if (bAddPar)
3025 [ # # ]: 0 : aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
3026 : :
3027 [ # # ]: 0 : if (pTableView)
3028 : : {
3029 [ # # ]: 0 : pTableView->InsertText( aText, false );
3030 [ # # ]: 0 : if (bAddPar)
3031 : : {
3032 [ # # ]: 0 : ESelection aSel = pTableView->GetSelection();
3033 : 0 : --aSel.nStartPos;
3034 : 0 : --aSel.nEndPos;
3035 [ # # ]: 0 : pTableView->SetSelection(aSel);
3036 : : }
3037 : : }
3038 [ # # ]: 0 : if (pTopView)
3039 : : {
3040 [ # # ]: 0 : pTopView->InsertText( aText, false );
3041 [ # # ]: 0 : if (bAddPar)
3042 : : {
3043 [ # # ]: 0 : ESelection aSel = pTopView->GetSelection();
3044 : 0 : --aSel.nStartPos;
3045 : 0 : --aSel.nEndPos;
3046 [ # # ]: 0 : pTopView->SetSelection(aSel);
3047 : : }
3048 : : }
3049 : :
3050 [ # # ]: 0 : DataChanged();
3051 : :
3052 [ # # ]: 0 : if (bAddPar)
3053 [ # # ]: 0 : AutoParAdded();
3054 : : }
3055 : :
3056 : 0 : void ScInputHandler::ClearText()
3057 : : {
3058 [ # # ]: 0 : if ( eMode == SC_INPUT_NONE )
3059 : : {
3060 : : OSL_FAIL("ClearText, nicht im Eingabemodus");
3061 : : return;
3062 : : }
3063 : :
3064 [ # # ]: 0 : UpdateActiveView();
3065 [ # # ][ # # ]: 0 : if (!pTableView && !pTopView)
3066 : : return; // z.B. FillMode
3067 : :
3068 [ # # ]: 0 : DataChanging(); // darf nicht neu sein
3069 : :
3070 [ # # ]: 0 : String aEmpty;
3071 [ # # ]: 0 : if (pTableView)
3072 : : {
3073 [ # # ][ # # ]: 0 : pTableView->GetEditEngine()->SetText( aEmpty );
3074 [ # # ]: 0 : pTableView->SetSelection( ESelection(0,0, 0,0) );
3075 : : }
3076 [ # # ]: 0 : if (pTopView)
3077 : : {
3078 [ # # ][ # # ]: 0 : pTopView->GetEditEngine()->SetText( aEmpty );
3079 [ # # ]: 0 : pTopView->SetSelection( ESelection(0,0, 0,0) );
3080 : : }
3081 : :
3082 [ # # ][ # # ]: 0 : DataChanged();
3083 : : }
3084 : :
3085 : 0 : bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, bool bStartEdit /* = false */ )
3086 : : {
3087 [ # # ]: 0 : if (!bOptLoaded)
3088 : : {
3089 [ # # ][ # # ]: 0 : bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
3090 : 0 : bOptLoaded = true;
3091 : : }
3092 : :
3093 : 0 : KeyCode aCode = rKEvt.GetKeyCode();
3094 : 0 : sal_uInt16 nModi = aCode.GetModifier();
3095 : 0 : bool bShift = aCode.IsShift();
3096 : 0 : bool bControl = aCode.IsMod1();
3097 : 0 : bool bAlt = aCode.IsMod2();
3098 : 0 : sal_uInt16 nCode = aCode.GetCode();
3099 : 0 : sal_Unicode nChar = rKEvt.GetCharCode();
3100 : :
3101 [ # # ][ # # ]: 0 : if (bAlt && !bControl && nCode != KEY_RETURN)
[ # # ]
3102 : : // Alt-Return and Alt-Ctrl-* are accepted. Everything else with ALT are not.
3103 : 0 : return false;
3104 : :
3105 [ # # ][ # # ]: 0 : if (!bControl && nCode == KEY_TAB)
3106 : : {
3107 : : // Normal TAB moves the cursor right.
3108 [ # # ]: 0 : EnterHandler();
3109 : :
3110 [ # # ]: 0 : if (pActiveViewSh)
3111 [ # # ]: 0 : pActiveViewSh->FindNextUnprot( bShift );
3112 : 0 : return true;
3113 : : }
3114 : :
3115 : 0 : bool bInputLine = ( eMode==SC_INPUT_TOP );
3116 : :
3117 : 0 : bool bUsed = false;
3118 : 0 : bool bSkip = false;
3119 : 0 : bool bDoEnter = false;
3120 : :
3121 [ # # # # : 0 : switch ( nCode )
# ]
3122 : : {
3123 : : case KEY_RETURN:
3124 [ # # ][ # # ]: 0 : if (bControl && !bShift && ( !bInputLine || ( pInputWin && pInputWin->IsMultiLineInput() ) ) )
[ # # ][ # # ]
[ # # ][ # # ]
3125 : 0 : bDoEnter = true;
3126 [ # # ][ # # ]: 0 : else if (nModi == 0 && nTipVisible && pFormulaData && miAutoPosFormula != pFormulaData->end())
[ # # ][ # # ]
[ # # ][ # # ]
3127 : : {
3128 [ # # ]: 0 : PasteFunctionData();
3129 : 0 : bUsed = true;
3130 : : }
3131 [ # # ][ # # ]: 0 : else if ( nModi == 0 && nTipVisible && !aManualTip.isEmpty() )
[ # # ][ # # ]
3132 : : {
3133 [ # # ]: 0 : PasteManualTip();
3134 : 0 : bUsed = true;
3135 : : }
3136 : : else
3137 : : {
3138 : 0 : sal_uInt8 nMode = SC_ENTER_NORMAL;
3139 [ # # ][ # # ]: 0 : if ( bShift && bControl )
3140 : 0 : nMode = SC_ENTER_MATRIX;
3141 [ # # ]: 0 : else if ( bAlt )
3142 : 0 : nMode = SC_ENTER_BLOCK;
3143 [ # # ]: 0 : EnterHandler( nMode );
3144 : :
3145 [ # # ]: 0 : if (pActiveViewSh)
3146 [ # # ][ # # ]: 0 : pActiveViewSh->MoveCursorEnter( bShift && !bControl );
[ # # ]
3147 : :
3148 : 0 : bUsed = true;
3149 : : }
3150 : 0 : break;
3151 : : case KEY_TAB:
3152 [ # # ][ # # ]: 0 : if (bControl && !bAlt)
3153 : : {
3154 [ # # ][ # # ]: 0 : if (pFormulaData && nTipVisible && miAutoPosFormula != pFormulaData->end())
[ # # ][ # # ]
[ # # ]
3155 : : {
3156 : : // blaettern
3157 : :
3158 [ # # ]: 0 : NextFormulaEntry( bShift );
3159 : 0 : bUsed = true;
3160 : : }
3161 [ # # ][ # # ]: 0 : else if (pColumnData && bUseTab && miAutoPosColumn != pColumnData->end())
[ # # ][ # # ]
[ # # ]
3162 : : {
3163 : : // in den Eintraegen der AutoEingabe blaettern
3164 : :
3165 [ # # ]: 0 : NextAutoEntry( bShift );
3166 : 0 : bUsed = true;
3167 : : }
3168 : : }
3169 : 0 : break;
3170 : : case KEY_ESCAPE:
3171 [ # # ]: 0 : if ( nTipVisible )
3172 : : {
3173 [ # # ]: 0 : HideTip();
3174 : 0 : bUsed = true;
3175 : : }
3176 [ # # ]: 0 : else if( nTipVisibleSec )
3177 : : {
3178 [ # # ]: 0 : HideTipBelow();
3179 : 0 : bUsed = true;
3180 : : }
3181 [ # # ]: 0 : else if (eMode != SC_INPUT_NONE)
3182 : : {
3183 [ # # ]: 0 : CancelHandler();
3184 : 0 : bUsed = true;
3185 : : }
3186 : : else
3187 : 0 : bSkip = true;
3188 : 0 : break;
3189 : : case KEY_F2:
3190 [ # # ][ # # ]: 0 : if ( !bShift && !bControl && !bAlt && eMode == SC_INPUT_TABLE )
[ # # ][ # # ]
3191 : : {
3192 : 0 : eMode = SC_INPUT_TYPE;
3193 : 0 : bUsed = true;
3194 : : }
3195 : 0 : break;
3196 : : }
3197 : :
3198 : : // Cursortasten nur ausfuehren, wenn schon im Edit-Modus
3199 : : // z.B. wegen Shift-Ctrl-PageDn (ist nicht als Accelerator definiert)
3200 : :
3201 [ # # ]: 0 : bool bCursorKey = EditEngine::DoesKeyMoveCursor(rKEvt);
3202 [ # # ][ # # ]: 0 : bool bInsKey = ( nCode == KEY_INSERT && !nModi ); // Insert wie Cursortasten behandeln
3203 [ # # ][ # # ]: 0 : if ( !bUsed && !bSkip && ( bDoEnter || EditEngine::DoesKeyChangeText(rKEvt) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3204 : : ( eMode != SC_INPUT_NONE && ( bCursorKey || bInsKey ) ) ) )
3205 : : {
3206 [ # # ]: 0 : HideTip();
3207 [ # # ]: 0 : HideTipBelow();
3208 : :
3209 [ # # ]: 0 : if (bSelIsRef)
3210 : : {
3211 [ # # ]: 0 : RemoveSelection();
3212 : 0 : bSelIsRef = false;
3213 : : }
3214 : :
3215 [ # # ]: 0 : UpdateActiveView();
3216 [ # # ]: 0 : bool bNewView = DataChanging( nChar );
3217 : :
3218 [ # # ]: 0 : if (bProtected) // Zelle geschuetzt?
3219 : 0 : bUsed = true; // Key-Event nicht weiterleiten
3220 : : else // Aenderungen erlaubt
3221 : : {
3222 [ # # ]: 0 : if (bNewView ) // neu anlegen
3223 : : {
3224 [ # # ]: 0 : if (pActiveViewSh)
3225 [ # # ]: 0 : pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
3226 [ # # ]: 0 : UpdateActiveView();
3227 [ # # ]: 0 : if (eMode==SC_INPUT_NONE)
3228 [ # # ][ # # ]: 0 : if (pTableView || pTopView)
3229 : : {
3230 [ # # ]: 0 : String aStrLoP;
3231 : :
3232 [ # # ][ # # ]: 0 : if ( bStartEdit && bCellHasPercentFormat && ((nChar >= '0' && nChar <= '9') || nChar == '-') )
[ # # ][ # # ]
[ # # ]
3233 [ # # ]: 0 : aStrLoP = '%';
3234 : :
3235 [ # # ]: 0 : if (pTableView)
3236 : : {
3237 [ # # ][ # # ]: 0 : pTableView->GetEditEngine()->SetText( aStrLoP );
3238 [ # # ]: 0 : if ( aStrLoP.Len() )
3239 [ # # ]: 0 : pTableView->SetSelection( ESelection(0,0, 0,0) ); // before the '%'
3240 : :
3241 : : // don't call SetSelection if the string is empty anyway,
3242 : : // to avoid breaking the bInitial handling in ScViewData::EditGrowY
3243 : : }
3244 [ # # ]: 0 : if (pTopView)
3245 : : {
3246 [ # # ][ # # ]: 0 : pTopView->GetEditEngine()->SetText( aStrLoP );
3247 [ # # ]: 0 : if ( aStrLoP.Len() )
3248 [ # # ]: 0 : pTopView->SetSelection( ESelection(0,0, 0,0) ); // before the '%'
3249 [ # # ]: 0 : }
3250 : : }
3251 [ # # ]: 0 : SyncViews();
3252 : : }
3253 : :
3254 [ # # ][ # # ]: 0 : if (pTableView || pTopView)
3255 : : {
3256 [ # # ]: 0 : if (bDoEnter)
3257 : : {
3258 [ # # ]: 0 : if (pTableView)
3259 [ # # ][ # # ]: 0 : if( pTableView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
[ # # ]
3260 : 0 : bUsed = true;
3261 [ # # ]: 0 : if (pTopView)
3262 [ # # ][ # # ]: 0 : if( pTopView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
[ # # ]
3263 : 0 : bUsed = true;
3264 : : }
3265 [ # # ][ # # ]: 0 : else if ( nAutoPar && nChar == ')' && CursorAtClosingPar() )
[ # # ][ # # ]
[ # # ]
3266 : : {
3267 [ # # ]: 0 : SkipClosingPar();
3268 : 0 : bUsed = true;
3269 : : }
3270 : : else
3271 : : {
3272 [ # # ]: 0 : if (pTableView)
3273 : : {
3274 [ # # ]: 0 : Window* pFrameWin = pActiveViewSh ? pActiveViewSh->GetFrameWin() : NULL;
3275 [ # # ][ # # ]: 0 : if ( pTableView->PostKeyEvent( rKEvt, pFrameWin ) )
3276 : 0 : bUsed = true;
3277 : : }
3278 [ # # ]: 0 : if (pTopView)
3279 [ # # ][ # # ]: 0 : if ( pTopView->PostKeyEvent( rKEvt ) )
3280 : 0 : bUsed = true;
3281 : : }
3282 : :
3283 : : // Auto-Eingabe:
3284 : :
3285 [ # # ][ # # ]: 0 : if ( bUsed && bAutoComplete )
3286 : : {
3287 : 0 : bUseTab = false;
3288 [ # # ]: 0 : if (pFormulaData)
3289 : 0 : miAutoPosFormula = pFormulaData->end(); // do not search further
3290 [ # # ]: 0 : if (pColumnData)
3291 : 0 : miAutoPosColumn = pColumnData->end();
3292 : :
3293 [ # # ]: 0 : KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
3294 [ # # ][ # # ]: 0 : if ( nChar && nChar != 8 && nChar != 127 && // no 'backspace', no 'delete'
[ # # ][ # # ]
3295 : : KEYFUNC_CUT != eFunc) // and no 'CTRL-X'
3296 : : {
3297 [ # # ]: 0 : if (bFormulaMode)
3298 [ # # ]: 0 : UseFormulaData();
3299 : : else
3300 [ # # ]: 0 : UseColData();
3301 : : }
3302 : : }
3303 : :
3304 : : // when the selection is changed manually or an opening parenthesis
3305 : : // is typed, stop overwriting parentheses
3306 [ # # ][ # # ]: 0 : if ( bUsed && nChar == '(' )
3307 : 0 : ResetAutoPar();
3308 : :
3309 [ # # ]: 0 : if ( KEY_INSERT == nCode )
3310 : : {
3311 [ # # ]: 0 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
3312 [ # # ]: 0 : if (pViewFrm)
3313 [ # # ]: 0 : pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
3314 : : }
3315 [ # # ][ # # ]: 0 : if( bUsed && bFormulaMode && ( bCursorKey || bInsKey || nCode == KEY_DELETE || nCode == KEY_BACKSPACE ) )
[ # # ][ # # ]
[ # # ][ # # ]
3316 : : {
3317 [ # # ]: 0 : ShowTipCursor();
3318 : : }
3319 : : }
3320 : :
3321 [ # # ]: 0 : DataChanged(); // ruft auch UpdateParenthesis()
3322 [ # # ]: 0 : InvalidateAttribs(); //! in DataChanged ?
3323 : : }
3324 : : }
3325 : :
3326 [ # # ][ # # ]: 0 : if (pTopView && eMode != SC_INPUT_NONE)
3327 [ # # ]: 0 : SyncViews();
3328 : :
3329 : 0 : return bUsed;
3330 : : }
3331 : :
3332 : 0 : bool ScInputHandler::InputCommand( const CommandEvent& rCEvt, bool bForce )
3333 : : {
3334 : 0 : bool bUsed = false;
3335 : :
3336 [ # # ]: 0 : if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
3337 : : {
3338 : : // for COMMAND_CURSORPOS, do as little as possible, because
3339 : : // with remote VCL, even a ShowCursor will generate another event.
3340 [ # # ]: 0 : if ( eMode != SC_INPUT_NONE )
3341 : : {
3342 : 0 : UpdateActiveView();
3343 [ # # ][ # # ]: 0 : if (pTableView || pTopView)
3344 : : {
3345 [ # # ]: 0 : if (pTableView)
3346 : 0 : pTableView->Command( rCEvt );
3347 [ # # ]: 0 : else if (pTopView) // call only once
3348 : 0 : pTopView->Command( rCEvt );
3349 : 0 : bUsed = true;
3350 : : }
3351 : : }
3352 : : }
3353 : : else
3354 : : {
3355 [ # # ][ # # ]: 0 : if ( bForce || eMode != SC_INPUT_NONE )
3356 : : {
3357 [ # # ]: 0 : if (!bOptLoaded)
3358 : : {
3359 : 0 : bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
3360 : 0 : bOptLoaded = true;
3361 : : }
3362 : :
3363 : 0 : HideTip();
3364 : 0 : HideTipBelow();
3365 : :
3366 [ # # ]: 0 : if ( bSelIsRef )
3367 : : {
3368 : 0 : RemoveSelection();
3369 : 0 : bSelIsRef = false;
3370 : : }
3371 : :
3372 : 0 : UpdateActiveView();
3373 : 0 : bool bNewView = DataChanging( 0, true );
3374 : :
3375 [ # # ]: 0 : if (bProtected) // cell protected
3376 : 0 : bUsed = true; // event is used
3377 : : else // changes allowed
3378 : : {
3379 [ # # ]: 0 : if (bNewView) // create new edit view
3380 : : {
3381 [ # # ]: 0 : if (pActiveViewSh)
3382 : 0 : pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
3383 : 0 : UpdateActiveView();
3384 [ # # ]: 0 : if (eMode==SC_INPUT_NONE)
3385 [ # # ][ # # ]: 0 : if (pTableView || pTopView)
3386 : : {
3387 [ # # ]: 0 : String aStrLoP;
3388 [ # # ]: 0 : if (pTableView)
3389 : : {
3390 [ # # ][ # # ]: 0 : pTableView->GetEditEngine()->SetText( aStrLoP );
3391 [ # # ]: 0 : pTableView->SetSelection( ESelection(0,0, 0,0) );
3392 : : }
3393 [ # # ]: 0 : if (pTopView)
3394 : : {
3395 [ # # ][ # # ]: 0 : pTopView->GetEditEngine()->SetText( aStrLoP );
3396 [ # # ]: 0 : pTopView->SetSelection( ESelection(0,0, 0,0) );
3397 [ # # ]: 0 : }
3398 : : }
3399 : 0 : SyncViews();
3400 : : }
3401 : :
3402 [ # # ][ # # ]: 0 : if (pTableView || pTopView)
3403 : : {
3404 [ # # ]: 0 : if (pTableView)
3405 : 0 : pTableView->Command( rCEvt );
3406 [ # # ]: 0 : if (pTopView)
3407 : 0 : pTopView->Command( rCEvt );
3408 : :
3409 : 0 : bUsed = true;
3410 : :
3411 [ # # ]: 0 : if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
3412 : : {
3413 : : // AutoInput after ext text input
3414 : :
3415 [ # # ]: 0 : if (pFormulaData)
3416 : 0 : miAutoPosFormula = pFormulaData->end();
3417 [ # # ]: 0 : if (pColumnData)
3418 : 0 : miAutoPosColumn = pColumnData->end();
3419 : :
3420 [ # # ]: 0 : if (bFormulaMode)
3421 : 0 : UseFormulaData();
3422 : : else
3423 : 0 : UseColData();
3424 : : }
3425 : : }
3426 : :
3427 : 0 : DataChanged(); // calls UpdateParenthesis()
3428 : 0 : InvalidateAttribs(); //! in DataChanged ?
3429 : : }
3430 : : }
3431 : :
3432 [ # # ][ # # ]: 0 : if (pTopView && eMode != SC_INPUT_NONE)
3433 : 0 : SyncViews();
3434 : : }
3435 : :
3436 : 0 : return bUsed;
3437 : : }
3438 : :
3439 : 1642 : void ScInputHandler::NotifyChange( const ScInputHdlState* pState,
3440 : : bool bForce, ScTabViewShell* pSourceSh,
3441 : : bool bStopEditing)
3442 : : {
3443 : : // Wenn der Aufruf aus einem Makro-Aufruf im EnterHandler kommt,
3444 : : // gleich abbrechen und nicht den Status durcheinander bringen
3445 [ - + ]: 1642 : if (bInEnterHandler)
3446 : 0 : return;
3447 : :
3448 : 1642 : bool bRepeat = (pState == pLastState);
3449 [ + - ][ + + ]: 1642 : if (!bRepeat && pState && pLastState)
[ + + ]
3450 : 1184 : bRepeat = (*pState == *pLastState);
3451 [ + + ][ + + ]: 1642 : if (bRepeat && !bForce)
3452 : 777 : return;
3453 : :
3454 : 865 : bInOwnChange = true; // disable ModifyHdl (reset below)
3455 : :
3456 [ + + ][ + + ]: 865 : if ( pState && !pLastState ) // wieder enablen
3457 : 233 : bForce = true;
3458 : :
3459 [ + + ][ + + ]: 865 : bool bHadObject = pLastState && pLastState->GetEditData();
3460 : :
3461 : : //! Before EditEngine gets eventually created (so it gets the right pools)
3462 [ + + ]: 865 : if ( pSourceSh )
3463 : 640 : pActiveViewSh = pSourceSh;
3464 : : else
3465 [ + - ][ + - ]: 225 : pActiveViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
3466 : :
3467 : 865 : ImplCreateEditEngine();
3468 : :
3469 [ + - ]: 865 : if ( pState != pLastState )
3470 : : {
3471 [ + + ]: 865 : delete pLastState;
3472 [ + + ][ + - ]: 865 : pLastState = pState ? new ScInputHdlState( *pState ) : NULL;
3473 : : }
3474 : :
3475 [ + + ][ + - ]: 865 : if ( pState && pActiveViewSh )
3476 : : {
3477 : 640 : ScModule* pScMod = SC_MOD();
3478 : :
3479 [ + - ]: 640 : if ( pState )
3480 : : {
3481 : 640 : bool bIgnore = false;
3482 : :
3483 : : // hier auch fremde Referenzeingabe beruecksichtigen (z.B. Funktions-AP),
3484 : : // FormEditData falls gerade von der Hilfe auf Calc umgeschaltet wird:
3485 : :
3486 [ + - ][ + - ]: 640 : if ( !bFormulaMode && !pScMod->IsFormulaMode() && !pScMod->GetFormEditData() )
[ + - ][ + - ]
3487 : : {
3488 [ - + ]: 640 : if ( bModified )
3489 : : {
3490 [ # # ]: 0 : if (pState->GetPos() != aCursorPos)
3491 : : {
3492 [ # # ]: 0 : if (!bProtected)
3493 : 0 : EnterHandler();
3494 : : }
3495 : : else
3496 : 0 : bIgnore = true;
3497 : : }
3498 : :
3499 [ + - ]: 640 : if ( !bIgnore )
3500 : : {
3501 : 640 : const ScAddress& rSPos = pState->GetStartPos();
3502 : 640 : const ScAddress& rEPos = pState->GetEndPos();
3503 : 640 : const EditTextObject* pData = pState->GetEditData();
3504 [ + - ]: 640 : rtl::OUString aString = pState->GetString();
3505 : 640 : bool bTxtMod = false;
3506 : 640 : ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
3507 : 640 : ScDocument* pDoc = pDocSh->GetDocument();
3508 : :
3509 : 640 : aCursorPos = pState->GetPos();
3510 : :
3511 [ + + ]: 640 : if ( pData )
3512 : 28 : bTxtMod = true;
3513 [ - + ]: 612 : else if ( bHadObject )
3514 : 0 : bTxtMod = true;
3515 [ + - ]: 612 : else if ( bTextValid )
3516 : 612 : bTxtMod = ( !aString.equals(aCurrentText) );
3517 : : else
3518 [ # # ][ # # ]: 0 : bTxtMod = ( !aString.equals(GetEditText(pEngine)) );
[ # # ][ # # ]
3519 : :
3520 [ + + ][ + + ]: 640 : if ( bTxtMod || bForce )
3521 : : {
3522 [ + + ]: 581 : if (pData)
3523 : : {
3524 [ + - ]: 28 : pEngine->SetText( *pData );
3525 [ + - ][ + - ]: 28 : if ( pInputWin && pInputWin->IsMultiLineInput() )
[ + - ]
3526 [ + - ][ + - ]: 28 : aString = ScEditUtil::GetMultilineString(*pEngine);
[ + - ]
3527 : : else
3528 [ # # ][ # # ]: 0 : aString = GetEditText(pEngine);
[ # # ][ # # ]
3529 [ + - ]: 28 : lcl_RemoveTabs(aString);
3530 : 28 : bTextValid = false;
3531 : 28 : aCurrentText = rtl::OUString();
3532 : : }
3533 : : else
3534 : : {
3535 : 553 : aCurrentText = aString;
3536 : 553 : bTextValid = true; //! erst nur als String merken
3537 : : }
3538 : :
3539 [ + - ]: 581 : if ( pInputWin )
3540 [ + - ][ + - ]: 581 : pInputWin->SetTextString(aString);
[ + - ]
3541 : : }
3542 : :
3543 [ + - ]: 640 : if ( pInputWin ) // Bereichsanzeige
3544 : : {
3545 : 640 : rtl::OUString aPosStr;
3546 [ + - ]: 640 : const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
3547 : :
3548 : : // Ist der Bereich ein Name?
3549 : : //! per Timer suchen ???
3550 : :
3551 [ + - ]: 640 : if ( pActiveViewSh )
3552 : : pActiveViewSh->GetViewData()->GetDocument()->
3553 [ + - ][ + - ]: 640 : GetRangeAtBlock( ScRange( rSPos, rEPos ), &aPosStr );
3554 : :
3555 [ + - ]: 640 : if ( aPosStr.isEmpty() ) // kein Name -> formatieren
3556 : : {
3557 : 640 : sal_uInt16 nFlags = 0;
3558 [ - + ]: 640 : if( aAddrDetails.eConv == formula::FormulaGrammar::CONV_XL_R1C1 )
3559 : 0 : nFlags |= SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;
3560 [ + + ]: 640 : if ( rSPos != rEPos )
3561 : : {
3562 : 20 : ScRange r(rSPos, rEPos);
3563 : 20 : nFlags |= (nFlags << 4);
3564 [ + - ]: 20 : r.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
3565 : : }
3566 : : else
3567 [ + - ]: 620 : aCursorPos.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
3568 : : }
3569 : :
3570 : : // Disable the accessible VALUE_CHANGE event
3571 [ + - ]: 640 : bool bIsSuppressed = pInputWin->IsAccessibilityEventsSuppressed(false);
3572 [ + - ]: 640 : pInputWin->SetAccessibilityEventsSuppressed(true);
3573 [ + - ][ + - ]: 640 : pInputWin->SetPosString(aPosStr);
[ + - ]
3574 [ + - ]: 640 : pInputWin->SetAccessibilityEventsSuppressed(bIsSuppressed);
3575 [ + - ]: 640 : pInputWin->SetSumAssignMode();
3576 : : }
3577 : :
3578 [ + - ]: 640 : if (bStopEditing)
3579 [ + - ][ + - ]: 640 : SFX_APP()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
[ + - ][ + - ]
3580 : :
3581 : : // As long as the content is not edited, turn off online spelling.
3582 : : // Online spelling is turned back on in StartTable, after setting
3583 : : // the right language from cell attributes.
3584 : :
3585 [ + - ]: 640 : sal_uLong nCntrl = pEngine->GetControlWord();
3586 [ - + ]: 640 : if ( nCntrl & EE_CNTRL_ONLINESPELLING )
3587 [ # # ]: 0 : pEngine->SetControlWord( nCntrl & ~EE_CNTRL_ONLINESPELLING );
3588 : :
3589 : 640 : bModified = false;
3590 : 640 : bSelIsRef = false;
3591 : 640 : bProtected = false;
3592 : 640 : bCommandErrorShown = false;
3593 : : }
3594 : : }
3595 : : }
3596 : :
3597 [ + - ]: 640 : if ( pInputWin)
3598 : : {
3599 [ + - ][ + - ]: 640 : if(!pScMod->IsFormulaMode()&& !pScMod->IsRefDialogOpen()) //BugID 54702
[ + - ]
3600 : : { //Wenn RefDialog offen, dann nicht enablen
3601 [ - + ]: 640 : if ( !pInputWin->IsEnabled())
3602 : : {
3603 : 0 : pInputWin->Enable();
3604 [ # # ]: 0 : if(pDelayTimer )
3605 : : {
3606 [ # # ]: 0 : DELETEZ( pDelayTimer );
3607 : : }
3608 : : }
3609 : : }
3610 [ # # ]: 0 : else if(pScMod->IsRefDialogOpen())
3611 : : { // Da jedes Dokument eigenes InputWin hat, sollte
3612 [ # # ]: 0 : if ( !pDelayTimer ) // nochmals Timer gestartet werden, da sonst Ein-
3613 : : { // gabezeile evt. noch aktiv ist.
3614 [ # # ]: 0 : pDelayTimer = new Timer;
3615 : 0 : pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
3616 : 0 : pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
3617 : 0 : pDelayTimer->Start();
3618 : : }
3619 : : }
3620 : 640 : }
3621 : : }
3622 : : else // !pState || !pActiveViewSh
3623 : : {
3624 [ + - ]: 225 : if ( !pDelayTimer )
3625 : : {
3626 [ + - ]: 225 : pDelayTimer = new Timer;
3627 : 225 : pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
3628 : 225 : pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
3629 : 225 : pDelayTimer->Start();
3630 : : }
3631 : : }
3632 : :
3633 : 865 : HideTip();
3634 : 865 : HideTipBelow();
3635 : 1642 : bInOwnChange = false;
3636 : : }
3637 : :
3638 : 0 : void ScInputHandler::UpdateCellAdjust( SvxCellHorJustify eJust )
3639 : : {
3640 : 0 : eAttrAdjust = eJust;
3641 : 0 : UpdateAdjust( 0 );
3642 : 0 : }
3643 : :
3644 : 32 : void ScInputHandler::ResetDelayTimer()
3645 : : {
3646 [ - + ]: 32 : if(pDelayTimer!=NULL)
3647 : : {
3648 [ # # ]: 0 : DELETEZ( pDelayTimer );
3649 : :
3650 [ # # ]: 0 : if ( pInputWin)
3651 : : {
3652 : 0 : pInputWin->Enable();
3653 : : }
3654 : : }
3655 : 32 : }
3656 : :
3657 : 5 : IMPL_LINK( ScInputHandler, DelayTimer, Timer*, pTimer )
3658 : : {
3659 [ + - ]: 5 : if ( pTimer == pDelayTimer )
3660 : : {
3661 [ + - ]: 5 : DELETEZ( pDelayTimer );
3662 : :
3663 [ - + ][ # # ]: 5 : if ( NULL == pLastState || SC_MOD()->IsFormulaMode() || SC_MOD()->IsRefDialogOpen())
[ # # ][ + - ]
3664 : : {
3665 : : //! new method at ScModule to query if function autopilot is open
3666 : :
3667 : 5 : SfxViewFrame* pViewFrm = SfxViewFrame::Current();
3668 [ - + ][ - + ]: 5 : if ( pViewFrm && pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
[ + - ]
3669 : : {
3670 [ # # ]: 0 : if ( pInputWin)
3671 : : {
3672 : 0 : pInputWin->EnableButtons( false );
3673 : 0 : pInputWin->Disable();
3674 : : }
3675 : : }
3676 [ + - ]: 5 : else if ( !bFormulaMode ) // Formel auch z.B. bei Hilfe behalten
3677 : : {
3678 : 5 : bInOwnChange = true; // disable ModifyHdl (reset below)
3679 : :
3680 : 5 : pActiveViewSh = NULL;
3681 : 5 : pEngine->SetText( EMPTY_STRING );
3682 [ + - ]: 5 : if ( pInputWin )
3683 : : {
3684 : 5 : pInputWin->SetPosString( EMPTY_STRING );
3685 : 5 : pInputWin->SetTextString( EMPTY_STRING );
3686 : 5 : pInputWin->Disable();
3687 : : }
3688 : :
3689 : 5 : bInOwnChange = false;
3690 : : }
3691 : : }
3692 : : }
3693 : 5 : return 0;
3694 : : }
3695 : :
3696 : 0 : void ScInputHandler::InputSelection( EditView* pView )
3697 : : {
3698 : 0 : SyncViews( pView );
3699 : 0 : ShowTipCursor();
3700 : 0 : UpdateParenthesis(); // Selektion geaendert -> Klammer-Hervorhebung neu
3701 : :
3702 : : // when the selection is changed manually, stop overwriting parentheses
3703 : 0 : ResetAutoPar();
3704 : 0 : }
3705 : :
3706 : 0 : void ScInputHandler::InputChanged( EditView* pView, bool bFromNotify )
3707 : : {
3708 : 0 : UpdateActiveView();
3709 : :
3710 : : // #i20282# DataChanged needs to know if this is from the input line's modify handler
3711 [ # # ][ # # ]: 0 : bool bFromTopNotify = ( bFromNotify && pView == pTopView );
3712 : :
3713 : 0 : bool bNewView = DataChanging(); //! kann das hier ueberhaupt sein?
3714 [ # # ]: 0 : aCurrentText = pView->GetEditEngine()->GetText(); // auch den String merken
3715 [ # # ]: 0 : pEngine->SetText( aCurrentText );
3716 : 0 : DataChanged( bFromTopNotify );
3717 : 0 : bTextValid = true; // wird in DataChanged auf false gesetzt
3718 : :
3719 [ # # ]: 0 : if ( pActiveViewSh )
3720 : : {
3721 : 0 : ScViewData* pViewData = pActiveViewSh->GetViewData();
3722 [ # # ]: 0 : if ( bNewView )
3723 : 0 : pViewData->GetDocShell()->PostEditView( pEngine, aCursorPos );
3724 : :
3725 : 0 : pViewData->EditGrowY();
3726 : 0 : pViewData->EditGrowX();
3727 : : }
3728 : :
3729 : 0 : SyncViews( pView );
3730 : 0 : }
3731 : :
3732 : 0 : const rtl::OUString& ScInputHandler::GetEditString()
3733 : : {
3734 [ # # ]: 0 : if (pEngine)
3735 : : {
3736 [ # # ]: 0 : aCurrentText = pEngine->GetText(); // immer neu aus Engine
3737 : 0 : bTextValid = true;
3738 : : }
3739 : :
3740 : 0 : return aCurrentText;
3741 : : }
3742 : :
3743 : 0 : Size ScInputHandler::GetTextSize()
3744 : : {
3745 : 0 : Size aSize;
3746 [ # # ]: 0 : if ( pEngine )
3747 : 0 : aSize = Size( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );
3748 : :
3749 : 0 : return aSize;
3750 : : }
3751 : :
3752 : 205 : bool ScInputHandler::GetTextAndFields( ScEditEngineDefaulter& rDestEngine )
3753 : : {
3754 : 205 : bool bRet = false;
3755 [ + - ]: 205 : if (pEngine)
3756 : : {
3757 : : // Feldbefehle enthalten?
3758 : :
3759 [ + - ]: 205 : sal_uInt16 nParCnt = pEngine->GetParagraphCount();
3760 [ + - ]: 205 : SfxItemSet aSet = pEngine->GetAttribs( ESelection(0,0,nParCnt,0) );
3761 [ + - ]: 205 : SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, false );
3762 [ + - ][ - + ]: 205 : if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
3763 : : {
3764 : : // Inhalt kopieren
3765 : :
3766 [ # # ]: 0 : EditTextObject* pObj = pEngine->CreateTextObject();
3767 [ # # ]: 0 : rDestEngine.SetText(*pObj);
3768 [ # # ][ # # ]: 0 : delete pObj;
3769 : :
3770 : : // Attribute loeschen
3771 : :
3772 [ # # ]: 0 : for (sal_uInt16 i=0; i<nParCnt; i++)
3773 [ # # ]: 0 : rDestEngine.QuickRemoveCharAttribs( i );
3774 : :
3775 : : // Absaetze zusammenfassen
3776 : :
3777 [ # # ]: 0 : while ( nParCnt > 1 )
3778 : : {
3779 [ # # ]: 0 : xub_StrLen nLen = rDestEngine.GetTextLen( (sal_uInt16)0 );
3780 : 0 : ESelection aSel( 0,nLen, 1,0 );
3781 [ # # ][ # # ]: 0 : rDestEngine.QuickInsertText( rtl::OUString(' '), aSel ); // Umbruch durch Space ersetzen
[ # # ]
3782 : 0 : --nParCnt;
3783 : : }
3784 : :
3785 : 0 : bRet = true;
3786 [ + - ]: 205 : }
3787 : : }
3788 : 205 : return bRet;
3789 : : }
3790 : :
3791 : : //------------------------------------------------------------------------
3792 : : // Methoden fuer FunktionsAutopiloten:
3793 : : // InputGetSelection, InputSetSelection, InputReplaceSelection, InputGetFormulaStr
3794 : : //------------------------------------------------------------------------
3795 : :
3796 : 0 : void ScInputHandler::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd )
3797 : : {
3798 : 0 : rStart = nFormSelStart;
3799 : 0 : rEnd = nFormSelEnd;
3800 : 0 : }
3801 : :
3802 : : //------------------------------------------------------------------------
3803 : :
3804 : 0 : EditView* ScInputHandler::GetFuncEditView()
3805 : : {
3806 : 0 : UpdateActiveView(); // wegen pTableView
3807 : :
3808 : 0 : EditView* pView = NULL;
3809 [ # # ]: 0 : if ( pInputWin )
3810 : : {
3811 : 0 : pInputWin->MakeDialogEditView();
3812 : 0 : pView = pInputWin->GetEditView();
3813 : : }
3814 : : else
3815 : : {
3816 [ # # ]: 0 : if ( eMode != SC_INPUT_TABLE )
3817 : : {
3818 : 0 : bCreatingFuncView = true; // RangeFinder nicht anzeigen
3819 : 0 : SetMode( SC_INPUT_TABLE );
3820 : 0 : bCreatingFuncView = false;
3821 [ # # ]: 0 : if ( pTableView )
3822 : 0 : pTableView->GetEditEngine()->SetText( EMPTY_STRING );
3823 : : }
3824 : 0 : pView = pTableView;
3825 : : }
3826 : :
3827 : 0 : return pView;
3828 : : }
3829 : :
3830 : : //------------------------------------------------------------------------
3831 : :
3832 : 0 : void ScInputHandler::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd )
3833 : : {
3834 [ # # ]: 0 : if ( nStart <= nEnd )
3835 : : {
3836 : 0 : nFormSelStart = nStart;
3837 : 0 : nFormSelEnd = nEnd;
3838 : : }
3839 : : else
3840 : : {
3841 : 0 : nFormSelEnd = nStart;
3842 : 0 : nFormSelStart = nEnd;
3843 : : }
3844 : :
3845 : 0 : EditView* pView = GetFuncEditView();
3846 [ # # ]: 0 : if (pView)
3847 [ # # ]: 0 : pView->SetSelection( ESelection(0,nStart, 0,nEnd) );
3848 : :
3849 : 0 : bModified = true;
3850 : 0 : }
3851 : :
3852 : : //------------------------------------------------------------------------
3853 : :
3854 : 0 : void ScInputHandler::InputReplaceSelection( const rtl::OUString& rStr )
3855 : : {
3856 [ # # ]: 0 : if (!pRefViewSh)
3857 : 0 : pRefViewSh = pActiveViewSh;
3858 : :
3859 : : OSL_ENSURE(nFormSelEnd>=nFormSelStart,"Selektion kaputt...");
3860 : :
3861 : 0 : sal_Int32 nOldLen = nFormSelEnd - nFormSelStart;
3862 : 0 : sal_Int32 nNewLen = rStr.getLength();
3863 : :
3864 [ # # ]: 0 : rtl::OUStringBuffer aBuf(aFormText);
3865 [ # # ]: 0 : if (nOldLen)
3866 [ # # ]: 0 : aBuf.remove(nFormSelStart, nOldLen);
3867 [ # # ]: 0 : if (nNewLen)
3868 [ # # ]: 0 : aBuf.insert(nFormSelStart, rStr);
3869 : :
3870 [ # # ]: 0 : aFormText = aBuf.makeStringAndClear();
3871 : :
3872 : 0 : nFormSelEnd = nFormSelStart + nNewLen;
3873 : :
3874 [ # # ]: 0 : EditView* pView = GetFuncEditView();
3875 [ # # ]: 0 : if (pView)
3876 : : {
3877 [ # # ]: 0 : pView->SetEditEngineUpdateMode( false );
3878 [ # # ][ # # ]: 0 : pView->GetEditEngine()->SetText( aFormText );
[ # # ][ # # ]
3879 [ # # ]: 0 : pView->SetSelection( ESelection(0,nFormSelStart, 0,nFormSelEnd) );
3880 [ # # ]: 0 : pView->SetEditEngineUpdateMode( true );
3881 : : }
3882 : 0 : bModified = true;
3883 : 0 : }
3884 : :
3885 : : //========================================================================
3886 : : // ScInputHdlState
3887 : : //========================================================================
3888 : :
3889 : 1417 : ScInputHdlState::ScInputHdlState( const ScAddress& rCurPos,
3890 : : const ScAddress& rStartPos,
3891 : : const ScAddress& rEndPos,
3892 : : const String& rString,
3893 : : const EditTextObject* pData )
3894 : : : aCursorPos ( rCurPos ),
3895 : : aStartPos ( rStartPos ),
3896 : : aEndPos ( rEndPos ),
3897 : : aString ( rString ),
3898 [ + + ][ + - ]: 1417 : pEditData ( pData ? pData->Clone() : NULL )
3899 : : {
3900 : 1417 : }
3901 : :
3902 : : //------------------------------------------------------------------------
3903 : :
3904 : 640 : ScInputHdlState::ScInputHdlState( const ScInputHdlState& rCpy )
3905 : 640 : : pEditData ( NULL )
3906 : : {
3907 [ + - ]: 640 : *this = rCpy;
3908 : 640 : }
3909 : :
3910 : : //------------------------------------------------------------------------
3911 : :
3912 : 2053 : ScInputHdlState::~ScInputHdlState()
3913 : : {
3914 [ + + ][ + - ]: 2053 : delete pEditData;
3915 : 2053 : }
3916 : :
3917 : : //------------------------------------------------------------------------
3918 : :
3919 : 1184 : int ScInputHdlState::operator==( const ScInputHdlState& r ) const
3920 : : {
3921 : 1184 : return ( (aStartPos == r.aStartPos)
3922 : 1113 : && (aEndPos == r.aEndPos)
3923 : 1077 : && (aCursorPos == r.aCursorPos)
3924 : 1077 : && (aString == r.aString)
3925 [ + + ][ + + : 4451 : && ScGlobal::EETextObjEqual( pEditData, r.pEditData ) );
+ + + - +
+ ]
3926 : : }
3927 : :
3928 : : //------------------------------------------------------------------------
3929 : :
3930 : 640 : ScInputHdlState& ScInputHdlState::operator=( const ScInputHdlState& r )
3931 : : {
3932 [ - + ]: 640 : delete pEditData;
3933 : :
3934 : 640 : aCursorPos = r.aCursorPos;
3935 : 640 : aStartPos = r.aStartPos;
3936 : 640 : aEndPos = r.aEndPos;
3937 : 640 : aString = r.aString;
3938 [ + + ]: 640 : pEditData = r.pEditData ? r.pEditData->Clone() : NULL;
3939 : :
3940 : 640 : return *this;
3941 : : }
3942 : :
3943 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|