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

Generated by: LCOV version 1.10