/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifdef _MSC_VER
#pragma hdrstop
#endif

#include "scitems.hxx"
#include <bf_svx/eeitem.hxx>
#define ITEMID_FIELD EE_FEATURE_FIELD

#include <bf_svtools/colorcfg.hxx>
#include <bf_svx/editstat.hxx>


#include <bf_svtools/poolitem.hxx>

#include <bf_svx/itemdata.hxx>

#include <tools/date.hxx>

#include <tools/time.hxx>

#include <bf_svx/flditem.hxx>
#include <bf_svtools/inethist.hxx>
#include <bf_svtools/syslocale.hxx>
#include <comphelper/string.hxx>

#include "editutil.hxx"
#include "docpool.hxx"
#include "patattr.hxx"
#include "scmod.hxx"
namespace binfilter {

// STATIC DATA -----------------------------------------------------------

//  Delimiters zusaetzlich zu EditEngine-Default:

const sal_Char ScEditUtil::pCalcDelimiters[] = "=();+-*/^&<>";


//------------------------------------------------------------------------

/*N*/ String ScEditUtil::ModifyDelimiters( const String& rOld )
/*N*/ {
/*N*/   // underscore is used in function argument names
/*N*/   String aRet = comphelper::string::remove(rOld, '_');
/*N*/   aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( pCalcDelimiters ) );
/*N*/   return aRet;
/*N*/ }

/*N*/ String ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
/*N*/ {
/*N*/   String aRet;
/*N*/   USHORT nParCount = rEngine.GetParagraphCount();
/*N*/   for (USHORT nPar=0; nPar<nParCount; nPar++)
/*N*/   {
/*N*/       if (nPar > 0)
/*N*/           aRet += ' ';
/*N*/       aRet += rEngine.GetText( nPar );
/*N*/   }
/*N*/   return aRet;
/*N*/ }

//------------------------------------------------------------------------


//------------------------------------------------------------------------

/*N*/ ScEditAttrTester::ScEditAttrTester( EditEngine* pEng ) :
/*N*/   pEngine( pEng ),
/*N*/   pEditAttrs( NULL ),
/*N*/   bNeedsObject( FALSE ),
/*N*/   bNeedsCellAttr( FALSE )
/*N*/ {
/*N*/   if ( pEngine->GetParagraphCount() > 1 )
/*N*/   {
/*N*/       bNeedsObject = TRUE;            //! Zellatribute finden ?
/*N*/   }
/*N*/   else
/*N*/   {
/*N*/       const SfxPoolItem* pItem = NULL;
/*N*/       pEditAttrs = new SfxItemSet( pEngine->GetAttribs(
/*N*/                                       ESelection(0,0,0,pEngine->GetTextLen(0)) ) );
/*N*/       const SfxItemPool* pEditPool = pEditAttrs->GetPool();
/*N*/
/*N*/       for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
/*N*/       {
/*N*/           SfxItemState eState = pEditAttrs->GetItemState( nId, FALSE, &pItem );
/*N*/           if (eState == SFX_ITEM_DONTCARE)
/*N*/               bNeedsObject = TRUE;
/*N*/           else if (eState == SFX_ITEM_SET)
/*N*/           {
/*N*/               if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
/*N*/                       nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
/*N*/               {
/*N*/                   //  Escapement and kerning are kept in EditEngine because there are no
/*N*/                   //  corresponding cell format items. User defined attributes are kept in
/*N*/                   //  EditEngine because "user attributes applied to all the text" is different
/*N*/                   //  from "user attributes applied to the cell".
/*N*/
/*N*/                   if ( *pItem != pEditPool->GetDefaultItem(nId) )
/*N*/                       bNeedsObject = TRUE;
/*N*/               }
/*N*/               else
/*N*/                   if (!bNeedsCellAttr)
/*N*/                       if ( *pItem != pEditPool->GetDefaultItem(nId) )
/*N*/                           bNeedsCellAttr = TRUE;
/*N*/               //  SetDefaults an der EditEngine setzt Pool-Defaults
/*N*/           }
/*N*/       }
/*N*/
/*N*/       //  Feldbefehle enthalten?
/*N*/
/*N*/       SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, FALSE );
/*N*/       if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
/*N*/           bNeedsObject = TRUE;
/*N*/
/*N*/       //  not converted characters?
/*N*/
/*N*/       SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, FALSE );
/*N*/       if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
/*N*/           bNeedsObject = TRUE;
/*N*/   }
/*N*/ }

