LCOV - code coverage report
Current view: top level - sc/source/ui/app - inputhdl.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 301 2096 14.4 %
Date: 2015-06-13 12:38:46 Functions: 33 103 32.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11