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

Generated by: LCOV version 1.10