/*N*/ ScEditAttrTester::~ScEditAttrTester()
/*N*/ {
/*N*/   delete pEditAttrs;
/*N*/ }


//------------------------------------------------------------------------

/*N*/ ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
/*N*/               BOOL bDeleteEnginePoolP )
/*N*/           :
/*N*/           pEnginePool( pEnginePoolP ),
/*N*/           pDefaults( NULL ),
/*N*/           bDeleteEnginePool( bDeleteEnginePoolP ),
/*N*/           bDeleteDefaults( FALSE )
/*N*/ {
/*N*/ }


/*N*/ ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg )
/*N*/           :
/*N*/           pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
/*N*/           pDefaults( NULL ),
/*N*/           bDeleteEnginePool( rOrg.bDeleteEnginePool ),
/*N*/           bDeleteDefaults( FALSE )
/*N*/ {
/*N*/ }


/*N*/ ScEnginePoolHelper::~ScEnginePoolHelper()
/*N*/ {
/*N*/   if ( bDeleteDefaults )
/*N*/       delete pDefaults;
/*N*/   if ( bDeleteEnginePool )
/*N*/       delete pEnginePool;
/*N*/ }


//------------------------------------------------------------------------

/*N*/ ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP,
/*N*/               BOOL bDeleteEnginePoolP )
/*N*/           :
/*N*/           ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
/*N*/           EditEngine( pEnginePoolP )
/*N*/ {
/*N*/   //  All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
/*N*/   //  DefaultLanguage for InputHandler's EditEngine is updated later.
/*N*/
/*N*/   SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
/*N*/ }


/*N*/ ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg )
/*N*/           :
/*N*/           ScEnginePoolHelper( rOrg ),
/*N*/           EditEngine( pEnginePool )
/*N*/ {
/*N*/   SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
/*N*/ }


/*N*/ ScEditEngineDefaulter::~ScEditEngineDefaulter()
/*N*/ {
/*N*/ }


/*N*/ void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, BOOL bRememberCopy )
/*N*/ {
/*N*/   if ( bRememberCopy )
/*N*/   {
/*N*/       if ( bDeleteDefaults )
/*N*/           delete pDefaults;
/*N*/       pDefaults = new SfxItemSet( rSet );
/*N*/       bDeleteDefaults = TRUE;
/*N*/   }
/*N*/   const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
/*N*/   BOOL bUndo = IsUndoEnabled();
/*N*/   EnableUndo( FALSE );
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( FALSE );
/*N*/   USHORT nPara = GetParagraphCount();
/*N*/   for ( USHORT j=0; j<nPara; j++ )
/*N*/   {
/*N*/       SetParaAttribs( j, rNewSet );
/*N*/   }
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( TRUE );
/*N*/   if ( bUndo )
/*N*/       EnableUndo( TRUE );
/*N*/ }


/*N*/ void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, BOOL bTakeOwnership )
/*N*/ {
/*N*/   if ( bDeleteDefaults )
/*N*/       delete pDefaults;
/*N*/   pDefaults = pSet;
/*N*/   bDeleteDefaults = bTakeOwnership;
/*N*/   if ( pDefaults )
/*N*/       SetDefaults( *pDefaults, FALSE );
/*N*/ }




/*N*/ void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
/*N*/ {
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( FALSE );
/*N*/   EditEngine::SetText( rTextObject );
/*N*/   if ( pDefaults )
/*N*/       SetDefaults( *pDefaults, FALSE );
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( TRUE );
/*N*/ }

/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
/*N*/           const SfxItemSet& rSet, BOOL bRememberCopy )
/*N*/ {
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( FALSE );
/*N*/   EditEngine::SetText( rTextObject );
/*N*/   SetDefaults( rSet, bRememberCopy );
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( TRUE );
/*N*/ }

