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

Generated by: LCOV version 1.10