/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
/*N*/           SfxItemSet* pSet, BOOL bTakeOwnership )
/*N*/ {
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*?*/       SetUpdateMode( FALSE );
/*N*/   EditEngine::SetText( rTextObject );
/*N*/   SetDefaults( pSet, bTakeOwnership );
/*N*/   if ( bUpdateMode )
/*?*/       SetUpdateMode( TRUE );
/*N*/ }


/*N*/ void ScEditEngineDefaulter::SetText( const String& rText )
/*N*/ {
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( FALSE );
/*N*/   EditEngine::SetText( rText );
/*N*/   if ( pDefaults )
/*?*/       SetDefaults( *pDefaults, FALSE );
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( TRUE );
/*N*/ }

/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText,
/*N*/           const SfxItemSet& rSet, BOOL bRememberCopy )
/*N*/ {
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( FALSE );
/*N*/   EditEngine::SetText( rText );
/*N*/   SetDefaults( rSet, bRememberCopy );
/*N*/   if ( bUpdateMode )
/*N*/       SetUpdateMode( TRUE );
/*N*/ }

/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText,
/*N*/           SfxItemSet* pSet, BOOL bTakeOwnership )
/*N*/ {
/*N*/   BOOL bUpdateMode = GetUpdateMode();
/*N*/   if ( bUpdateMode )
/*?*/       SetUpdateMode( FALSE );
/*N*/   EditEngine::SetText( rText );
/*N*/   SetDefaults( pSet, bTakeOwnership );
/*N*/   if ( bUpdateMode )
/*?*/       SetUpdateMode( TRUE );
/*N*/ }



//------------------------------------------------------------------------
//      Feldbefehle fuer Kopf- und Fusszeilen
//------------------------------------------------------------------------

//
//      Zahlen aus \sw\source\core\doc\numbers.cxx
//



/*N*/ String lcl_GetNumStr( USHORT nNo, SvxNumType eType )
/*N*/ {
/*N*/   String aTmpStr( '0' );
/*N*/   if( nNo )
/*N*/   {
/*N*/       switch( eType )
/*N*/       {
/*?*/       case SVX_CHARS_UPPER_LETTER:
/*?*/       case SVX_CHARS_LOWER_LETTER:
/*?*/           break;
/*?*/
/*?*/       case SVX_ROMAN_UPPER:
/*?*/       case SVX_ROMAN_LOWER:
/*?*/           break;
/*?*/
/*?*/       case SVX_NUMBER_NONE:
/*?*/           aTmpStr.Erase();
/*?*/           break;
/*?*/
/*N*/       default:
/*N*/           aTmpStr = String::CreateFromInt32( nNo );
/*N*/           break;
/*N*/       }
/*N*/
/*N*/       if( SVX_CHARS_UPPER_LETTER == eType || SVX_ROMAN_UPPER == eType )
/*N*/           aTmpStr.ToUpperAscii();
/*N*/   }
/*N*/   return aTmpStr;
/*N*/ }

/*N*/ ScHeaderFieldData::ScHeaderFieldData()
        :
            aDate( Date::EMPTY ),
            aTime( Time::EMPTY )
/*N*/ {
/*N*/   nPageNo = nTotalPages = 0;
/*N*/   eNumType = SVX_ARABIC;
/*N*/ }

/*N*/ ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pInEnginePool, BOOL bInDeleteEnginePool )
/*N*/       : ScEditEngineDefaulter( pInEnginePool, bInDeleteEnginePool )
/*N*/ {
/*N*/ }

/*N*/ String ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
/*N*/                                   USHORT /*nPara*/, USHORT /*nPos*/,
/*N*/                                   Color*& /*rTxtColor*/, Color*& /*rFldColor*/ )
/*N*/ {
/*N*/   String aRet;
/*N*/   const SvxFieldData* pFieldData = rField.GetField();
/*N*/   if ( pFieldData )
/*N*/   {
/*N*/       TypeId aType = pFieldData->Type();
/*N*/       if (aType == TYPE(SvxPageField))
/*N*/           aRet = lcl_GetNumStr( (USHORT)aData.nPageNo,aData.eNumType );
/*N*/       else if (aType == TYPE(SvxPagesField))
/*?*/           aRet = lcl_GetNumStr( (USHORT)aData.nTotalPages,aData.eNumType );
/*N*/       else if (aType == TYPE(SvxTimeField))
/*N*/             aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
/*N*/       else if (aType == TYPE(SvxFileField))
/*N*/           aRet = aData.aTitle;
/*N*/       else if (aType == TYPE(SvxExtFileField))
/*N*/       {
/*?*/           switch ( ((const SvxExtFileField*)pFieldData)->GetFormat() )
/*?*/           {
/*?*/               case SVXFILEFORMAT_FULLPATH :
/*?*/                   aRet = aData.aLongDocName;
/*?*/               break;
/*?*/               default:
/*?*/                   aRet = aData.aShortDocName;
/*?*/           }
/*N*/       }
/*N*/       else if (aType == TYPE(SvxTableField))
/*N*/           aRet = aData.aTabName;
/*N*/       else if (aType == TYPE(SvxDateField))
/*N*/             aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
/*N*/       else
/*N*/       {
/*N*/           //OSL_FAIL("unbekannter Feldbefehl");
/*N*/           aRet = '?';
/*N*/       }
/*N*/   }
/*N*/   else
/*N*/   {
            // #i75599# no assertion - can happen with old files
/*N*/       //OSL_FAIL("FieldData ist 0");
/*N*/       aRet = '?';
/*N*/   }
/*N*/
/*N*/   return aRet;
/*N*/ }

//------------------------------------------------------------------------
//
//                          Feld-Daten
//
//------------------------------------------------------------------------

/*N*/ ScFieldEditEngine::ScFieldEditEngine( SfxItemPool* pInEnginePool,
/*N*/           SfxItemPool* pTextObjectPool, BOOL bInDeleteEnginePool )
/*N*/       :
/*N*/       ScEditEngineDefaulter( pInEnginePool, bInDeleteEnginePool ),
/*N*/       bExecuteURL( TRUE )
/*N*/ {
/*N*/   if ( pTextObjectPool )
/*N*/       SetEditTextObjectPool( pTextObjectPool );
/*N*/   //  EE_CNTRL_URLSFXEXECUTE nicht, weil die Edit-Engine den ViewFrame nicht kennt
/*N*/   // wir haben keine StyleSheets fuer Text
/*N*/   SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
/*N*/ }

/*N*/ String ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
/*N*/                                   USHORT /*nPara*/, USHORT /*nPos*/,
/*N*/                                   Color*& rTxtColor, Color*& /*rFldColor*/ )
/*N*/ {
/*N*/   String aRet;
/*N*/   const SvxFieldData* pFieldData = rField.GetField();
/*N*/
/*N*/   if ( pFieldData )
/*N*/   {
/*N*/       TypeId aType = pFieldData->Type();
/*N*/
/*N*/       if (aType == TYPE(SvxURLField))
/*N*/       {
/*N*/           String aURL = ((const SvxURLField*)pFieldData)->GetURL();
/*N*/
/*N*/           switch ( ((const SvxURLField*)pFieldData)->GetFormat() )
/*N*/           {
/*N*/               case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
/*N*/               case SVXURLFORMAT_REPR:
/*N*/                   aRet = ((const SvxURLField*)pFieldData)->GetRepresentation();
/*N*/                   break;
/*N*/
/*N*/               case SVXURLFORMAT_URL:
/*N*/                   aRet = aURL;
/*N*/                   break;
/*N*/           }
/*N*/
                    ColorConfigEntry eEntry = INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? LINKSVISITED : LINKS;
/*N*/           rTxtColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
/*N*/       }
/*N*/       else
/*N*/       {
/*N*/           //OSL_FAIL("unbekannter Feldbefehl");
/*N*/           aRet = '?';
/*N*/       }
/*N*/   }
/*N*/
/*N*/   if (!aRet.Len())        // leer ist baeh
/*N*/       aRet = ' ';         // Space ist Default der Editengine
/*N*/
/*N*/   return aRet;
/*N*/ }


}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
