[ooo-build-commit] Branch 'ooo/master' - sc/inc sc/source

Jan Holesovsky kendy at kemper.freedesktop.org
Wed Jul 29 10:19:07 PDT 2009


 sc/inc/cellsuno.hxx                               |   36 +-
 sc/inc/compiler.hxx                               |   31 +-
 sc/inc/conditio.hxx                               |   23 +
 sc/inc/document.hxx                               |   12 
 sc/inc/fmtuno.hxx                                 |   45 +--
 sc/inc/formulaparserpool.hxx                      |   70 +++++
 sc/inc/tokenuno.hxx                               |   22 +
 sc/inc/unonames.hxx                               |    6 
 sc/inc/validat.hxx                                |    6 
 sc/source/core/data/cell.cxx                      |    6 
 sc/source/core/data/conditio.cxx                  |   50 ++-
 sc/source/core/data/documen2.cxx                  |   13 
 sc/source/core/data/documen3.cxx                  |   14 -
 sc/source/core/data/validat.cxx                   |    7 
 sc/source/core/tool/compiler.cxx                  |  108 ++++++-
 sc/source/core/tool/formulaparserpool.cxx         |  171 ++++++++++++
 sc/source/core/tool/makefile.mk                   |    4 
 sc/source/filter/xml/XMLConverter.cxx             |  304 +++++++++++++++++++++-
 sc/source/filter/xml/XMLConverter.hxx             |   58 ++++
 sc/source/filter/xml/XMLTrackedChangesContext.cxx |   24 -
 sc/source/filter/xml/xmlcelli.cxx                 |   42 +--
 sc/source/filter/xml/xmlcelli.hxx                 |    3 
 sc/source/filter/xml/xmlcvali.cxx                 |  291 +++++++--------------
 sc/source/filter/xml/xmlimprt.cxx                 |   81 +++--
 sc/source/filter/xml/xmlimprt.hxx                 |   80 ++---
 sc/source/filter/xml/xmlnexpi.cxx                 |   17 -
 sc/source/filter/xml/xmlstyli.cxx                 |  244 +++++------------
 sc/source/filter/xml/xmlstyli.hxx                 |   30 +-
 sc/source/filter/xml/xmlsubti.cxx                 |   17 -
 sc/source/filter/xml/xmlsubti.hxx                 |    8 
 sc/source/ui/docshell/docfunc.cxx                 |   42 +--
 sc/source/ui/docshell/docsh3.cxx                  |    4 
 sc/source/ui/formdlg/formula.cxx                  |   23 +
 sc/source/ui/inc/docfunc.hxx                      |    4 
 sc/source/ui/inc/formula.hxx                      |    7 
 sc/source/ui/unoobj/cellsuno.cxx                  |   33 +-
 sc/source/ui/unoobj/fmtuno.cxx                    |  151 +++++++---
 sc/source/ui/unoobj/tokenuno.cxx                  |   51 +--
 sc/source/ui/view/viewfunc.cxx                    |    2 
 39 files changed, 1374 insertions(+), 766 deletions(-)

New commits:
commit 8db622fc0307b21084742e816116d2e9d8dabb68
Author: Jens-Heiner Rechtien <hr at openoffice.org>
Date:   Wed Jul 29 14:46:52 2009 +0000

    CWS-TOOLING: integrate CWS dr71
    2009-07-07 16:26:00 +0200 dr  r273805 : #i10000# unused variables
    2009-07-07 10:27:14 +0200 dr  r273780 : CWS-TOOLING: rebase CWS dr71 to trunk at 273468 (milestone: DEV300:m51)
    2009-07-01 11:28:24 +0200 dr  r273559 : #101471# special handling for XL library functions in ODF formulas (EUROCONVERT)
    2009-06-29 17:48:46 +0200 dr  r273478 : #i101471# typo
    2009-06-29 17:35:16 +0200 dr  r273477 : #i101471# import msoxl: formulas from conditional formatting and data validation
    2009-06-18 13:45:17 +0200 dr  r273115 : #101471# changed interface css.sheet.XFormulaParser
    2009-06-18 13:44:43 +0200 dr  r273114 : #101471# changed interface css.sheet.XFormulaParser
    2009-06-17 17:29:23 +0200 dr  r273089 : #i101471# extend the XFormulaParser interface with a ReferencePosition parameter, make rel-refs from msoxl: namespace working
    2009-06-17 17:28:39 +0200 dr  r273088 : #i101471# extend the XFormulaParser interface with a ReferencePosition parameter
    2009-06-17 17:28:19 +0200 dr  r273087 : #i101471# extend the XFormulaParser interface with a ReferencePosition parameter
    2009-06-17 17:27:19 +0200 dr  r273086 : #i101471# extend the XFormulaParser interface with a ReferencePosition parameter, remove that property from FormulaParser service
    2009-06-17 12:52:20 +0200 dr  r273059 : #i101471# import cell formulas from msoxl: namespace
    2009-06-16 11:40:50 +0200 dr  r273013 : #i101471# import formula namespace from xml elements
    2009-06-12 18:34:13 +0200 dr  r272935 : #i101471# external formula parser for oox in odf
    2009-06-12 18:33:13 +0200 dr  r272934 : #i101471# external formula parsers
    2009-06-12 18:29:46 +0200 dr  r272933 : #i101471# external formula parsers
    2009-06-05 15:53:47 +0200 dr  r272705 : #i101471# provide OOX formula parser as UNO service

diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx
index 1eb76e8..7c47691 100644
--- a/sc/inc/cellsuno.hxx
+++ b/sc/inc/cellsuno.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -152,7 +152,7 @@ public:
 namespace ooo
 {
     namespace vba {
-    class ScVbaCellRangeAccess;  // Vba Helper class 
+    class ScVbaCellRangeAccess;  // Vba Helper class
     }
 }
 
@@ -328,16 +328,16 @@ public:
                                 throw (::com::sun::star::uno::RuntimeException);
 
                             // XTolerantMultiPropertySet
-    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::SetPropertyTolerantFailed > SAL_CALL 
-        setPropertyValuesTolerant( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, 
-                                    const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) 
+    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::SetPropertyTolerantFailed > SAL_CALL
+        setPropertyValuesTolerant( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames,
+                                    const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues )
                                     throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
-    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::GetPropertyTolerantResult > SAL_CALL 
-        getPropertyValuesTolerant( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) 
-                                    throw (::com::sun::star::uno::RuntimeException); 
-    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::GetDirectPropertyTolerantResult > SAL_CALL 
-        getDirectPropertyValuesTolerant( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) 
-                                    throw (::com::sun::star::uno::RuntimeException); 
+    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::GetPropertyTolerantResult > SAL_CALL
+        getPropertyValuesTolerant( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames )
+                                    throw (::com::sun::star::uno::RuntimeException);
+    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::GetDirectPropertyTolerantResult > SAL_CALL
+        getDirectPropertyValuesTolerant( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames )
+                                    throw (::com::sun::star::uno::RuntimeException);
 
                             // XPropertyState
     virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState(
@@ -629,9 +629,10 @@ protected:
                                 throw(::com::sun::star::lang::IndexOutOfBoundsException,
                                     ::com::sun::star::uno::RuntimeException);
 
-            void            SetArrayFormula_Impl( const rtl::OUString& aFormula,
-                                                    const formula::FormulaGrammar::Grammar eGrammar )
-                                throw(::com::sun::star::uno::RuntimeException);
+            void            SetArrayFormula_Impl( const rtl::OUString& rFormula,
+                                const rtl::OUString& rFormulaNmsp,
+                                const formula::FormulaGrammar::Grammar eGrammar )
+                                    throw(::com::sun::star::uno::RuntimeException);
 
 public:
                             ScCellRangeObj(ScDocShell* pDocSh, const ScRange& rR);
@@ -650,7 +651,8 @@ public:
     virtual void			RefChanged();
 
                             // via getImplementation()
-    virtual void            SetArrayFormulaWithGrammar( const ::rtl::OUString& aFormula,
+    virtual void            SetArrayFormulaWithGrammar( const ::rtl::OUString& rFormula,
+                                    const ::rtl::OUString& rFormulaNmsp,
                                     const formula::FormulaGrammar::Grammar )
                                 throw(::com::sun::star::uno::RuntimeException);
 
@@ -786,7 +788,7 @@ public:
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL
                             getCellRangeByName( const ::rtl::OUString& aRange )
                                 throw(::com::sun::star::uno::RuntimeException);
-    ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > 
+    ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
                             getCellRangeByName( const ::rtl::OUString& aRange,  const ScAddress::Details& rDetails )
                                 throw(::com::sun::star::uno::RuntimeException);
 
@@ -869,7 +871,7 @@ public:
     void					SetFormulaResultString( const ::rtl::OUString& rResult );
     void					SetFormulaResultDouble( double fResult );
     void                    SetFormulaWithGrammar( const ::rtl::OUString& rFormula,
-                                                    const formula::FormulaGrammar::Grammar );
+                                const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar );
     const ScAddress&		GetPosition() const { return aCellPos; }
 
                             // XText
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 39a2e2c..0b48742 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -235,9 +235,9 @@ public:
                                    xub_StrLen nSrcPos,
                                    const CharClass* pCharClass) const = 0;
 
-        /** 
-         * Parse the symbol string and pick up the file name and the external 
-         * range name. 
+        /**
+         * Parse the symbol string and pick up the file name and the external
+         * range name.
          *
          * @return true on successful parse, or false otherwise.
          */
@@ -249,18 +249,18 @@ public:
         virtual String makeExternalNameStr( const String& rFile, const String& rName ) const = 0;
 
         virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-                                         sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef, 
+                                         sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef,
                                          ScExternalRefManager* pRefMgr ) const = 0;
 
         virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-                                         sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef, 
+                                         sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef,
                                          ScExternalRefManager* pRefMgr ) const = 0;
 
         enum SpecialSymbolType
         {
-            /** 
-             * Character between sheet name and address.  In OOO A1 this is 
-             * '.', while XL A1 and XL R1C1 this is '!'. 
+            /**
+             * Character between sheet name and address.  In OOO A1 this is
+             * '.', while XL A1 and XL R1C1 this is '!'.
              */
             SHEET_SEPARATOR,
 
@@ -276,7 +276,7 @@ public:
 
 private:
 
-    
+
     static CharClass            *pCharClassEnglish;                      // character classification for en_US locale
     static const Convention     *pConventions[ formula::FormulaGrammar::CONV_LAST ];
 
@@ -307,7 +307,7 @@ private:
     String      aFormula;                           // formula source code
     xub_StrLen  nSrcPos;                            // tokenizer position (source code)
     ScRawTokenRef   pRawToken;
-    
+
     const CharClass*    pCharClass;         // which character classification is used for parseAnyToken
     USHORT      mnPredetectedReference;     // reference when reading ODF, 0 (none), 1 (single) or 2 (double)
     SCsTAB      nMaxTab;                    // last sheet in document
@@ -354,11 +354,11 @@ public:
                                 const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO );
 
     static BOOL EnQuote( String& rStr );
-    
     sal_Unicode GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const;
 
+
     // Check if it is a valid english function name
-    bool IsEnglishSymbol( const String& rName ); 
+    bool IsEnglishSymbol( const String& rName );
 
     //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both
     // #i101512# SetCompileForFAP is in formula::FormulaCompiler
@@ -376,7 +376,7 @@ public:
 private:
     /** Set grammar and reference convention from within SetFormulaLanguage()
         or SetGrammar().
-        
+
         @param eNewGrammar
             The new grammar to be set and the associated reference convention.
 
@@ -396,6 +396,8 @@ public:
         maExternalLinks = rLinks;
     }
 
+    void            CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp );
+
     void            SetExtendedErrorDetection( bool bVal ) { mbExtendedErrorDetection = bVal; }
 
     BOOL            IsCorrected() { return bCorrected; }
@@ -403,6 +405,7 @@ public:
 
     // Use convention from this->aPos by default
     ScTokenArray* CompileString( const String& rFormula );
+    ScTokenArray* CompileString( const String& rFormula, const String& rFormulaNmsp );
     const ScDocument* GetDoc() const { return pDoc; }
     const ScAddress& GetPos() const { return aPos; }
 
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 7ee308d..a9b2a6f 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -84,7 +84,10 @@ class SC_DLLPUBLIC ScConditionEntry
     double				nVal2;
     String				aStrVal1;		// eingegeben oder berechnet
     String				aStrVal2;
-    formula::FormulaGrammar::Grammar  eTempGrammar;   // grammar to be used on (re)compilation, e.g. in XML import
+    String              aStrNmsp1;      // namespace to be used on (re)compilation, e.g. in XML import
+    String              aStrNmsp2;      // namespace to be used on (re)compilation, e.g. in XML import
+    formula::FormulaGrammar::Grammar eTempGrammar1;  // grammar to be used on (re)compilation, e.g. in XML import
+    formula::FormulaGrammar::Grammar eTempGrammar2;  // grammar to be used on (re)compilation, e.g. in XML import
     BOOL				bIsStr1;		// um auch leere Strings zu erkennen
     BOOL				bIsStr2;
     ScTokenArray*		pFormula1;		// eingegebene Formel
@@ -101,7 +104,10 @@ class SC_DLLPUBLIC ScConditionEntry
 
     void	MakeCells( const ScAddress& rPos );
     void	Compile( const String& rExpr1, const String& rExpr2,
-                        const formula::FormulaGrammar::Grammar eGrammar, BOOL bTextToReal );
+                        const String& rExprNmsp1, const String& rExprNmsp2,
+                        formula::FormulaGrammar::Grammar eGrammar1,
+                        formula::FormulaGrammar::Grammar eGrammar2,
+                        BOOL bTextToReal );
     void	Interpret( const ScAddress& rPos );
 
     BOOL	IsValid( double nArg ) const;
@@ -111,7 +117,9 @@ public:
             ScConditionEntry( ScConditionMode eOper,
                                 const String& rExpr1, const String& rExpr2,
                                 ScDocument* pDocument, const ScAddress& rPos,
-                                const formula::FormulaGrammar::Grammar eGrammar );
+                                const String& rExprNmsp1, const String& rExprNmsp2,
+                                formula::FormulaGrammar::Grammar eGrammar1,
+                                formula::FormulaGrammar::Grammar eGrammar2 );
             ScConditionEntry( ScConditionMode eOper,
                                 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                 ScDocument* pDocument, const ScAddress& rPos );
@@ -174,7 +182,10 @@ public:
                                 const String& rExpr1, const String& rExpr2,
                                 ScDocument* pDocument, const ScAddress& rPos,
                                 const String& rStyle,
-                                const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT );
+                                const String& rExprNmsp1 = EMPTY_STRING,
+                                const String& rExprNmsp2 = EMPTY_STRING,
+                                formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
+                                formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
             ScCondFormatEntry( ScConditionMode eOper,
                                 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                 ScDocument* pDocument, const ScAddress& rPos,
@@ -285,7 +296,7 @@ public:
 
     void	SourceChanged( const ScAddress& rAddr );
 
-    /** Temporarily during save, returns RefManager's decision whether ALL 
+    /** Temporarily during save, returns RefManager's decision whether ALL
      *  references are marked now. */
     bool    MarkUsedExternalReferences() const;
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d7bbc47..81da5f6 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -139,6 +139,7 @@ class ScTemporaryChartLock;
 class ScLookupCache;
 struct ScLookupCacheMapImpl;
 class SfxUndoManager;
+class ScFormulaParserPool;
 
 namespace com { namespace sun { namespace star {
     namespace lang {
@@ -291,6 +292,11 @@ private:
     ::std::auto_ptr<ScDocProtection> pDocProtection;
 
     ::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
+
+    // mutable for lazy construction
+    mutable ::std::auto_ptr< ScFormulaParserPool >
+                        mxFormulaParserPool;            /// Pool for all external formula parsers used by this document.
+
     String              aDocName;                       // opt: Dokumentname
     ScRangePairListRef	xColNameRanges;
     ScRangePairListRef	xRowNameRanges;
@@ -619,6 +625,10 @@ public:
     void            MarkUsedExternalReferences();
     bool            MarkUsedExternalReferences( ScTokenArray & rArr );
 
+    /** Returns the pool containing external formula parsers. Creates the pool
+        on first call. */
+    ScFormulaParserPool& GetFormulaParserPool() const;
+
     BOOL			HasDdeLinks() const;
     BOOL			HasAreaLinks() const;
     void            UpdateExternalRefLinks();
@@ -933,7 +943,7 @@ public:
     BOOL			IsClipboard() const 						{ return bIsClip; }
     bool			IsUndoEnabled() const						{ return mbUndoEnabled; }
     void            EnableUndo( bool bVal );
-    
+
     bool            IsAdjustHeightEnabled() const               { return mbAdjustHeightEnabled; }
     void            EnableAdjustHeight( bool bVal )             { mbAdjustHeightEnabled = bVal; }
     bool            IsExecuteLinkEnabled() const                { return mbExecuteLinkEnabled; }
diff --git a/sc/inc/fmtuno.hxx b/sc/inc/fmtuno.hxx
index 9f1e988..5300f60 100644
--- a/sc/inc/fmtuno.hxx
+++ b/sc/inc/fmtuno.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -32,7 +32,8 @@
 #define SC_FMTUNO_HXX
 
 #include "address.hxx"
-#include "formula/grammar.hxx"
+#include "conditio.hxx"
+#include <formula/grammar.hxx>
 #include <tools/list.hxx>
 #include <svtools/itemprop.hxx>
 #include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
@@ -61,16 +62,19 @@ struct ScCondFormatEntryItem
 {
     ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > maTokens1;
     ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > maTokens2;
-    String             maExpr1;
-    String             maExpr2;
-    String             maPosStr;  // formula position as text
-    String             maStyle;   // display name as stored in ScStyleSheet
-    ScAddress          maPos;
-    formula::FormulaGrammar::Grammar meGrammar; // grammar used with maExpr1 and maExpr2
-    USHORT             mnMode;    // stores enum ScConditionMode
+    String              maExpr1;
+    String              maExpr2;
+    String              maExprNmsp1;
+    String              maExprNmsp2;
+    String              maPosStr;  // formula position as text
+    String              maStyle;   // display name as stored in ScStyleSheet
+    ScAddress           maPos;
+    formula::FormulaGrammar::Grammar meGrammar1; // grammar used with maExpr1
+    formula::FormulaGrammar::Grammar meGrammar2; // grammar used with maExpr2
+    ScConditionMode     meMode;
 
     // Make sure the grammar is initialized for API calls.
-    ScCondFormatEntryItem() : meGrammar( formula::FormulaGrammar::GRAM_UNSPECIFIED ) {}
+    ScCondFormatEntryItem();
 };
 
 class ScTableConditionalFormat : public cppu::WeakImplHelper5<
@@ -89,11 +93,11 @@ private:
     ScTableConditionalFormat(); // disable
 public:
                             ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
-                                                        const formula::FormulaGrammar::Grammar eGrammar);
+                                formula::FormulaGrammar::Grammar eGrammar);
     virtual					~ScTableConditionalFormat();
 
-    void					FillFormat( ScConditionalFormat& rFormat,
-                                            ScDocument* pDoc, formula::FormulaGrammar::Grammar eGrammar ) const;
+    void                    FillFormat( ScConditionalFormat& rFormat, ScDocument* pDoc,
+                                formula::FormulaGrammar::Grammar eGrammar) const;
     void					DataChanged();
 
                             // XSheetConditionalEntries
@@ -161,7 +165,7 @@ private:
 
     ScTableConditionalEntry(); // disabled
 public:
-                            ScTableConditionalEntry(ScTableConditionalFormat* pPar, 
+                            ScTableConditionalEntry(ScTableConditionalFormat* pPar,
                                                     const ScCondFormatEntryItem& aItem);
     virtual					~ScTableConditionalEntry();
 
@@ -211,7 +215,10 @@ private:
     USHORT				nMode;			// enum ScConditionMode
     String				aExpr1;
     String				aExpr2;
-    formula::FormulaGrammar::Grammar  meGrammar;      // grammar used with aExpr1 and aExpr2
+    String              maExprNmsp1;
+    String              maExprNmsp2;
+    formula::FormulaGrammar::Grammar  meGrammar1;      // grammar used with aExpr1 and aExpr2
+    formula::FormulaGrammar::Grammar  meGrammar2;      // grammar used with aExpr1 and aExpr2
     ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > aTokens1;
     ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > aTokens2;
     ScAddress			aSrcPos;
@@ -256,14 +263,14 @@ public:
                                 throw(::com::sun::star::uno::RuntimeException);
 
                             // XMultiFormulaTokens
-    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > 
-                            SAL_CALL getTokens( sal_Int32 nIndex ) 
+    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >
+                            SAL_CALL getTokens( sal_Int32 nIndex )
                                 throw(::com::sun::star::uno::RuntimeException,::com::sun::star::lang::IndexOutOfBoundsException);
-    virtual void SAL_CALL setTokens( sal_Int32 nIndex, 
+    virtual void SAL_CALL setTokens( sal_Int32 nIndex,
                                      const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& aTokens )
                                 throw(::com::sun::star::uno::RuntimeException,::com::sun::star::lang::IndexOutOfBoundsException);
     virtual sal_Int32 SAL_CALL getCount() throw(::com::sun::star::uno::RuntimeException);
-                    
+
                             // XPropertySet
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
                             SAL_CALL getPropertySetInfo()
diff --git a/sc/inc/formulaparserpool.hxx b/sc/inc/formulaparserpool.hxx
new file mode 100644
index 0000000..af6b0ed
--- /dev/null
+++ b/sc/inc/formulaparserpool.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: formulaparserpool.hxx,v $
+ * $Revision: 1.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMULAPARSERPOOL_HXX
+#define SC_FORMULAPARSERPOOL_HXX
+
+#include <hash_map>
+#include <com/sun/star/sheet/XFormulaParser.hpp>
+
+class ScDocument;
+
+// ============================================================================
+
+/** Stores the used instances of the FilterFormulaParser service
+    implementations, mapped by the formula namespace they support. */
+class ScFormulaParserPool
+{
+public:
+    explicit            ScFormulaParserPool( const ScDocument& rDoc );
+                        ~ScFormulaParserPool();
+
+    /** Returns true, if a formula parser is registered for the passed namespace. */
+    bool                hasFormulaParser( const ::rtl::OUString& rNamespace );
+
+    /** Returns the formula parser that is registered for the passed namespace. */
+    ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser >
+                        getFormulaParser( const ::rtl::OUString& rNamespace );
+
+private:
+    typedef ::std::hash_map<
+        ::rtl::OUString,
+        ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser >,
+        ::rtl::OUStringHash,
+        ::std::equal_to< ::rtl::OUString > > ParserMap;
+
+    const ScDocument&   mrDoc;
+    ParserMap           maParsers;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/inc/tokenuno.hxx b/sc/inc/tokenuno.hxx
index c686872..bcd3435 100644
--- a/sc/inc/tokenuno.hxx
+++ b/sc/inc/tokenuno.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -31,15 +31,14 @@
 #ifndef SC_TOKENUNO_HXX
 #define SC_TOKENUNO_HXX
 
-#include <svtools/lstner.hxx>
-#include <com/sun/star/sheet/FormulaToken.hpp>
 #include <com/sun/star/uno/Sequence.hxx>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/sheet/XFormulaParser.hpp>
-#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
 #include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
+#include <com/sun/star/sheet/FormulaToken.hpp>
+#include <com/sun/star/sheet/XFormulaParser.hpp>
 #include <cppuhelper/implbase3.hxx>
+#include <svtools/lstner.hxx>
 #include <formula/FormulaOpCodeMapperObj.hxx>
 #include "address.hxx"
 #include "compiler.hxx"
@@ -47,6 +46,7 @@
 class ScTokenArray;
 class ScDocShell;
 
+// ============================================================================
 
 class ScTokenConversion
 {
@@ -61,6 +61,7 @@ public:
                         const ScTokenArray& rTokenArray );
 };
 
+// ============================================================================
 
 class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
                             ::com::sun::star::sheet::XFormulaParser,
@@ -73,7 +74,6 @@ private:
     ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks;
     ScCompiler::OpCodeMapPtr    mxOpCodeMap;
     ScDocShell*         mpDocShell;
-    ScAddress           maRefPos;
     sal_Int16           mnConv;
     bool                mbEnglish;
     bool                mbIgnoreSpaces;
@@ -89,10 +89,12 @@ public:
 
                             // XFormulaParser
     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL parseFormula(
-                                    const ::rtl::OUString& aFormula )
+                                    const ::rtl::OUString& aFormula,
+                                    const ::com::sun::star::table::CellAddress& rReferencePos )
                                 throw (::com::sun::star::uno::RuntimeException);
     virtual ::rtl::OUString SAL_CALL printFormula( const ::com::sun::star::uno::Sequence<
-                                    ::com::sun::star::sheet::FormulaToken >& aTokens )
+                                    ::com::sun::star::sheet::FormulaToken >& aTokens,
+                                    const ::com::sun::star::table::CellAddress& rReferencePos )
                                 throw (::com::sun::star::uno::RuntimeException);
 
                             // XPropertySet
@@ -145,11 +147,15 @@ public:
                                 throw(::com::sun::star::uno::RuntimeException);
 };
 
+// ============================================================================
+
 class ScFormulaOpCodeMapperObj : public formula::FormulaOpCodeMapperObj
 {
 public:
     ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler);
 };
 
+// ============================================================================
+
 #endif
 
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index 9df643f..c7ce536 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -318,7 +318,10 @@
 #define SC_UNONAME_FORMULA2			"Formula2"
 #define SC_UNONAME_SOURCEPOS		"SourcePosition"
 #define SC_UNONAME_SOURCESTR        "SourcePositionAsString" // only for use in XML filter
-#define SC_UNONAME_GRAMMAR          "Grammar" // only for use in XML filter
+#define SC_UNONAME_FORMULANMSP1     "FormulaNamespace1" // only for use in XML filter
+#define SC_UNONAME_FORMULANMSP2     "FormulaNamespace2" // only for use in XML filter
+#define SC_UNONAME_GRAMMAR1         "Grammar1" // only for use in XML filter
+#define SC_UNONAME_GRAMMAR2         "Grammar2" // only for use in XML filter
 #define SC_UNONAME_STYLENAME		"StyleName"
 
 //	validation
@@ -599,7 +602,6 @@
 // <--
 
 // FormulaParser
-#define SC_UNO_REFERENCEPOS         "ReferencePosition"
 #define SC_UNO_COMPILEENGLISH       "CompileEnglish"
 #define SC_UNO_FORMULACONVENTION    "FormulaConvention"
 #define SC_UNO_IGNORELEADING        "IgnoreLeadingSpaces"
diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx
index 44b7390..ee2a848 100644
--- a/sc/inc/validat.hxx
+++ b/sc/inc/validat.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -93,7 +93,9 @@ public:
             ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                 const String& rExpr1, const String& rExpr2,
                                 ScDocument* pDocument, const ScAddress& rPos,
-                                const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT );
+                                const String& rExprNmsp1 = EMPTY_STRING, const String& rExprNmsp2 = EMPTY_STRING,
+                                formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
+                                formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
             ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                 ScDocument* pDocument, const ScAddress& rPos );
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 08f201d..99bf993 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1016,15 +1016,15 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
 
     ScCompiler aComp( pDocument, aPos, *pCode);
     aComp.SetGrammar(eTempGrammar);
-    String aFormula;
-    aComp.CreateStringFromTokenArray( aFormula );
+    String aFormula, aFormulaNmsp;
+    aComp.CreateStringFromXMLTokenArray( aFormula, aFormulaNmsp );
     pDocument->DecXMLImportedFormulaCount( aFormula.Len() );
     rProgress.SetStateCountDownOnPercent( pDocument->GetXMLImportedFormulaCount() );
     // pCode darf fuer Abfragen noch nicht geloescht, muss aber leer sein
     if ( pCode )
         pCode->Clear();
     ScTokenArray* pCodeOld = pCode;
-    pCode = aComp.CompileString( aFormula );
+    pCode = aComp.CompileString( aFormula, aFormulaNmsp );
     delete pCodeOld;
     if( !pCode->GetCodeError() )
     {
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 50fb22a..b47b300 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -130,7 +130,10 @@ ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
     nVal2(r.nVal2),
     aStrVal1(r.aStrVal1),
     aStrVal2(r.aStrVal2),
-    eTempGrammar(r.eTempGrammar),
+    aStrNmsp1(r.aStrNmsp1),
+    aStrNmsp2(r.aStrNmsp2),
+    eTempGrammar1(r.eTempGrammar1),
+    eTempGrammar2(r.eTempGrammar2),
     bIsStr1(r.bIsStr1),
     bIsStr2(r.bIsStr2),
     pFormula1(NULL),
@@ -161,7 +164,10 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr
     nVal2(r.nVal2),
     aStrVal1(r.aStrVal1),
     aStrVal2(r.aStrVal2),
-    eTempGrammar(r.eTempGrammar),
+    aStrNmsp1(r.aStrNmsp1),
+    aStrNmsp2(r.aStrNmsp2),
+    eTempGrammar1(r.eTempGrammar1),
+    eTempGrammar2(r.eTempGrammar2),
     bIsStr1(r.bIsStr1),
     bIsStr2(r.bIsStr2),
     pFormula1(NULL),
@@ -187,14 +193,17 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr
 }
 
 ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
-                                const String& rExpr1, const String& rExpr2,
-                                ScDocument* pDocument, const ScAddress& rPos,
-                                const FormulaGrammar::Grammar eGrammar ) :
+        const String& rExpr1, const String& rExpr2, ScDocument* pDocument, const ScAddress& rPos,
+        const String& rExprNmsp1, const String& rExprNmsp2,
+        FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
     eOp(eOper),
     nOptions(0),	// spaeter...
     nVal1(0.0),
     nVal2(0.0),
-    eTempGrammar(eGrammar),
+    aStrNmsp1(rExprNmsp1),
+    aStrNmsp2(rExprNmsp2),
+    eTempGrammar1(eGrammar1),
+    eTempGrammar2(eGrammar2),
     bIsStr1(FALSE),
     bIsStr2(FALSE),
     pFormula1(NULL),
@@ -207,7 +216,7 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
     bRelRef2(FALSE),
     bFirstRun(TRUE)
 {
-    Compile( rExpr1, rExpr2, eGrammar, FALSE );
+    Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, FALSE );
 
     //	Formelzellen werden erst bei IsValid angelegt
 }
@@ -219,7 +228,8 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
     nOptions(0),	// spaeter...
     nVal1(0.0),
     nVal2(0.0),
-    eTempGrammar(FormulaGrammar::GRAM_DEFAULT),
+    eTempGrammar1(FormulaGrammar::GRAM_DEFAULT),
+    eTempGrammar2(FormulaGrammar::GRAM_DEFAULT),
     bIsStr1(FALSE),
     bIsStr2(FALSE),
     pFormula1(NULL),
@@ -294,15 +304,16 @@ ScConditionEntry::~ScConditionEntry()
 }
 
 void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
-                                const FormulaGrammar::Grammar eGrammar, BOOL bTextToReal )
+        const String& rExprNmsp1, const String& rExprNmsp2,
+        FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2, BOOL bTextToReal )
 {
     if ( rExpr1.Len() || rExpr2.Len() )
     {
         ScCompiler aComp( pDoc, aSrcPos );
-        aComp.SetGrammar(eGrammar);
 
         if ( rExpr1.Len() )
         {
+            aComp.SetGrammar( eGrammar1 );
             if ( pDoc->IsImportingXML() && !bTextToReal )
             {
                 //	temporary formula string as string tokens
@@ -313,7 +324,7 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
             }
             else
             {
-                pFormula1 = aComp.CompileString( rExpr1 );
+                pFormula1 = aComp.CompileString( rExpr1, rExprNmsp1 );
                 if ( pFormula1->GetLen() == 1 )
                 {
                     // einzelne (konstante Zahl) ?
@@ -339,6 +350,7 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
 
         if ( rExpr2.Len() )
         {
+            aComp.SetGrammar( eGrammar2 );
             if ( pDoc->IsImportingXML() && !bTextToReal )
             {
                 //	temporary formula string as string tokens
@@ -349,7 +361,7 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
             }
             else
             {
-                pFormula2 = aComp.CompileString( rExpr2 );
+                pFormula2 = aComp.CompileString( rExpr2, rExprNmsp2 );
                 if ( pFormula2->GetLen() == 1 )
                 {
                     // einzelne (konstante Zahl) ?
@@ -429,9 +441,9 @@ void ScConditionEntry::CompileXML()
 
     //	Convert the text tokens that were created during XML import into real tokens.
 
-    Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar),
-             GetExpression(aSrcPos, 1, 0, eTempGrammar),
-             eTempGrammar, TRUE );
+    Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
+             GetExpression(aSrcPos, 1, 0, eTempGrammar2),
+             aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, TRUE );
 }
 
 void ScConditionEntry::SetSrcString( const String& rNew )
@@ -1129,8 +1141,10 @@ ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
                                         const String& rExpr1, const String& rExpr2,
                                         ScDocument* pDocument, const ScAddress& rPos,
                                         const String& rStyle,
-                                        const FormulaGrammar::Grammar eGrammar ) :
-    ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, eGrammar ),
+                                        const String& rExprNmsp1, const String& rExprNmsp2,
+                                        FormulaGrammar::Grammar eGrammar1,
+                                        FormulaGrammar::Grammar eGrammar2 ) :
+    ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
     aStyleName( rStyle ),
     pParent( NULL )
 {
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 487b029..cdbc333 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -95,6 +95,7 @@
 #include "lookupcache.hxx"
 #include "externalrefmgr.hxx"
 #include "tabprotection.hxx"
+#include "formulaparserpool.hxx"
 
 // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
 // dtor plus helpers are convenient.
@@ -154,7 +155,6 @@ ScDocument::ScDocument( ScDocumentMode	eMode,
         pScriptTypeData( NULL ),
         pCacheFieldEditEngine( NULL ),
         pDocProtection( NULL ),
-        pExternalRefMgr( NULL ),
         pViewOptions( NULL ),
         pDocOptions( NULL ),
         pExtDocOptions( NULL ),
@@ -384,15 +384,14 @@ ScDocument::~ScDocument()
             pLinkManager->Remove( 0, pLinkManager->GetLinks().Count() );
     }
 
-    if (pExternalRefMgr.get())
-        // Destroy the external ref mgr instance here because it has a timer 
-        // which needs to be stopped before the app closes.
-        pExternalRefMgr.reset(NULL);
+    mxFormulaParserPool.reset();
+    // Destroy the external ref mgr instance here because it has a timer
+    // which needs to be stopped before the app closes.
+    pExternalRefMgr.reset();
 
     ScAddInAsync::RemoveDocument( this );
     ScAddInListener::RemoveDocument( this );
-    delete pChartListenerCollection;	// vor pBASM wg. evtl. Listener!
-    pChartListenerCollection = NULL;
+    DELETEZ( pChartListenerCollection);   // vor pBASM wg. evtl. Listener!
     DELETEZ( pLookupCacheMapImpl);  // before pBASM because of listeners
     // BroadcastAreas vor allen Zellen zerstoeren um unnoetige
     // Einzel-EndListenings der Formelzellen zu vermeiden
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 6143b5b..3f79e2f 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -40,6 +40,7 @@
 #include <sfx2/bindings.hxx>
 #include <sfx2/objsh.hxx>
 #include <svtools/zforlist.hxx>
+#include <svtools/PasswordHelper.hxx>
 #include <vcl/svapp.hxx>
 #include "document.hxx"
 #include "attrib.hxx"
@@ -77,8 +78,8 @@
 #include "drwlayer.hxx"
 #include "unoreflist.hxx"
 #include "listenercalls.hxx"
-#include "svtools/PasswordHelper.hxx"
 #include "tabprotection.hxx"
+#include "formulaparserpool.hxx"
 
 #include <memory>
 
@@ -341,7 +342,7 @@ void ScDocument::GetScenarioFlags( SCTAB nTab, USHORT& rFlags ) const
 BOOL ScDocument::IsLinked( SCTAB nTab ) const
 {
     return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsLinked();
-    // euqivalent to 
+    // euqivalent to
     //if (ValidTab(nTab) && pTab[nTab])
     //	return pTab[nTab]->IsLinked();
     //return FALSE;
@@ -505,10 +506,17 @@ void ScDocument::MarkUsedExternalReferences()
         if (pTab[nTab])
             bAllMarked = pTab[nTab]->MarkUsedExternalReferences();
     }
-    /* NOTE: Conditional formats and validation objects are marked when 
+    /* NOTE: Conditional formats and validation objects are marked when
      * collecting them during export. */
 }
 
+ScFormulaParserPool& ScDocument::GetFormulaParserPool() const
+{
+    if( !mxFormulaParserPool.get() )
+        mxFormulaParserPool.reset( new ScFormulaParserPool( *this ) );
+    return *mxFormulaParserPool;
+}
+
 ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate )
 {
     ScOutlineTable* pVal = NULL;
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index c136b80..77e3e8f 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -76,8 +76,9 @@ SV_IMPL_OP_PTRARR_SORT( ScValidationEntries_Impl, ScValidationDataPtr );
 ScValidationData::ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                             const String& rExpr1, const String& rExpr2,
                             ScDocument* pDocument, const ScAddress& rPos,
-                            const formula::FormulaGrammar::Grammar eGrammar ) :
-    ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, eGrammar ),
+                            const String& rExprNmsp1, const String& rExprNmsp2,
+                            FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
+    ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
     nKey( 0 ),
     eDataMode( eMode ),
     eErrorStyle( SC_VALERR_STOP ),
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 74c8e49..c35e2ef 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -68,11 +68,14 @@
 #include "cell.hxx"
 #include "dociter.hxx"
 #include "docoptio.hxx"
-#include "formula/errorcodes.hxx"
+#include <formula/errorcodes.hxx>
 #include "parclass.hxx"
 #include "autonamecache.hxx"
 #include "externalrefmgr.hxx"
 #include "rangeutl.hxx"
+#include "convuno.hxx"
+#include "tokenuno.hxx"
+#include "formulaparserpool.hxx"
 
 using namespace formula;
 using namespace ::com::sun::star;
@@ -408,28 +411,36 @@ void ScCompiler::InitCharClassEnglish()
 
 void ScCompiler::SetGrammar( const FormulaGrammar::Grammar eGrammar )
 {
-    DBG_ASSERT( eGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "ScCompiler::SetGrammar: don't passFormulaGrammar::GRAM_UNSPECIFIED");
+    DBG_ASSERT( eGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "ScCompiler::SetGrammar: don't pass FormulaGrammar::GRAM_UNSPECIFIED");
     if (eGrammar == GetGrammar())
         return;     // nothing to be done
 
-    FormulaGrammar::Grammar eMyGrammar = eGrammar;
-    const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage( eMyGrammar);
-    OpCodeMapPtr xMap( GetOpCodeMap( nFormulaLanguage));
-    DBG_ASSERT( xMap, "ScCompiler::SetGrammar: unknown formula language");
-    if (!xMap)
+    if( eGrammar == FormulaGrammar::GRAM_EXTERNAL )
     {
-        xMap = GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
-        eMyGrammar = xMap->getGrammar();
+        meGrammar = eGrammar;
+        mxSymbols = GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
     }
+    else
+    {
+        FormulaGrammar::Grammar eMyGrammar = eGrammar;
+        const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage( eMyGrammar);
+        OpCodeMapPtr xMap = GetOpCodeMap( nFormulaLanguage);
+        DBG_ASSERT( xMap, "ScCompiler::SetGrammar: unknown formula language");
+        if (!xMap)
+        {
+            xMap = GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
+            eMyGrammar = xMap->getGrammar();
+        }
 
-    // Save old grammar for call to SetGrammarAndRefConvention().
-    FormulaGrammar::Grammar eOldGrammar = GetGrammar();
-    // This also sets the grammar associated with the map!
-    SetFormulaLanguage( xMap);
+        // Save old grammar for call to SetGrammarAndRefConvention().
+        FormulaGrammar::Grammar eOldGrammar = GetGrammar();
+        // This also sets the grammar associated with the map!
+        SetFormulaLanguage( xMap);
 
-    // Override if necessary.
-    if (eMyGrammar != GetGrammar())
-        SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
+        // Override if necessary.
+        if (eMyGrammar != GetGrammar())
+            SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
+    }
 }
 
 
@@ -3656,6 +3667,21 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
     return true;
 }
 
+void ScCompiler::CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp )
+{
+    bool bExternal = GetGrammar() == FormulaGrammar::GRAM_EXTERNAL;
+    USHORT nExpectedCount = bExternal ? 2 : 1;
+    DBG_ASSERT( pArr->GetLen() == nExpectedCount, "ScCompiler::CreateStringFromXMLTokenArray - wrong number of tokens" );
+    if( pArr->GetLen() == nExpectedCount )
+    {
+        FormulaToken** ppTokens = pArr->GetArray();
+        // string tokens expected, GetString() will assert if token type is wrong
+        rFormula = ppTokens[ 0 ]->GetString();
+        if( bExternal )
+            rFormulaNmsp = ppTokens[ 1 ]->GetString();
+    }
+}
+
 ScTokenArray* ScCompiler::CompileString( const String& rFormula )
 {
 #if 0
@@ -3663,6 +3689,10 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
              rtl::OUStringToOString( rFormula, RTL_TEXTENCODING_UTF8 ).getStr() );
 #endif
 
+    OSL_ENSURE( meGrammar != FormulaGrammar::GRAM_EXTERNAL, "ScCompiler::CompileString - unexpected grammar GRAM_EXTERNAL" );
+    if( meGrammar == FormulaGrammar::GRAM_EXTERNAL )
+        SetGrammar( FormulaGrammar::GRAM_PODF );
+
     ScTokenArray aArr;
     pArr = &aArr;
     aFormula = rFormula;
@@ -3865,6 +3895,34 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
 }
 
 
+ScTokenArray* ScCompiler::CompileString( const String& rFormula, const String& rFormulaNmsp )
+{
+    DBG_ASSERT( (GetGrammar() == FormulaGrammar::GRAM_EXTERNAL) || (rFormulaNmsp.Len() == 0),
+        "ScCompiler::CompileString - unexpected formula namespace for internal grammar" );
+    if( GetGrammar() == FormulaGrammar::GRAM_EXTERNAL ) try
+    {
+        ScFormulaParserPool& rParserPool = pDoc->GetFormulaParserPool();
+        uno::Reference< sheet::XFormulaParser > xParser( rParserPool.getFormulaParser( rFormulaNmsp ), uno::UNO_SET_THROW );
+        table::CellAddress aReferencePos;
+        ScUnoConversion::FillApiAddress( aReferencePos, aPos );
+        uno::Sequence< sheet::FormulaToken > aTokenSeq = xParser->parseFormula( rFormula, aReferencePos );
+        ScTokenArray aTokenArray;
+        if( ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, aTokenSeq ) )
+        {
+            // remember pArr, in case a subsequent CompileTokenArray() is executed.
+            ScTokenArray* pNew = new ScTokenArray( aTokenArray );
+            pArr = pNew;
+            return pNew;
+        }
+    }
+    catch( uno::Exception& )
+    {
+    }
+    // no success - fallback to some internal grammar and hope the best
+    return CompileString( rFormula );
+}
+
+
 BOOL ScCompiler::HandleRange()
 {
     ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() );
@@ -4185,18 +4243,18 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                 {
                     case svExternalSingleRef:
                     case svExternalDoubleRef:
-                        // External references never change their positioning 
-                        // nor point to parts that will be removed or expanded. 
-                        // In fact, calling ScRefUpdate::Update() for URM_MOVE 
-                        // may have negative side effects. Simply adapt 
+                        // External references never change their positioning
+                        // nor point to parts that will be removed or expanded.
+                        // In fact, calling ScRefUpdate::Update() for URM_MOVE
+                        // may have negative side effects. Simply adapt
                         // relative references to the new position.
                         t->CalcRelFromAbs( aPos);
                         break;
                     case svSingleRef:
                         {
-                            if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, 
-                                        aPos, r, nDx, nDy, nDz, 
-                                        SingleDoubleRefModifier( 
+                            if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+                                        aPos, r, nDx, nDy, nDz,
+                                        SingleDoubleRefModifier(
                                             t->GetSingleRef()).Ref())
                                     != UR_NOTHING)
                                 rChanged = TRUE;
@@ -4208,8 +4266,8 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                             SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
                             SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
                             SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
-                            if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, 
-                                        aPos, r, nDx, nDy, nDz, 
+                            if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+                                        aPos, r, nDx, nDy, nDz,
                                         t->GetDoubleRef()) != UR_NOTHING)
                             {
                                 rChanged = TRUE;
diff --git a/sc/source/core/tool/formulaparserpool.cxx b/sc/source/core/tool/formulaparserpool.cxx
new file mode 100644
index 0000000..94259a5
--- /dev/null
+++ b/sc/source/core/tool/formulaparserpool.cxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: formulaparserpool.cxx,v $
+ * $Revision: 1.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "formulaparserpool.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XFilterFormulaParser.hpp>
+#include <rtl/instance.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/objsh.hxx>
+#include "document.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+
+// ============================================================================
+
+namespace {
+
+class ScParserFactoryMap
+{
+public:
+    explicit            ScParserFactoryMap();
+
+    Reference< XFormulaParser > createFormulaParser(
+                            const Reference< XComponent >& rxComponent,
+                            const OUString& rNamespace );
+
+private:
+    typedef ::std::hash_map<
+        OUString,
+        Reference< XSingleComponentFactory >,
+        OUStringHash,
+        ::std::equal_to< OUString > > FactoryMap;
+
+    Reference< XComponentContext > mxContext;   /// Default context of global process factory.
+    FactoryMap          maFactories;            /// All parser factories, mapped by formula namespace.
+};
+
+ScParserFactoryMap::ScParserFactoryMap()
+{
+    try
+    {
+        // get process factory and default component context
+        Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
+        Reference< XPropertySet > xPropSet( xFactory, UNO_QUERY_THROW );
+        mxContext.set( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), UNO_QUERY_THROW );
+
+        // enumerate all implementations of the FormulaParser service
+        Reference< XContentEnumerationAccess > xFactoryEA( xFactory, UNO_QUERY_THROW );
+        Reference< XEnumeration > xEnum( xFactoryEA->createContentEnumeration( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FilterFormulaParser" ) ) ), UNO_SET_THROW );
+        while( xEnum->hasMoreElements() ) try // single try/catch for every element
+        {
+            // create an instance of the formula parser implementation
+            Reference< XSingleComponentFactory > xCompFactory( xEnum->nextElement(), UNO_QUERY_THROW );
+            Reference< XFilterFormulaParser > xParser( xCompFactory->createInstanceWithContext( mxContext ), UNO_QUERY_THROW );
+
+            // store factory in the map
+            OUString aNamespace = xParser->getSupportedNamespace();
+            if( aNamespace.getLength() > 0 )
+                maFactories[ aNamespace ] = xCompFactory;
+        }
+        catch( Exception& )
+        {
+        }
+    }
+    catch( Exception& )
+    {
+    }
+}
+
+Reference< XFormulaParser > ScParserFactoryMap::createFormulaParser(
+        const Reference< XComponent >& rxComponent, const OUString& rNamespace )
+{
+    Reference< XFormulaParser > xParser;
+    FactoryMap::const_iterator aIt = maFactories.find( rNamespace );
+    if( aIt != maFactories.end() ) try
+    {
+        Sequence< Any > aArgs( 1 );
+        aArgs[ 0 ] <<= rxComponent;
+        xParser.set( aIt->second->createInstanceWithArgumentsAndContext( aArgs, mxContext ), UNO_QUERY_THROW );
+    }
+    catch( Exception& )
+    {
+    }
+    return xParser;
+}
+
+struct ScParserFactorySingleton : public ::rtl::Static< ScParserFactoryMap, ScParserFactorySingleton > {};
+
+} // namespace
+
+// ============================================================================
+
+ScFormulaParserPool::ScFormulaParserPool( const ScDocument& rDoc ) :
+    mrDoc( rDoc )
+{
+}
+
+ScFormulaParserPool::~ScFormulaParserPool()
+{
+}
+
+bool ScFormulaParserPool::hasFormulaParser( const OUString& rNamespace )
+{
+    return getFormulaParser( rNamespace ).is();
+}
+
+Reference< XFormulaParser > ScFormulaParserPool::getFormulaParser( const OUString& rNamespace )
+{
+    // try to find an existing parser entry
+    ParserMap::iterator aIt = maParsers.find( rNamespace );
+    if( aIt != maParsers.end() )
+        return aIt->second;
+
+    // always create a new entry in the map (even if the following initialization fails)
+    Reference< XFormulaParser >& rxParser = maParsers[ rNamespace ];
+
+    // try to create a new parser object
+    if( SfxObjectShell* pDocShell = mrDoc.GetDocumentShell() ) try
+    {
+        Reference< XComponent > xComponent( pDocShell->GetModel(), UNO_QUERY_THROW );
+        ScParserFactoryMap& rFactoryMap = ScParserFactorySingleton::get();
+        rxParser = rFactoryMap.createFormulaParser( xComponent, rNamespace );
+    }
+    catch( Exception& )
+    {
+    }
+    return rxParser;
+}
+
+// ============================================================================
+
diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk
index 8a4b1b4..ac0aa23 100644
--- a/sc/source/core/tool/makefile.mk
+++ b/sc/source/core/tool/makefile.mk
@@ -1,7 +1,7 @@
 #*************************************************************************
 #
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
+#
 # Copyright 2008 by Sun Microsystems, Inc.
 #
 # OpenOffice.org - a multi-platform office productivity suite
@@ -78,6 +78,7 @@ SLOFILES =  \
         $(SLO)$/docoptio.obj \
         $(SLO)$/editutil.obj \
         $(SLO)$/filtopt.obj \
+        $(SLO)$/formulaparserpool.obj \
         $(SLO)$/hints.obj \
         $(SLO)$/indexmap.obj \
         $(SLO)$/inputopt.obj \
@@ -122,6 +123,7 @@ EXCEPTIONSFILES= \
         $(SLO)$/chartlock.obj \
         $(SLO)$/chgtrack.obj \
         $(SLO)$/compiler.obj \
+        $(SLO)$/formulaparserpool.obj \
         $(SLO)$/interpr1.obj \
         $(SLO)$/interpr2.obj \
         $(SLO)$/interpr3.obj \
diff --git a/sc/source/filter/xml/XMLConverter.cxx b/sc/source/filter/xml/XMLConverter.cxx
index 7fa5826..950fb74 100644
--- a/sc/source/filter/xml/XMLConverter.cxx
+++ b/sc/source/filter/xml/XMLConverter.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -31,20 +31,17 @@
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_sc.hxx"
 
-
-
-
-//___________________________________________________________________
 #include "XMLConverter.hxx"
+#include <com/sun/star/util/DateTime.hpp>
+#include <tools/datetime.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
 #include "rangelst.hxx"
 #include "rangeutl.hxx"
 #include "docuno.hxx"
 #include "convuno.hxx"
 #include "document.hxx"
-#include <tools/datetime.hxx>
-#include <xmloff/xmltoken.hxx>
-#include <xmloff/xmluconv.hxx>
-#include <com/sun/star/util/DateTime.hpp>
+#include "ftools.hxx"
 
 using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
@@ -385,3 +382,292 @@ void ScXMLConverter::ConvertAPIToCoreDateTime(const util::DateTime& aDateTime, D
     rDateTime = aTempDateTime;
 }
 
+// ============================================================================
+
+namespace {
+
+/** Enumerates different types of condition tokens. */
+enum ScXMLConditionTokenType
+{
+    XML_COND_TYPE_KEYWORD,          /// Simple keyword without parentheses, e.g. 'and'.
+    XML_COND_TYPE_COMPARISON,       /// Comparison rule, e.g. 'cell-content()<=2'.
+    XML_COND_TYPE_FUNCTION0,        /// Function without parameters, e.g. 'cell-content-is-whole-number()'.
+    XML_COND_TYPE_FUNCTION1,        /// Function with 1 parameter, e.g. 'is-true-formula(1+1=2)'.
+    XML_COND_TYPE_FUNCTION2         /// Function with 2 parameters, e.g. 'cell-content-is-between(1,2)'.
+};
+
+struct ScXMLConditionInfo
+{
+    ScXMLConditionToken meToken;
+    ScXMLConditionTokenType meType;
+    sheet::ValidationType meValidation;
+    sheet::ConditionOperator meOperator;
+    const sal_Char*     mpcIdentifier;
+    sal_Int32           mnIdentLength;
+};
+
+static const ScXMLConditionInfo spConditionInfos[] =
+{
+    { XML_COND_AND,                     XML_COND_TYPE_KEYWORD,    sheet::ValidationType_ANY,      sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "and" ) },
+    { XML_COND_CELLCONTENT,             XML_COND_TYPE_COMPARISON, sheet::ValidationType_ANY,      sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "cell-content" ) },
+    { XML_COND_ISBETWEEN,               XML_COND_TYPE_FUNCTION2,  sheet::ValidationType_ANY,      sheet::ConditionOperator_BETWEEN,     RTL_CONSTASCII_STRINGPARAM( "cell-content-is-between" ) },
+    { XML_COND_ISNOTBETWEEN,            XML_COND_TYPE_FUNCTION2,  sheet::ValidationType_ANY,      sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-not-between" ) },
+    { XML_COND_ISWHOLENUMBER,           XML_COND_TYPE_FUNCTION0,  sheet::ValidationType_WHOLE,    sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "cell-content-is-whole-number" ) },
+    { XML_COND_ISDECIMALNUMBER,         XML_COND_TYPE_FUNCTION0,  sheet::ValidationType_DECIMAL,  sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "cell-content-is-decimal-number" ) },
+    { XML_COND_ISDATE,                  XML_COND_TYPE_FUNCTION0,  sheet::ValidationType_DATE,     sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "cell-content-is-date" ) },
+    { XML_COND_ISTIME,                  XML_COND_TYPE_FUNCTION0,  sheet::ValidationType_TIME,     sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "cell-content-is-time" ) },
+    { XML_COND_ISINLIST,                XML_COND_TYPE_FUNCTION1,  sheet::ValidationType_LIST,     sheet::ConditionOperator_EQUAL,       RTL_CONSTASCII_STRINGPARAM( "cell-content-is-in-list" ) },
+    { XML_COND_TEXTLENGTH,              XML_COND_TYPE_COMPARISON, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NONE,        RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length" ) },
+    { XML_COND_TEXTLENGTH_ISBETWEEN,    XML_COND_TYPE_FUNCTION2,  sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_BETWEEN,     RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-between" ) },
+    { XML_COND_TEXTLENGTH_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2,  sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-not-between" ) },
+    { XML_COND_ISTRUEFORMULA,           XML_COND_TYPE_FUNCTION1,  sheet::ValidationType_CUSTOM,   sheet::ConditionOperator_FORMULA,     RTL_CONSTASCII_STRINGPARAM( "is-true-formula" ) }
+};
+
+void lclSkipWhitespace( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+    while( (rpcString < pcEnd) && (*rpcString <= ' ') ) ++rpcString;
+}
+
+const ScXMLConditionInfo* lclGetConditionInfo( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+    lclSkipWhitespace( rpcString, pcEnd );
+    /*  Search the end of an identifier name; assuming that valid identifiers
+        consist of [a-z-] only. */
+    const sal_Unicode* pcIdStart = rpcString;
+    while( (rpcString < pcEnd) && (((*rpcString >= 'a') && (*rpcString <= 'z')) || (*rpcString == '-')) ) ++rpcString;
+    sal_Int32 nLength = static_cast< sal_Int32 >( rpcString - pcIdStart );
+
+    // search the table for an entry
+    if( nLength > 0 )
+        for( const ScXMLConditionInfo* pInfo = spConditionInfos; pInfo < STATIC_TABLE_END( spConditionInfos ); ++pInfo )
+            if( (nLength == pInfo->mnIdentLength) && (::rtl_ustr_ascii_shortenedCompare_WithLength( pcIdStart, nLength, pInfo->mpcIdentifier, nLength ) == 0) )
+                return pInfo;
+
+    return 0;
+}
+
+sheet::ConditionOperator lclGetConditionOperator( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+    // check for double-char operators
+    if( (rpcString + 1 < pcEnd) && (rpcString[ 1 ] == '=') )
+    {
+        sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
+        switch( *rpcString )
+        {
+            case '!':   eOperator = sheet::ConditionOperator_NOT_EQUAL;     break;
+            case '<':   eOperator = sheet::ConditionOperator_LESS_EQUAL;    break;
+            case '>':   eOperator = sheet::ConditionOperator_GREATER_EQUAL; break;
+        }
+        if( eOperator != sheet::ConditionOperator_NONE )
+        {
+            rpcString += 2;
+            return eOperator;
+        }
+    }
+
+    // check for single-char operators
+    if( rpcString < pcEnd )
+    {
+        sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
+        switch( *rpcString )
+        {
+            case '=':   eOperator = sheet::ConditionOperator_EQUAL;     break;
+            case '<':   eOperator = sheet::ConditionOperator_LESS;      break;
+            case '>':   eOperator = sheet::ConditionOperator_GREATER;   break;
+        }
+        if( eOperator != sheet::ConditionOperator_NONE )
+        {
+            ++rpcString;
+            return eOperator;
+        }
+    }
+
+    return sheet::ConditionOperator_NONE;
+}
+
+/** Skips a literal string in a formula expression.
+
+    @param rpcString
+        (in-out) On call, must point to the first character of the string
+        following the leading string delimiter character. On return, points to
+        the trailing string delimiter character if existing, otherwise to
+        pcEnd.
+
+    @param pcEnd
+        The end of the string to parse.
+
+    @param cQuoteChar
+        The string delimiter character enclosing the string.
+  */
+void lclSkipExpressionString( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cQuoteChar )
+{
+    if( rpcString < pcEnd )
+    {
+        sal_Int32 nLength = static_cast< sal_Int32 >( pcEnd - rpcString );
+        sal_Int32 nNextQuote = ::rtl_ustr_indexOfChar_WithLength( rpcString, nLength, cQuoteChar );
+        if( nNextQuote >= 0 )
+            rpcString += nNextQuote;
+        else
+            rpcString = pcEnd;
+    }
+}
+
+/** Skips a formula expression. Processes embedded parentheses, braces, and
+    literal strings.
+
+    @param rpcString
+        (in-out) On call, must point to the first character of the expression.
+        On return, points to the passed end character if existing, otherwise to
+        pcEnd.
+
+    @param pcEnd
+        The end of the string to parse.
+
+    @param cEndChar
+        The termination character following the expression.
+  */
+void lclSkipExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar )
+{
+    while( rpcString < pcEnd )
+    {
+        if( *rpcString == cEndChar )
+            return;
+        switch( *rpcString )
+        {
+            case '(':       lclSkipExpression( ++rpcString, pcEnd, ')' );           break;
+            case '{':       lclSkipExpression( ++rpcString, pcEnd, '}' );           break;
+            case '"':       lclSkipExpressionString( ++rpcString, pcEnd, '"' );     break;
+            case '\'':      lclSkipExpressionString( ++rpcString, pcEnd, '\'' );    break;
+        }
+        if( rpcString < pcEnd ) ++rpcString;
+    }
+}
+
+/** Extracts a formula expression. Processes embedded parentheses, braces, and
+    literal strings.
+
+    @param rpcString
+        (in-out) On call, must point to the first character of the expression.
+        On return, points *behind* the passed end character if existing,
+        otherwise to pcEnd.
+
+    @param pcEnd
+        The end of the string to parse.
+
+    @param cEndChar
+        The termination character following the expression.
+  */
+OUString lclGetExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar )
+{
+    OUString aExp;
+    const sal_Unicode* pcExpStart = rpcString;
+    lclSkipExpression( rpcString, pcEnd, cEndChar );
+    if( rpcString < pcEnd )
+    {
+        aExp = OUString( pcExpStart, static_cast< sal_Int32 >( rpcString - pcExpStart ) ).trim();
+        ++rpcString;
+    }
+    return aExp;
+}
+
+/** Tries to skip an empty pair of parentheses (which may contain whitespace
+    characters).
+
+    @return
+        True on success, rpcString points behind the closing parentheses then.
+ */
+bool lclSkipEmptyParentheses( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+    if( (rpcString < pcEnd) && (*rpcString == '(') )
+    {
+        lclSkipWhitespace( ++rpcString, pcEnd );
+        if( (rpcString < pcEnd) && (*rpcString == ')') )
+        {
+            ++rpcString;
+            return true;
+        }
+    }
+    return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+/*static*/ void ScXMLConditionHelper::parseCondition(
+        ScXMLConditionParseResult& rParseResult, const OUString& rAttribute, sal_Int32 nStartIndex )
+{
+    rParseResult.meToken = XML_COND_INVALID;
+    if( (nStartIndex < 0) || (nStartIndex >= rAttribute.getLength()) ) return;
+
+    // try to find an identifier
+    const sal_Unicode* pcBegin = rAttribute.getStr();
+    const sal_Unicode* pcString = pcBegin + nStartIndex;
+    const sal_Unicode* pcEnd = pcBegin + rAttribute.getLength();
+    if( const ScXMLConditionInfo* pCondInfo = lclGetConditionInfo( pcString, pcEnd ) )
+    {
+        // insert default values into parse result (may be changed below)
+        rParseResult.meValidation = pCondInfo->meValidation;
+        rParseResult.meOperator = pCondInfo->meOperator;
+        // continue parsing dependent on token type
+        switch( pCondInfo->meType )
+        {
+            case XML_COND_TYPE_KEYWORD:
+                // nothing specific has to follow, success
+                rParseResult.meToken = pCondInfo->meToken;
+            break;
+
+            case XML_COND_TYPE_COMPARISON:
+                // format is <condition>()<operator><expression>
+                if( lclSkipEmptyParentheses( pcString, pcEnd ) )
+                {
+                    rParseResult.meOperator = lclGetConditionOperator( pcString, pcEnd );
+                    if( rParseResult.meOperator != sheet::ConditionOperator_NONE )
+                    {
+                        lclSkipWhitespace( pcString, pcEnd );
+                        if( pcString < pcEnd )
+                        {
+                            rParseResult.meToken = pCondInfo->meToken;
+                            // comparison must be at end of attribute, remaining text is the formula
+                            rParseResult.maOperand1 = OUString( pcString, static_cast< sal_Int32 >( pcEnd - pcString ) );
+                        }
+                    }
+                }
+            break;
+
+            case XML_COND_TYPE_FUNCTION0:
+                // format is <condition>()
+                if( lclSkipEmptyParentheses( pcString, pcEnd ) )
+                    rParseResult.meToken = pCondInfo->meToken;
+            break;
+
+            case XML_COND_TYPE_FUNCTION1:
+                // format is <condition>(<expression>)
+                if( (pcString < pcEnd) && (*pcString == '(') )
+                {
+                    rParseResult.maOperand1 = lclGetExpression( ++pcString, pcEnd, ')' );
+                    if( rParseResult.maOperand1.getLength() > 0 )
+                        rParseResult.meToken = pCondInfo->meToken;
+                }
+            break;
+
+            case XML_COND_TYPE_FUNCTION2:
+                // format is <condition>(<expression1>,<expression2>)
+                if( (pcString < pcEnd) && (*pcString == '(') )
+                {
+                    rParseResult.maOperand1 = lclGetExpression( ++pcString, pcEnd, ',' );
+                    if( rParseResult.maOperand1.getLength() > 0 )
+                    {
+                        rParseResult.maOperand2 = lclGetExpression( pcString, pcEnd, ')' );
+                        if( rParseResult.maOperand2.getLength() > 0 )
+                            rParseResult.meToken = pCondInfo->meToken;
+                    }
+                }
+            break;
+        }
+        rParseResult.mnEndIndex = static_cast< sal_Int32 >( pcString - pcBegin );
+    }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/xml/XMLConverter.hxx b/sc/source/filter/xml/XMLConverter.hxx
index 5f8d6a2..29ccd83 100644
--- a/sc/source/filter/xml/XMLConverter.hxx
+++ b/sc/source/filter/xml/XMLConverter.hxx
@@ -36,8 +36,10 @@
 #include "detdata.hxx"
 #include <rtl/ustrbuf.hxx>
 #include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
 #include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
 #include <com/sun/star/util/DateTime.hpp>
 
 class ScDocument;
@@ -117,6 +119,62 @@ public:
     static void         ConvertAPIToCoreDateTime(const com::sun::star::util::DateTime& aDateTime, DateTime& rDateTime);
 };
 
+// ============================================================================
+
+enum ScXMLConditionToken
+{
+    XML_COND_INVALID,                       /// Token not recognized.
+    XML_COND_AND,                           /// The 'and' token.
+    XML_COND_CELLCONTENT,                   /// The 'cell-content' token.
+    XML_COND_ISBETWEEN,                     /// The 'cell-content-is-between' token.
+    XML_COND_ISNOTBETWEEN,                  /// The 'cell-content-is-not-between' token.
+    XML_COND_ISWHOLENUMBER,                 /// The 'cell-content-is-whole-number' token.
+    XML_COND_ISDECIMALNUMBER,               /// The 'cell-content-is-decimal-number' token.
+    XML_COND_ISDATE,                        /// The 'cell-content-is-date' token.
+    XML_COND_ISTIME,                        /// The 'cell-content-is-time' token.
+    XML_COND_ISINLIST,                      /// The 'cell-content-is-in-list' token.
+    XML_COND_TEXTLENGTH,                    /// The 'cell-content-text-length' token.
+    XML_COND_TEXTLENGTH_ISBETWEEN,          /// The 'cell-content-text-length-is-between' token.
+    XML_COND_TEXTLENGTH_ISNOTBETWEEN,       /// The 'cell-content-text-length-is-not-between' token.
+    XML_COND_ISTRUEFORMULA                  /// The 'is-true-formula' token.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Result of an attempt to parse a single condition in a 'condition' attribute
+    value of e.g. conditional formatting or data validation.
+ */
+struct ScXMLConditionParseResult
+{
+    ScXMLConditionToken meToken;            /// The leading condition token.
+    ::com::sun::star::sheet::ValidationType
+                        meValidation;       /// A data validation type if existing.
+    ::com::sun::star::sheet::ConditionOperator
+                        meOperator;         /// A comparison operator if existing.
+    ::rtl::OUString     maOperand1;         /// First operand of the token or comparison value.
+    ::rtl::OUString     maOperand2;         /// Second operand of 'between' conditions.
+    sal_Int32           mnEndIndex;         /// Index of first character following the condition.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScXMLConditionHelper
+{
+public:
+    /** Parses the next condition in a 'condition' attribute value of e.g.
+        conditional formatting or data validation.
+     */
+    static void         parseCondition(
+                            ScXMLConditionParseResult& rParseResult,
+                            const ::rtl::OUString& rAttribute,
+                            sal_Int32 nStartIndex );
+
+private:
+                        ScXMLConditionHelper();
+                        ~ScXMLConditionHelper();
+};
+
+// ============================================================================
 
 #endif
 
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.cxx b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
index cd2ab82..5964f38 100644
--- a/sc/source/filter/xml/XMLTrackedChangesContext.cxx
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
@@ -109,6 +109,7 @@ class ScXMLCellContentDeletionContext : public SvXMLImportContext
 {
     rtl::OUString						sFormulaAddress;
     rtl::OUString						sFormula;
+    rtl::OUString                       sFormulaNmsp;
     rtl::OUString                       sInputString;
     ScBigRange							aBigRange;
     double								fValue;
@@ -298,7 +299,8 @@ public:
     ScXMLChangeCellContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName,
                                       const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
-                                      ScBaseCell*& rOldCell, rtl::OUString& sAddress, rtl::OUString& sFormula,
+                                      ScBaseCell*& rOldCell, rtl::OUString& sAddress,
+                                      rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp,
                                       formula::FormulaGrammar::Grammar& rGrammar,
                                       rtl::OUString& rInputString, double& fValue, sal_uInt16& nType,
                                       sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows);
@@ -322,6 +324,7 @@ class ScXMLPreviousContext : public SvXMLImportContext
 {
     rtl::OUString						sFormulaAddress;
     rtl::OUString						sFormula;
+    rtl::OUString                       sFormulaNmsp;
     rtl::OUString                       sInputString;
     double								fValue;
     ScXMLChangeTrackingImportHelper*	pChangeTrackingImportHelper;
@@ -329,7 +332,7 @@ class ScXMLPreviousContext : public SvXMLImportContext
     sal_uInt32							nID;
     sal_Int32							nMatrixCols;
     sal_Int32							nMatrixRows;
-    formula::FormulaGrammar::Grammar                  eGrammar;
+    formula::FormulaGrammar::Grammar    eGrammar;
     sal_uInt16							nType;
     sal_uInt8							nMatrixFlag;
 
@@ -831,7 +834,7 @@ SvXMLImportContext *ScXMLCellContentDeletionContext::CreateChildContext( USHORT
         {
             bContainsCell = sal_True;
             pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
-                pCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows );
+                pCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows );
         }
         else if (IsXMLToken(rLocalName, XML_CELL_ADDRESS))
         {
@@ -1115,7 +1118,8 @@ ScXMLChangeCellContext::ScXMLChangeCellContext(  ScXMLImport& rImport,
                                               USHORT nPrfx,
                                                    const ::rtl::OUString& rLName,
                                               const uno::Reference<xml::sax::XAttributeList>& xAttrList,
-                                            ScBaseCell*& rTempOldCell, rtl::OUString& rAddress, rtl::OUString& rFormula,
+                                            ScBaseCell*& rTempOldCell, rtl::OUString& rAddress,
+                                            rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp,
                                             formula::FormulaGrammar::Grammar& rGrammar,
                                             rtl::OUString& rTempInputString, double& fDateTimeValue, sal_uInt16& nType,
                                             sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows ) :
@@ -1130,7 +1134,6 @@ ScXMLChangeCellContext::ScXMLChangeCellContext(  ScXMLImport& rImport,
     bString(sal_True),
     bFormula(sal_False)
 {
-    const formula::FormulaGrammar::Grammar eStorageGrammar = rGrammar = GetScImport().GetDocument()->GetStorageGrammar();
     sal_Bool bIsMatrix(sal_False);
     sal_Bool bIsCoveredMatrix(sal_False);
     sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
@@ -1147,12 +1150,7 @@ ScXMLChangeCellContext::ScXMLChangeCellContext(  ScXMLImport& rImport,
             if (IsXMLToken(aLocalName, XML_FORMULA))
             {
                 bEmpty = sal_False;
-                sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
-                        _GetKeyByAttrName( sValue, &rFormula, sal_False );
-
-                if (!ScXMLImport::IsAcceptedFormulaNamespace( nFormulaPrefix,
-                            sValue, rGrammar, eStorageGrammar))
-                    rFormula = sValue;
+                GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, rGrammar, sValue );
                 bFormula = sal_True;
             }
             else if (IsXMLToken(aLocalName, XML_CELL_ADDRESS))
@@ -1339,8 +1337,6 @@ ScXMLPreviousContext::ScXMLPreviousContext(  ScXMLImport& rImport,
                                               const uno::Reference<xml::sax::XAttributeList>& xAttrList,
                                             ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
     SvXMLImportContext( rImport, nPrfx, rLName ),
-    sFormulaAddress(),
-    sFormula(),
     pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
     pOldCell(NULL),
     nID(0),
@@ -1380,7 +1376,7 @@ SvXMLImportContext *ScXMLPreviousContext::CreateChildContext( USHORT nPrefix,
 
     if ((nPrefix == XML_NAMESPACE_TABLE) && (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL)))
         pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
-            pOldCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows);
+            pOldCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows);
 
     if( !pContext )
         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 91a9368..2fd8e88 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -129,7 +129,6 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
     bSolarMutexLocked(sal_False),
     bFormulaTextResult(sal_False)
 {
-    formula::FormulaGrammar::Grammar eStorageGrammar = eGrammar = GetScImport().GetDocument()->GetStorageGrammar();
     rXMLImport.SetRemoveLastChar(sal_False);
     rXMLImport.GetTables().AddColumn(bTempIsCovered);
     const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
@@ -232,25 +231,9 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
                 if (sValue.getLength())
                 {
                     DBG_ASSERT(!pOUFormula, "here should be only one formula");
-                    rtl::OUString sFormula;
-                    sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
-                            _GetKeyByAttrName( sValue, &sFormula, sal_False );
-
-                    if (ScXMLImport::IsAcceptedFormulaNamespace(
-                                nFormulaPrefix, sValue, eGrammar,
-                                eStorageGrammar))
-                    {
-                        // Namespaces we accept.
-                        pOUFormula.reset( sFormula);
-                    }
-                    else
-                    {
-                        // No namespace => entire string.
-                        // Also unknown namespace included in formula,
-                        // so hopefully will result in string or
-                        // compile error.
-                        pOUFormula.reset( sValue);
-                    }
+                    rtl::OUString aFormula, aFormulaNmsp;
+                    rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
+                    pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) );
                 }
             }
             break;
@@ -530,7 +513,7 @@ void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Referen
     if (pContentValidationName)
     {
         ScMyImportValidation aValidation;
-        aValidation.eGrammar = GetScImport().GetDocument()->GetStorageGrammar();
+        aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
         if (rXMLImport.GetValidation(*pContentValidationName, aValidation))
         {
             uno::Reference<beans::XPropertySet> xPropertySet(xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML))), uno::UNO_QUERY);
@@ -559,8 +542,11 @@ void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Referen
                     // #b4974740# source position must be set as string, because it may
                     // refer to a sheet that hasn't been loaded yet.
                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SOURCESTR)), uno::makeAny(aValidation.sBaseCellAddress));
-                    // Transport grammar.
-                    xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar)));
+                    // Transport grammar and formula namespace
+                    xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP1)), uno::makeAny(aValidation.sFormulaNmsp1));
+                    xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP2)), uno::makeAny(aValidation.sFormulaNmsp2));
+                    xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR1)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar1)));
+                    xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR2)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar2)));
                 }
             }
             xPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML)), uno::makeAny(xPropertySet));
@@ -1046,7 +1032,7 @@ void ScXMLTableRowCellContext::EndElement()
                     //SetType(xTempCell);
                 }
             }
-            else
+            else // if ( !pOUFormula )
             {
                 if (CellExists(aCellPos))
                 {
@@ -1059,7 +1045,7 @@ void ScXMLTableRowCellContext::EndElement()
                     {
                         DBG_ERRORFILE("It seems here are to many columns or rows");
                     }
-                    if (xCell.is() && pOUFormula)
+                    if (xCell.is())
                     {
                         SetCellProperties(xCell); // set now only the validation
                         DBG_ASSERT(((nCellsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
@@ -1072,7 +1058,7 @@ void ScXMLTableRowCellContext::EndElement()
                                             xCell));
                             if (pCellObj)
                             {
-                                pCellObj->SetFormulaWithGrammar( *pOUFormula, eGrammar);
+                                pCellObj->SetFormulaWithGrammar( pOUFormula->first, pOUFormula->second, eGrammar);
                                 if (bFormulaTextResult && pOUTextValue && pOUTextValue->getLength())
                                     pCellObj->SetFormulaResultString( *pOUTextValue);
                                 else if (fValue != 0.0)
@@ -1087,7 +1073,7 @@ void ScXMLTableRowCellContext::EndElement()
                                         aCellPos.Column, aCellPos.Row,
                                         aCellPos.Column + nMatrixCols - 1,
                                         aCellPos.Row + nMatrixRows - 1,
-                                        *pOUFormula, eGrammar);
+                                        pOUFormula->first, pOUFormula->second, eGrammar);
                             }
                         }
                         SetAnnotation( aCellPos );
@@ -1104,7 +1090,7 @@ void ScXMLTableRowCellContext::EndElement()
                         rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
                 }
 
-            }
+            } // if ( !pOUFormula )
         }
         UnlockSolarMutex();
     }
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 644ddb0..6a2edac 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -52,11 +52,12 @@ struct ScXMLAnnotationData;
 
 class ScXMLTableRowCellContext : public SvXMLImportContext
 {
+    typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > FormulaWithNamespace;
     com::sun::star::uno::Reference<com::sun::star::table::XCell> xBaseCell;
     com::sun::star::uno::Reference<com::sun::star::document::XActionLockable> xLockable;
     ::boost::optional< rtl::OUString > pOUTextValue;
     ::boost::optional< rtl::OUString > pOUTextContent;
-    ::boost::optional< rtl::OUString > pOUFormula;
+    ::boost::optional< FormulaWithNamespace > pOUFormula;
     rtl::OUString* pContentValidationName;
     ::std::auto_ptr< ScXMLAnnotationData > mxAnnotationData;
     ScMyImpDetectiveObjVec*	pDetectiveObjVec;
diff --git a/sc/source/filter/xml/xmlcvali.cxx b/sc/source/filter/xml/xmlcvali.cxx
index a128251..b5ab697 100644
--- a/sc/source/filter/xml/xmlcvali.cxx
+++ b/sc/source/filter/xml/xmlcvali.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -51,6 +51,8 @@
 
 using namespace com::sun::star;
 using namespace xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
 
 class ScXMLContentValidationContext : public SvXMLImportContext
 {
@@ -62,7 +64,6 @@ class ScXMLContentValidationContext : public SvXMLImportContext
     rtl::OUString      sErrorMessageType;
     rtl::OUString      sBaseCellAddress;
     rtl::OUString      sCondition;
-    formula::FormulaGrammar::Grammar eGrammar;
     sal_Int16          nShowList;
     sal_Bool           bAllowEmptyCell;
     sal_Bool           bDisplayHelp;
@@ -73,11 +74,10 @@ class ScXMLContentValidationContext : public SvXMLImportContext
     const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
     ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
 
-    void GetAlertStyle(const rtl::OUString& sMessageType, com::sun::star::sheet::ValidationAlertStyle& aAlertStyle);
-    void SetFormulas(const rtl::OUString& sFormulas, rtl::OUString& sFormula1, rtl::OUString& sFormula2) const;
-    void GetCondition(const rtl::OUString& sCondition, rtl::OUString& sFormula1, rtl::OUString& sFormula2,
-        com::sun::star::sheet::ValidationType& aValidationType,
-        com::sun::star::sheet::ConditionOperator& aOperator);
+    com::sun::star::sheet::ValidationAlertStyle GetAlertStyle() const;
+    void SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+        const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const;
+    void GetCondition( ScMyImportValidation& rValidation ) const;
 
 public:
 
@@ -235,20 +235,11 @@ ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImpo
                                       const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
     SvXMLImportContext( rImport, nPrfx, rLName ),
-    sName(),
-    sHelpTitle(),
-    sHelpMessage(),
-    sErrorTitle(),
-    sErrorMessage(),
-    sErrorMessageType(),
-    sBaseCellAddress(),
-    sCondition(),
     nShowList(sheet::TableValidationVisibility::UNSORTED),
     bAllowEmptyCell(sal_True),
     bDisplayHelp(sal_False),
     bDisplayError(sal_False)
 {
-    const formula::FormulaGrammar::Grammar eStorageGrammar = eGrammar = GetScImport().GetDocument()->GetStorageGrammar();
     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationAttrTokenMap();
     for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -265,14 +256,7 @@ ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImpo
                 sName = sValue;
             break;
             case XML_TOK_CONTENT_VALIDATION_CONDITION:
-                {
-                    sal_uInt16 nCondPrefix = GetImport().GetNamespaceMap().
-                            _GetKeyByAttrName( sValue, &sCondition, sal_False );
-
-                    if (!ScXMLImport::IsAcceptedFormulaNamespace( nCondPrefix,
-                                sValue, eGrammar, eStorageGrammar))
-                        sCondition = sValue;
-                }
+                sCondition = sValue;
             break;
             case XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS:
                 sBaseCellAddress = sValue;
@@ -336,189 +320,116 @@ SvXMLImportContext *ScXMLContentValidationContext::CreateChildContext( USHORT nP
     return pContext;
 }
 
-void ScXMLContentValidationContext::GetAlertStyle(const rtl::OUString& sMessageType, com::sun::star::sheet::ValidationAlertStyle& aAlertStyle)
+sheet::ValidationAlertStyle ScXMLContentValidationContext::GetAlertStyle() const
 {
-    if (IsXMLToken(sMessageType, XML_MACRO))
-        aAlertStyle = sheet::ValidationAlertStyle_MACRO;
-    else if (IsXMLToken(sMessageType, XML_STOP))
-        aAlertStyle = sheet::ValidationAlertStyle_STOP;
-    else if (IsXMLToken(sMessageType, XML_WARNING))
-        aAlertStyle = sheet::ValidationAlertStyle_WARNING;
-    else if (IsXMLToken(sMessageType, XML_INFORMATION))
-        aAlertStyle = sheet::ValidationAlertStyle_INFO;
-    else    // don't leave uninitialized
-        aAlertStyle = sheet::ValidationAlertStyle_STOP;
+    if (IsXMLToken(sErrorMessageType, XML_MACRO))
+        return sheet::ValidationAlertStyle_MACRO;
+    if (IsXMLToken(sErrorMessageType, XML_STOP))
+        return sheet::ValidationAlertStyle_STOP;
+    if (IsXMLToken(sErrorMessageType, XML_WARNING))
+        return sheet::ValidationAlertStyle_WARNING;
+    if (IsXMLToken(sErrorMessageType, XML_INFORMATION))
+        return sheet::ValidationAlertStyle_INFO;
+    // default for unknown
+    return sheet::ValidationAlertStyle_STOP;
 }
 
-void ScXMLContentValidationContext::SetFormulas(const rtl::OUString& sFormulas, rtl::OUString& sFormula1, rtl::OUString& sFormula2) const
+void ScXMLContentValidationContext::SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+    const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const
 {
-    sal_Int32 i = 0;
-    sal_Bool bString = sal_False;
-    sal_Int32 nBrakes = 0;
-    while ((sFormulas[i] != ',' || nBrakes > 0 || bString) && i < sFormulas.getLength())
+    reGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+    if( bHasNmsp )
     {
-        if (sFormulas[i] == '(')
-            ++nBrakes;
-        if (sFormulas[i] == ')')
-            --nBrakes;
-        if (sFormulas[i] == '"')
-            bString = !bString;
-        ++i;
+        // the entire attribute contains a namespace: internal namespace not allowed
+        rFormula = rCondition;
+        rFormulaNmsp = rGlobNmsp;
+        reGrammar = eGlobGrammar;
     }
-    if (sFormulas[i] == ',')
+    else
     {
-        sFormula1 = sFormulas.copy(0, i);
-        sFormula2 = sFormulas.copy(i + 1);
+        // the attribute does not contain a namespace: try to find a namespace of an external grammar
+        GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, reGrammar, rCondition, true );
+        if( reGrammar != FormulaGrammar::GRAM_EXTERNAL )
+            reGrammar = eGlobGrammar;
     }
 }
 
-void ScXMLContentValidationContext::GetCondition(const rtl::OUString& sTempCondition, rtl::OUString& sFormula1, rtl::OUString& sFormula2,
-        com::sun::star::sheet::ValidationType& aValidationType,
-        com::sun::star::sheet::ConditionOperator& aOperator)
+void ScXMLContentValidationContext::GetCondition( ScMyImportValidation& rValidation ) const
 {
-    aValidationType = sheet::ValidationType_ANY;    // #b6343997# default if no condition is given
-    aOperator = sheet::ConditionOperator_NONE;
+    rValidation.aValidationType = sheet::ValidationType_ANY;    // #b6343997# default if no condition is given
+    rValidation.aOperator = sheet::ConditionOperator_NONE;
 
-    rtl::OUString sLocalCondition(sTempCondition);
-    if (sLocalCondition.getLength())
+    if( sCondition.getLength() > 0 )
     {
-        // ToDo: erase all blanks in the condition, but not in formulas or strings
-        rtl::OUString scell_content(RTL_CONSTASCII_USTRINGPARAM("cell_content"));
-        rtl::OUString scell_content_is_date(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-date"));
-        rtl::OUString scell_content_is_time(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-time"));
-        rtl::OUString scell_content_is_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between"));
-        rtl::OUString scell_content_is_in_list(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-in-list"));
-        rtl::OUString scell_content_text_length(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length"));
-        rtl::OUString scell_content_is_not_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between"));
-        rtl::OUString scell_content_is_whole_number(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-whole-number"));
-        rtl::OUString scell_content_is_decimal_number(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-decimal-number"));
-        rtl::OUString scell_content_text_length_is_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-between"));
-        rtl::OUString scell_content_text_length_is_not_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-not-between"));
-        sal_Int32 i = 0;
-        sal_Bool bAnd(sal_True);
-        while (sLocalCondition[i] != '(' && i < sLocalCondition.getLength())
-            ++i;
-        if (sLocalCondition[i] == '(')
+        // extract leading namespace from condition string
+        OUString aCondition, aConditionNmsp;
+        FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+        GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sCondition );
+        bool bHasNmsp = aCondition.getLength() < sCondition.getLength();
+
+        // parse a condition from the attribute string
+        ScXMLConditionParseResult aParseResult;
+        ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
+
+        /*  Check the result. A valid value in aParseResult.meToken implies
+            that the other members of aParseResult are filled with valid data
+            for that token. */
+        bool bSecondaryPart = false;
+        switch( aParseResult.meToken )
         {
-            if (i != scell_content_text_length.getLength() &&
-                i != scell_content_text_length_is_between.getLength() &&
-                i != scell_content_text_length_is_not_between.getLength() &&
-                i != scell_content_is_in_list.getLength())
-            {
-                if (i == scell_content_is_time.getLength())
-                {
-                    rtl::OUString sTemp = sLocalCondition.copy(0, i);
-                    if (sTemp == scell_content_is_time)
-                        aValidationType = sheet::ValidationType_TIME;
-                    else
-                        aValidationType = sheet::ValidationType_DATE;
-                }
-                else if (i == scell_content_is_whole_number.getLength())
-                    aValidationType = sheet::ValidationType_WHOLE;
-                else if (i == scell_content_is_decimal_number.getLength())
-                    aValidationType = sheet::ValidationType_DECIMAL;
-                sLocalCondition = sLocalCondition.copy(i + 2);
-                rtl::OUString sTemp = sLocalCondition.copy(0, 5);
-                if (sTemp.compareToAscii(" and ") == 0)
-                    sLocalCondition = sLocalCondition.copy(5);
-                else
-                    bAnd = sal_False;
-            }
-            if (sLocalCondition.getLength() && bAnd)
+            case XML_COND_TEXTLENGTH:               // condition is 'cell-content-text-length()<operator><expression>'
+            case XML_COND_TEXTLENGTH_ISBETWEEN:     // condition is 'cell-content-text-length-is-between(<expression1>,<expression2>)'
+            case XML_COND_TEXTLENGTH_ISNOTBETWEEN:  // condition is 'cell-content-text-length-is-not-between(<expression1>,<expression2>)'
+            case XML_COND_ISINLIST:                 // condition is 'cell-content-is-in-list(<expression>)'
+                rValidation.aValidationType = aParseResult.meValidation;
+                rValidation.aOperator = aParseResult.meOperator;
+            break;
+
+            case XML_COND_ISWHOLENUMBER:            // condition is 'cell-content-is-whole-number() and <condition>'
+            case XML_COND_ISDECIMALNUMBER:          // condition is 'cell-content-is-decimal-number() and <condition>'
+            case XML_COND_ISDATE:                   // condition is 'cell-content-is-date() and <condition>'
+            case XML_COND_ISTIME:                   // condition is 'cell-content-is-time() and <condition>'
+                rValidation.aValidationType = aParseResult.meValidation;
+                bSecondaryPart = true;
+            break;
+
+            default:;   // unacceptable or unknown condition
+        }
+
+        /*  Parse the following 'and <condition>' part of some conditions. This
+            updates the members of aParseResult that will contain the operands
+            and comparison operator then. */
+        if( bSecondaryPart )
+        {
+            ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+            if( aParseResult.meToken == XML_COND_AND )
             {
-                i = 0;
-                while (sLocalCondition[i] != '(' && i < sLocalCondition.getLength())
-                    ++i;
-                if (sLocalCondition[i] == '(')
+                ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+                switch( aParseResult.meToken )
                 {
-                    rtl::OUString sTemp = sLocalCondition.copy(0, i);
-                    sLocalCondition = sLocalCondition.copy(i + 1);
-                    if (i == scell_content_is_between.getLength() ||
-                        i == scell_content_text_length_is_between.getLength())
-                    {
-                        if (sTemp == scell_content_is_in_list)
-                        {
-                            aValidationType = sheet::ValidationType_LIST;
-                            sFormula1 = sLocalCondition.copy(0, sLocalCondition.getLength() - 1);
-                            aOperator = sheet::ConditionOperator_EQUAL;
-                        }
-                        else
-                        {
-                            if (i == scell_content_text_length_is_between.getLength())
-                                aValidationType = sheet::ValidationType_TEXT_LEN;
-                            aOperator = sheet::ConditionOperator_BETWEEN;
-                            sLocalCondition = sLocalCondition.copy(0, sLocalCondition.getLength() - 1);
-                            SetFormulas(sLocalCondition, sFormula1, sFormula2);
-                        }
-                    }
-                    else if (i == scell_content_is_not_between.getLength() ||
-                        i == scell_content_text_length_is_not_between.getLength())
-                    {
-                        if (i == scell_content_text_length_is_not_between.getLength())
-                            aValidationType = sheet::ValidationType_TEXT_LEN;
-                        aOperator = sheet::ConditionOperator_NOT_BETWEEN;
-                        sLocalCondition = sLocalCondition.copy(0, sLocalCondition.getLength() - 1);
-                        SetFormulas(sLocalCondition, sFormula1, sFormula2);
-                    }
-                    else if (i == scell_content.getLength() ||
-                        i == scell_content_text_length.getLength())
-                    {
-                        if (i == scell_content_text_length.getLength())
-                            aValidationType = sheet::ValidationType_TEXT_LEN;
-                        sLocalCondition = sLocalCondition.copy(1);
-                        switch (sLocalCondition[0])
-                        {
-                            case '<' :
-                            {
-                                if (sLocalCondition[1] == '=')
-                                {
-                                    aOperator = sheet::ConditionOperator_LESS_EQUAL;
-                                    sLocalCondition = sLocalCondition.copy(2);
-                                }
-                                else
-                                {
-                                    aOperator = sheet::ConditionOperator_LESS;
-                                    sLocalCondition = sLocalCondition.copy(1);
-                                }
-                            }
-                            break;
-                            case '>' :
-                            {
-                                if (sLocalCondition[1] == '=')
-                                {
-                                    aOperator = sheet::ConditionOperator_GREATER_EQUAL;
-                                    sLocalCondition = sLocalCondition.copy(2);
-                                }
-                                else
-                                {
-                                    aOperator = sheet::ConditionOperator_GREATER;
-                                    sLocalCondition = sLocalCondition.copy(1);
-                                }
-                            }
-                            break;
-                            case '=' :
-                            {
-                                aOperator = sheet::ConditionOperator_EQUAL;
-                                sLocalCondition = sLocalCondition.copy(1);
-                            }
-                            break;
-                            case '!' :
-                            {
-                                aOperator = sheet::ConditionOperator_NOT_EQUAL;
-                                sLocalCondition = sLocalCondition.copy(1);
-                            }
-                            break;
-                        }
-                        sFormula1 = sLocalCondition;
-                    }
+                    case XML_COND_CELLCONTENT:  // condition is 'and cell-content()<operator><expression>'
+                    case XML_COND_ISBETWEEN:    // condition is 'and cell-content-is-between(<expression1>,<expression2>)'
+                    case XML_COND_ISNOTBETWEEN: // condition is 'and cell-content-is-not-between(<expression1>,<expression2>)'
+                        rValidation.aOperator = aParseResult.meOperator;
+                    break;
+                    default:;   // unacceptable or unknown condition
                 }
             }
         }
-    }
 
-    // a validation type (date, integer) without a condition isn't possible
-    if ( aOperator == sheet::ConditionOperator_NONE )
-        aValidationType = sheet::ValidationType_ANY;
+        // a validation type (date, integer) without a condition isn't possible
+        if( rValidation.aOperator == sheet::ConditionOperator_NONE )
+            rValidation.aValidationType = sheet::ValidationType_ANY;
+
+        // parse the formulas
+        if( rValidation.aValidationType != sheet::ValidationType_ANY )
+        {
+            SetFormula( rValidation.sFormula1, rValidation.sFormulaNmsp1, rValidation.eGrammar1,
+                aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp );
+            SetFormula( rValidation.sFormula2, rValidation.sFormulaNmsp2, rValidation.eGrammar2,
+                aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp );
+        }
+    }
 }
 
 void ScXMLContentValidationContext::EndElement()
@@ -546,15 +457,15 @@ void ScXMLContentValidationContext::EndElement()
     }
 
     ScMyImportValidation aValidation;
-    aValidation.eGrammar = eGrammar;
+    aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
     aValidation.sName = sName;
     aValidation.sBaseCellAddress = sBaseCellAddress;
     aValidation.sImputTitle = sHelpTitle;
     aValidation.sImputMessage = sHelpMessage;
     aValidation.sErrorTitle = sErrorTitle;
     aValidation.sErrorMessage = sErrorMessage;
-    GetCondition(sCondition, aValidation.sFormula1,	aValidation.sFormula2, aValidation.aValidationType, aValidation.aOperator);
-    GetAlertStyle(sErrorMessageType, aValidation.aAlertStyle);
+    GetCondition( aValidation );
+    aValidation.aAlertStyle = GetAlertStyle();
     aValidation.bShowErrorMessage = bDisplayError;
     aValidation.bShowImputMessage = bDisplayHelp;
     aValidation.bIgnoreBlanks = bAllowEmptyCell;
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 8e95e26..a45add1 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -74,6 +74,7 @@
 #include "unonames.hxx"
 #include "rangeutl.hxx"
 #include "postit.hxx"
+#include "formulaparserpool.hxx"
 #include <comphelper/extract.hxx>
 
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -2887,36 +2888,62 @@ sal_Int32 ScXMLImport::GetVisibleSheet()
     return 0;
 }
 
-// static
-bool ScXMLImport::IsAcceptedFormulaNamespace( const sal_uInt16 nFormulaPrefix,
-                                             const rtl::OUString & rValue, formula::FormulaGrammar::Grammar& rGrammar,
-                                             const formula::FormulaGrammar::Grammar eStorageGrammar )
+void ScXMLImport::ExtractFormulaNamespaceGrammar(
+        OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+        const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const
 {
-    switch (nFormulaPrefix)
+    // parse the attribute value, extract namespace ID, literal namespace, and formula string
+    rFormulaNmsp = OUString();
+    sal_uInt16 nNsId = GetNamespaceMap()._GetKeyByAttrName( rAttrValue, 0, &rFormula, &rFormulaNmsp, sal_False );
+
+    // check if we have an ODF formula namespace
+    if( !bRestrictToExternalNmsp ) switch( nNsId )
     {
-    case XML_NAMESPACE_OF:
-        rGrammar = formula::FormulaGrammar::GRAM_ODFF;
-        return true;
-    case XML_NAMESPACE_OOOC:
-        rGrammar = formula::FormulaGrammar::GRAM_PODF;
-        return true;
+        case XML_NAMESPACE_OOOC:
+            rFormulaNmsp = OUString();  // remove namespace string for built-in grammar
+            reGrammar = FormulaGrammar::GRAM_PODF;
+            return;
+        case XML_NAMESPACE_OF:
+            rFormulaNmsp = OUString();  // remove namespace string for built-in grammar
+            reGrammar = FormulaGrammar::GRAM_ODFF;
+            return;
     }
 
-    // An invalid namespace can occur from a colon in the formula text if no
-    // namespace tag was added. First character in string has to be '=' in that
-    // case.
-    bool bNoNamespace = (nFormulaPrefix == XML_NAMESPACE_NONE ||
-        (nFormulaPrefix == XML_NAMESPACE_UNKNOWN && rValue.toChar() == '='));
-
-    if (bNoNamespace && eStorageGrammar == formula::FormulaGrammar::GRAM_PODF)
-        // There may be documents in the wild that stored no namespace in ODF 1.x
-        rGrammar = formula::FormulaGrammar::GRAM_PODF;
-    else if (bNoNamespace)
-        // The default for ODF 1.2 and later without namespace is 'of:' ODFF
-        rGrammar = formula::FormulaGrammar::GRAM_ODFF;
-    else
-        // Whatever ...
-        rGrammar = eStorageGrammar;
+    /*  Find default grammar for formulas without namespace. There may be
+        documents in the wild that stored no namespace in ODF 1.0/1.1. Use
+        GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF
+        1.2 and later without namespace is GRAM_ODFF (OpenFormula). */
+    FormulaGrammar::Grammar eDefaultGrammar =
+        (GetDocument()->GetStorageGrammar() == FormulaGrammar::GRAM_PODF) ?
+            FormulaGrammar::GRAM_PODF : FormulaGrammar::GRAM_ODFF;
+
+    /*  Check if we have no namespace at all. The value XML_NAMESPACE_NONE
+        indicates that there is no colon. If the first character of the
+        attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN
+        indicates that there is a colon somewhere in the formula string. */
+    if( (nNsId == XML_NAMESPACE_NONE) || ((nNsId == XML_NAMESPACE_UNKNOWN) && (rAttrValue.toChar() == '=')) )
+    {
+        rFormula = rAttrValue;          // return entire string as formula
+        reGrammar = eDefaultGrammar;
+        return;
+    }
 
-    return false;
+    /*  Check if a namespace URL could be resolved from the attribute value.
+        Use that namespace only, if the Calc document knows an associated
+        external formula parser. This prevents that the range operator in
+        conjunction with defined names is confused as namespaces prefix, e.g.
+        in the expression 'table:A1' where 'table' is a named reference. */
+    if( ((nNsId & XML_NAMESPACE_UNKNOWN_FLAG) != 0) && (rFormulaNmsp.getLength() > 0) &&
+        GetDocument()->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp ) )
+    {
+        reGrammar = FormulaGrammar::GRAM_EXTERNAL;
+        return;
+    }
+
+    /*  All attempts failed (e.g. no namespace and no leading equality sign, or
+        an invalid namespace prefix), continue with the entire attribute value. */
+    rFormula = rAttrValue;
+    rFormulaNmsp = OUString();  // remove any namespace string
+    reGrammar = eDefaultGrammar;
 }
+
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index efb2b14..f9cdfe0 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -598,6 +598,7 @@ struct ScMyNamedExpression
 {
     rtl::OUString      sName;
     rtl::OUString      sContent;
+    rtl::OUString      sContentNmsp;
     rtl::OUString      sBaseCellAddress;
     rtl::OUString      sRangeType;
     formula::FormulaGrammar::Grammar eGrammar;
@@ -624,11 +625,14 @@ struct ScMyImportValidation
     rtl::OUString									sErrorMessage;
     rtl::OUString									sFormula1;
     rtl::OUString									sFormula2;
+    rtl::OUString                                   sFormulaNmsp1;
+    rtl::OUString                                   sFormulaNmsp2;
     rtl::OUString                                   sBaseCellAddress;   // #b4974740# string is used directly
     com::sun::star::sheet::ValidationAlertStyle		aAlertStyle;
     com::sun::star::sheet::ValidationType			aValidationType;
     com::sun::star::sheet::ConditionOperator		aOperator;
-    formula::FormulaGrammar::Grammar                              eGrammar;
+    formula::FormulaGrammar::Grammar                eGrammar1;
+    formula::FormulaGrammar::Grammar                eGrammar2;
     sal_Int16                                       nShowList;
     sal_Bool										bShowErrorMessage;
     sal_Bool										bShowImputMessage;
@@ -984,46 +988,42 @@ public:
     void AddDefaultNote( const com::sun::star::table::CellAddress& aCell );
 
     sal_Int32   GetVisibleSheet();
-
-    /** If namespace prefix is an accepted formula namespace.
-
-        For an accepted namespace (return <TRUE/>), the formula text is the
-        part without the namespace tag (aFormula of the _GetKeyByAttrName()
-        example below).
-
-        For an invalid namespace (not defined in the file,
-        XML_NAMESPACE_UNKNOWN; may also be the result of no namespace with
-        colon in the formula text, in that case text has to start with
-        character '=') or no namespace tag (XML_NAMESPACE_NONE) the full text
-        (rValue) should be used (return <FALSE/>).
-
-        @param nFormulaPrefix
-            The result of a _GetKeyByAttrName( rValue, aFormula, sal_False)
-            call.
-
-        @param rValue
-            The attribute's string (formula text) including the namespace, if
-            any.
-
-        @param rGrammar
-            Return value set toformula::FormulaGrammar::GRAM_ODFF orformula::FormulaGrammar::GRAM_PODF or
-            eStorageGrammar, according to the namespace or absence thereof
-            encountered.
-
-        @param eStorageGrammar
-            Default storage grammar of the document,formula::FormulaGrammar::GRAM_ODFF for
-            ODF 1.2 and later documents,formula::FormulaGrammar::GRAM_PODF for ODF 1.x
-            documents.
-
-        @return
-            <TRUE/> if an accepted namespace (XML_NAMESPACE_OF or
-            XML_NAMESPACE_OOOC), else <FALSE/>.
+    /** Extracts the formula string, the formula grammar namespace URL, and a
+        grammar enum value from the passed formula attribute value.
+
+        @param rFormula
+            (out-parameter) Returns the plain formula string with the leading
+            equality sign if existing.
+
+        @param rFormulaNmsp
+            (out-parameter) Returns the URL of the formula grammar namespace if
+            the attribute value contains the prefix of an unknown namespace.
+
+        @param reGrammar
+            (out-parameter) Returns the exact formula grammar if the formula
+            is in a supported ODF format (e.g. FormulaGrammar::GRAM_PODF for
+            ODF 1.0/1.1 formulas, or FormulaGrammar::GRAM_ODFF for ODF 1.2
+            formulas a.k.a. OpenFormula). Returns the default storage grammar,
+            if the attribute value does not contain a namespace prefix. Returns
+            the special value FormulaGrammar::GRAM_EXTERNAL, if an unknown
+            namespace could be extracted from the formula which will be
+            contained in the parameter rFormulaNmsp then.
+
+        @param rAttrValue
+            The value of the processed formula attribute.
+
+        @param bRestrictToExternalNmsp
+            If set to TRUE, only namespaces of external formula grammars will
+            be recognized. Internal namespace prefixes (e.g. 'oooc:' or 'of:'
+            will be considered to be part of the formula, e.g. an expression
+            with range operator.
      */
-
-    static bool IsAcceptedFormulaNamespace( const sal_uInt16 nFormulaPrefix,
-            const rtl::OUString & rValue, formula::FormulaGrammar::Grammar& rGrammar,
-            const formula::FormulaGrammar::Grammar eStorageGrammar );
-
+    void ExtractFormulaNamespaceGrammar(
+            ::rtl::OUString& rFormula,
+            ::rtl::OUString& rFormulaNmsp,
+            ::formula::FormulaGrammar::Grammar& reGrammar,
+            const ::rtl::OUString& rAttrValue,
+            bool bRestrictToExternalNmsp = false ) const;
 };
 
 #endif
diff --git a/sc/source/filter/xml/xmlnexpi.cxx b/sc/source/filter/xml/xmlnexpi.cxx
index 95f64a8..6254ad6 100644
--- a/sc/source/filter/xml/xmlnexpi.cxx
+++ b/sc/source/filter/xml/xmlnexpi.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -196,8 +196,6 @@ ScXMLNamedExpressionContext::ScXMLNamedExpressionContext( ScXMLImport& rImport,
     SvXMLImportContext( rImport, nPrfx, rLName )
 {
     ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression);
-    const formula::FormulaGrammar::Grammar eStorageGrammar = pNamedExpression->eGrammar =
-        GetScImport().GetDocument()->GetStorageGrammar();
     sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
     const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetNamedExpressionAttrTokenMap());
     for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -217,16 +215,9 @@ ScXMLNamedExpressionContext::ScXMLNamedExpressionContext( ScXMLImport& rImport,
             break;
             case XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION :
             {
-                rtl::OUString sFormula;
-                sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
-                    _GetKeyByAttrName( sValue, &sFormula, sal_False );
-
-                if (ScXMLImport::IsAcceptedFormulaNamespace( nFormulaPrefix,
-                            sValue, pNamedExpression->eGrammar,
-                            eStorageGrammar))
-                    pNamedExpression->sContent = sFormula;
-                else
-                    pNamedExpression->sContent = sValue;
+                GetScImport().ExtractFormulaNamespaceGrammar(
+                    pNamedExpression->sContent, pNamedExpression->sContentNmsp,
+                    pNamedExpression->eGrammar, sValue );
             }
             break;
             case XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS :
diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx
index d3748c3..cf58896 100644
--- a/sc/source/filter/xml/xmlstyli.cxx
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -73,6 +73,7 @@ using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::container;
 using namespace xmloff::token;
 //using namespace ::com::sun::star::text;
+using namespace ::formula;
 
 ScXMLCellImportPropertyMapper::ScXMLCellImportPropertyMapper(
         const UniReference< XMLPropertySetMapper >& rMapper,
@@ -285,10 +286,7 @@ public:
 
 ScXMLMapContext::ScXMLMapContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
             const OUString& rLName,	const uno::Reference< xml::sax::XAttributeList > & xAttrList )
-    : SvXMLImportContext( rImport, nPrfx, rLName ),
-    sApplyStyle(),
-    sCondition(),
-    sBaseCell()
+    : SvXMLImportContext( rImport, nPrfx, rLName )
 {
     sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
     for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -315,200 +313,118 @@ ScXMLMapContext::~ScXMLMapContext()
 {
 }
 
-void XMLTableStyleContext::SetOperator(com::sun::star::uno::Sequence<beans::PropertyValue>& aProps,
-        const com::sun::star::sheet::ConditionOperator aOp) const
-{
-    sal_Int32 nLength(aProps.getLength());
-    aProps.realloc(nLength + 1);
-    aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OPERATOR));
-    aProps[nLength].Value <<= aOp;
-}
+namespace {
 
-void XMLTableStyleContext::SetBaseCellAddress(com::sun::star::uno::Sequence<beans::PropertyValue>& aProps,
-    const rtl::OUString& sBaseCell) const
+template< typename Type >
+inline void lclAppendProperty( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rPropName, const Type& rValue )
 {
-    sal_Int32 nLength(aProps.getLength());
-    aProps.realloc(nLength + 1);
-
-    // #b4974740# source position must be set as string, because it may
-    // refer to a sheet that hasn't been loaded yet.
-
-    aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SOURCESTR));
-    aProps[nLength].Value <<= sBaseCell;
+    sal_Int32 nLength = rProps.getLength();
+    rProps.realloc( nLength + 1 );
+    rProps[ nLength ].Name = rPropName;
+    rProps[ nLength ].Value <<= rValue;
 }
 
-void XMLTableStyleContext::SetStyle(com::sun::star::uno::Sequence<beans::PropertyValue>& aProps,
-    const rtl::OUString& sApplyStyle) const
+} // namespace
+
+void XMLTableStyleContext::SetOperator( uno::Sequence< beans::PropertyValue >& rProps, sheet::ConditionOperator eOp ) const
 {
-    sal_Int32 nLength(aProps.getLength());
-    aProps.realloc(nLength + 1);
-    aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STYLENAME));
-    aProps[nLength].Value <<= sApplyStyle;
+    lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_OPERATOR ) ), eOp );
 }
 
-void XMLTableStyleContext::SetFormula1(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-    const rtl::OUString& sFormula, bool bPreParse) const
+void XMLTableStyleContext::SetBaseCellAddress( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rBaseCell ) const
 {
-    sal_Int32 nLength(aProps.getLength());
-    aProps.realloc(nLength + 1);
-    aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULA1));
-    if (bPreParse)
-    {
-        rtl::OUString sRealFormula(sFormula);
-        ScXMLConverter::ParseFormula(sRealFormula);
-        aProps[nLength].Value <<= sRealFormula;
-    }
-    else
-        aProps[nLength].Value <<= sFormula;
+    /*  #b4974740# Source position must be set as string, because it may refer
+        to a sheet that hasn't been loaded yet. */
+    lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SOURCESTR ) ), rBaseCell );
 }
 
-void XMLTableStyleContext::SetFormula2(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-    const rtl::OUString& sFormula) const
+void XMLTableStyleContext::SetStyle( uno::Sequence<beans::PropertyValue>& rProps, const OUString& rApplyStyle ) const
 {
-    sal_Int32 nLength(aProps.getLength());
-    aProps.realloc(nLength + 1);
-    aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULA2));
-    rtl::OUString sRealFormula(sFormula);
-    ScXMLConverter::ParseFormula(sRealFormula);
-    aProps[nLength].Value <<= sRealFormula;
+    lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_STYLENAME ) ), rApplyStyle );
 }
 
-void XMLTableStyleContext::SetFormulas(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-    const rtl::OUString& sFormulas) const
+void XMLTableStyleContext::SetFormula( uno::Sequence< beans::PropertyValue >& rProps,
+        sal_Int32 nFormulaIdx, const OUString& rFormula, const OUString& rFormulaNmsp,
+        FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const
 {
-    sal_Int32 i(0);
-    sal_Bool bString(sal_False);
-    sal_Int32 nBrakes(0);
-    while ((sFormulas[i] != ',' || nBrakes > 0 || bString) && i < sFormulas.getLength())
+    OUString aFormula, aFormulaNmsp;
+    FormulaGrammar::Grammar eNewGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+    if( bHasNmsp )
     {
-        if (sFormulas[i] == '(')
-            ++nBrakes;
-        if (sFormulas[i] == ')')
-            --nBrakes;
-        if (sFormulas[i] == '"')
-            bString = !bString;
-        ++i;
+        // the entire attribute contains a namespace: internal namespace not allowed
+        aFormula = rFormula;
+        aFormulaNmsp = rFormulaNmsp;
+        eNewGrammar = eGrammar;
     }
-    if (sFormulas[i] == ',')
+    else
     {
-        rtl::OUString sFormula1(sFormulas.copy(0, i));
-        rtl::OUString sFormula2(sFormulas.copy(i + 1));
-        SetFormula1(aProps, sFormula1);
-        SetFormula2(aProps, sFormula2);
+        // the attribute does not contain a namespace: try to find a namespace of an external grammar
+        GetScImport().ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eNewGrammar, rFormula, true );
+        if( eNewGrammar != FormulaGrammar::GRAM_EXTERNAL )
+            eNewGrammar = eGrammar;
     }
-}
 
-void XMLTableStyleContext::SetGrammar(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const formula::FormulaGrammar::Grammar eGrammar) const
-{
-    sal_Int32 nLength(aProps.getLength());
-    aProps.realloc(nLength + 1);
-    aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR));
-    aProps[nLength].Value <<= static_cast<sal_Int32>(eGrammar);
+    // add formula, formula namespace, and grammar with appropriate property names
+    sal_Int32 nGrammar = static_cast< sal_Int32 >( eNewGrammar );
+    switch( nFormulaIdx )
+    {
+        case 1:
+            lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA1 ) ), aFormula );
+            lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP1 ) ), aFormulaNmsp );
+            lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR1 ) ), nGrammar );
+        break;
+        case 2:
+            lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA2 ) ), aFormula );
+            lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP2 ) ), aFormulaNmsp );
+            lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR2 ) ), nGrammar );
+        break;
+        default:
+            OSL_ENSURE( false, "XMLTableStyleContext::SetFormula - invalid formula index" );
+    }
 }
 
 void XMLTableStyleContext::GetConditionalFormat(uno::Any& aAny,
         const rtl::OUString& sTempCondition,
         const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const
 {
-    rtl::OUString sCondition(sTempCondition);
-    if (sCondition.getLength() && sApplyStyle.getLength())
+    if (sTempCondition.getLength() && sApplyStyle.getLength())
     {
         uno::Reference<sheet::XSheetConditionalEntries> xConditionalEntries(aAny, uno::UNO_QUERY);
         if (xConditionalEntries.is())
         {
-            const formula::FormulaGrammar::Grammar eStorageGrammar = GetScImport().GetDocument()->GetStorageGrammar();
-            formula::FormulaGrammar::Grammar eGrammar = eStorageGrammar;
-            // ToDo: erase all blanks in the condition, but not in formulas or strings
-            rtl::OUString scell_content(RTL_CONSTASCII_USTRINGPARAM("cell_content"));
-            rtl::OUString scell_content_is_between(RTL_CONSTASCII_USTRINGPARAM("cell_content_is_between"));
-            rtl::OUString scell_content_is_not_between(RTL_CONSTASCII_USTRINGPARAM("cell_content_is_not_between"));
-            rtl::OUString sis_true_formula(RTL_CONSTASCII_USTRINGPARAM("is_true_formula"));
             uno::Sequence<beans::PropertyValue> aProps;
             if (sBaseCell.getLength())
                 SetBaseCellAddress(aProps, sBaseCell);
             SetStyle(aProps, sApplyStyle);
-            sal_Int32 i = 0;
-            while (sCondition[i] != '(' && i < sCondition.getLength())
-                ++i;
-            if (sCondition[i] == '(')
+
+            // extract leading namespace from condition string
+            OUString aCondition, aConditionNmsp;
+            FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+            GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sTempCondition );
+            bool bHasNmsp = aCondition.getLength() < sTempCondition.getLength();
+
+            // parse a condition from the attribute string
+            ScXMLConditionParseResult aParseResult;
+            ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
+
+            /*  Check the result. A valid value in aParseResult.meToken implies
+                that the other members of aParseResult are filled with valid
+                data for that token. */
+            switch( aParseResult.meToken )
             {
-                sCondition = sCondition.copy(i + 1);
-                if (i == scell_content.getLength())
-                {
-                    sCondition = sCondition.copy(1);
-                    switch (sCondition[0])
-                    {
-                        case '<' :
-                        {
-                            if (sCondition[1] == '=')
-                            {
-                                SetOperator(aProps, sheet::ConditionOperator_LESS_EQUAL);
-                                sCondition = sCondition.copy(2);
-                            }
-                            else
-                            {
-                                SetOperator(aProps, sheet::ConditionOperator_LESS);
-                                sCondition = sCondition.copy(1);
-                            }
-                        }
-                        break;
-                        case '>' :
-                        {
-                            if (sCondition[1] == '=')
-                            {
-                                SetOperator(aProps, sheet::ConditionOperator_GREATER_EQUAL);
-                                sCondition = sCondition.copy(2);
-                            }
-                            else
-                            {
-                                SetOperator(aProps, sheet::ConditionOperator_GREATER);
-                                sCondition = sCondition.copy(1);
-                            }
-                        }
-                        break;
-                        case '=' :
-                        {
-                            SetOperator(aProps, sheet::ConditionOperator_EQUAL);
-                            sCondition = sCondition.copy(1);
-                        }
-                        break;
-                        case '!' :
-                        {
-                            SetOperator(aProps, sheet::ConditionOperator_NOT_EQUAL);
-                            sCondition = sCondition.copy(1);
-                        }
-                        break;
-                    }
-                    SetFormula1(aProps, sCondition);
-                }
-                else if (i == scell_content_is_between.getLength())
-                {
-                    SetOperator(aProps, sheet::ConditionOperator_BETWEEN);
-                    sCondition = sCondition.copy(0, sCondition.getLength() - 1);
-                    SetFormulas(aProps, sCondition);
-                }
-                else if (i == scell_content_is_not_between.getLength())
-                {
-                    SetOperator(aProps, sheet::ConditionOperator_NOT_BETWEEN);
-                    sCondition = sCondition.copy(0, sCondition.getLength() - 1);
-                    SetFormulas(aProps, sCondition);
-                }
-                else if (i == sis_true_formula.getLength())
-                {
-                    SetOperator(aProps, sheet::ConditionOperator_FORMULA);
-                    sCondition = sCondition.copy(0, sCondition.getLength() - 1);
-                    rtl::OUString sFormula;
-                    sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
-                        _GetKeyByAttrName( sCondition, &sFormula, sal_False );
-                    if (ScXMLImport::IsAcceptedFormulaNamespace( nFormulaPrefix,
-                                sCondition, eGrammar, eStorageGrammar))
-                        sCondition = sFormula;
-                    SetFormula1(aProps, sCondition, false);
-                }
+                case XML_COND_CELLCONTENT:      // condition is 'cell-content()<operator><expression>'
+                case XML_COND_ISTRUEFORMULA:    // condition is 'is-true-formula(<expression>)'
+                case XML_COND_ISBETWEEN:        // condition is 'cell-content-is-between(<expression1>,<expression2>)'
+                case XML_COND_ISNOTBETWEEN:     // condition is 'cell-content-is-not-between(<expression1>,<expression2>)'
+                    SetOperator( aProps, aParseResult.meOperator );
+                    SetFormula( aProps, 1, aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp );
+                    SetFormula( aProps, 2, aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp );
+                break;
+
+                default:;   // unacceptable or unknown condition
             }
-            SetGrammar( aProps, eGrammar);
-            xConditionalEntries->addNew(aProps);
+
+            xConditionalEntries->addNew( aProps );
             aAny <<= xConditionalEntries;
         }
     }
diff --git a/sc/source/filter/xml/xmlstyli.hxx b/sc/source/filter/xml/xmlstyli.hxx
index 2e7f497..6ba234a 100644
--- a/sc/source/filter/xml/xmlstyli.hxx
+++ b/sc/source/filter/xml/xmlstyli.hxx
@@ -107,20 +107,22 @@ class XMLTableStyleContext : public XMLPropStyleContext
     const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
     ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
 
-    void SetOperator(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const com::sun::star::sheet::ConditionOperator aOp) const;
-    void SetBaseCellAddress(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const rtl::OUString& sBaseCell) const;
-    void SetStyle(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const rtl::OUString& sApplyStyle) const;
-    void SetFormula1(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const rtl::OUString& sFormula, bool bPreParse = true) const;
-    void SetFormula2(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const rtl::OUString& sFormula) const;
-    void SetFormulas(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const rtl::OUString& sFormulas) const;
-    void SetGrammar(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
-        const formula::FormulaGrammar::Grammar eGrammar) const;
+    void SetOperator(
+            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+            ::com::sun::star::sheet::ConditionOperator eOp ) const;
+
+    void SetBaseCellAddress(
+            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+            const ::rtl::OUString& rBaseCell ) const;
+
+    void SetStyle(
+            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+            const ::rtl::OUString& rApplyStyle ) const;
+
+    void SetFormula(
+        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+        sal_Int32 nFormulaIdx, const ::rtl::OUString& rFormula,
+        const ::rtl::OUString& rFormulaNmsp, ::formula::FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const;
 
     void GetConditionalFormat(
         ::com::sun::star::uno::Any& aAny, const rtl::OUString& sCondition,
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 81d830a..d326a30 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -641,7 +641,7 @@ void ScMyTables::DeleteTable()
         ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
         while(aItr != aEndItr)
         {
-            SetMatrix(aItr->aRange, aItr->sFormula, aItr->eGrammar);
+            SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
             ++aItr;
         }
         aMatrixRangeList.clear();
@@ -755,7 +755,9 @@ void ScMyTables::AddShape(uno::Reference <drawing::XShape>& rShape,
     aResizeShapes.AddShape(rShape, pRangeList, rStartAddress, rEndAddress, nEndX, nEndY);
 }
 
-void ScMyTables::AddMatrixRange(sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow, const rtl::OUString& rFormula, const formula::FormulaGrammar::Grammar eGrammar)
+void ScMyTables::AddMatrixRange(
+        sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow,
+        const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
 {
     DBG_ASSERT(nEndRow >= nStartRow, "wrong row order");
     DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order");
@@ -765,7 +767,7 @@ void ScMyTables::AddMatrixRange(sal_Int32 nStartColumn, sal_Int32 nStartRow, sal
     aRange.EndColumn = nEndColumn;
     aRange.EndRow = nEndRow;
     aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
-    ScMatrixRange aMRange(aRange, rFormula, eGrammar);
+    ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar);
     aMatrixRangeList.push_back(aMRange);
 }
 
@@ -786,7 +788,7 @@ sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
             }
             else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn))
             {
-                SetMatrix(aItr->aRange, aItr->sFormula, aItr->eGrammar);
+                SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
                 aItr = aMatrixRangeList.erase(aItr);
             }
             else if (nColumn < aItr->aRange.StartColumn)
@@ -803,7 +805,8 @@ sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
     return bResult;
 }
 
-void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const formula::FormulaGrammar::Grammar eGrammar)
+void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula,
+        const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
 {
     uno::Reference <table::XCellRange> xMatrixCellRange(
         GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow,
@@ -817,7 +820,7 @@ void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUS
                 static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation(
                             xMatrixCellRange));
             if (pCellRangeObj)
-                pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, eGrammar);
+                pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar);
         }
     }
 }
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
index b0fa041..8f1e826 100644
--- a/sc/source/filter/xml/xmlsubti.hxx
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -97,10 +97,12 @@ public:
 struct ScMatrixRange
 {
     rtl::OUString sFormula;
+    rtl::OUString sFormulaNmsp;
     formula::FormulaGrammar::Grammar eGrammar;
     com::sun::star::table::CellRangeAddress aRange;
-    ScMatrixRange(const com::sun::star::table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const formula::FormulaGrammar::Grammar eGrammarP) :
+    ScMatrixRange(const com::sun::star::table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammarP) :
         sFormula(rFormula),
+        sFormulaNmsp(rFormulaNmsp),
         eGrammar(eGrammarP),
         aRange(rRange)
     {
@@ -181,11 +183,13 @@ public:
                                                 sal_Int32 nEndColumn,
                                                 sal_Int32 nEndRow,
                                                 const rtl::OUString& rFormula,
+                                                const rtl::OUString& rFormulaNmsp,
                                                 const formula::FormulaGrammar::Grammar );
 
     sal_Bool                            IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow);
     void                                SetMatrix( const com::sun::star::table::CellRangeAddress& rRange,
                                                 const rtl::OUString& rFormula,
+                                                const rtl::OUString& rFormulaNmsp,
                                                 const formula::FormulaGrammar::Grammar );
 };
 
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 22d764a..9979601 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -960,16 +960,18 @@ BOOL ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
 }
 
 
-ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText )
+ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
     ScTokenArray* pCode = new ScTokenArray;
     pCode->AddString( rText );
+    if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (rFormulaNmsp.Len() > 0) )
+        pCode->AddString( rFormulaNmsp );
     return pCode;
 }
 
 
 ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
-        const String& rText, const formula::FormulaGrammar::Grammar eGrammar )
+        const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
     ScDocument* pDoc = rDocShell.GetDocument();
     ScBaseCell* pNewCell = NULL;
@@ -979,7 +981,7 @@ ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
         ScTokenArray* pCode;
         if ( pDoc->IsImportingXML() )
         {	// temporary formula string as string tokens
-            pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText );
+            pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText, rFormulaNmsp, eGrammar );
             pDoc->IncXMLImportedFormulaCount( rText.Len() );
         }
         else
@@ -1016,8 +1018,8 @@ ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
 
 
 BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
-                                BOOL bInterpret, BOOL bEnglish, BOOL bApi,
-                                const formula::FormulaGrammar::Grammar eGrammar )
+        BOOL bInterpret, BOOL bEnglish, BOOL bApi,
+        const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
     //	SetCellText ruft PutCell oder SetNormalString
 
@@ -1030,12 +1032,15 @@ BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
             //	code moved to own method InterpretEnglishString because it is also used in
             //	ScCellRangeObj::setFormulaArray
 
-            pNewCell = InterpretEnglishString( rPos, rText, eGrammar );
+            pNewCell = InterpretEnglishString( rPos, rText, rFormulaNmsp, eGrammar );
         }
         // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
     }
     else if ( rText.Len() )
+    {
+        OSL_ENSURE( rFormulaNmsp.Len() == 0, "ScDocFunc::SetCellText - formula namespace, but do not interpret?" );
         pNewCell = ScBaseCell::CreateTextCell( rText, pDoc );	// immer Text
+    }
 
     if (pNewCell)
         return PutCell( rPos, pNewCell, bApi );
@@ -1320,7 +1325,7 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
     SCCOL nCursorCol = 0;
     SCROW nCursorRow = 0;
     if( pViewSh )
-    { 
+    {
         nCursorCol = pViewSh->GetViewData()->GetCurX();
         nCursorRow = pViewSh->GetViewData()->GetCurY();
     }
@@ -1445,7 +1450,7 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
 
                 pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
                 pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
-                
+
                 if(( eCmd == INS_CELLSDOWN && ( nMergeStartX != nMergeTestStartX || nMergeEndX != nMergeTestEndX )) ||
                     (eCmd == INS_CELLSRIGHT && ( nMergeStartY != nMergeTestStartY || nMergeEndY != nMergeTestEndY )) )
                 {
@@ -1454,7 +1459,7 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
                     rDocShell.GetUndoManager()->LeaveListAction();
                     return FALSE;
                 }
-                
+
                 SCCOL nTestCol = -1;
                 SCROW nTestRow1 = -1;
                 SCROW nTestRow2 = -1;
@@ -1622,7 +1627,7 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
         }
 
         // #i8302 : we remerge growing ranges, with the new part inserted
-        
+
         while( !qIncreaseRange.empty() )
         {
             ScRange aRange = qIncreaseRange.back();
@@ -1909,7 +1914,7 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
 
                 if( bDeletingMerge )
                 {
-                    
+
                     if( eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP )
                     {
                         nStartRow = aExtendMergeRange.aStart.Row();
@@ -2086,11 +2091,11 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
 
     // #i8302 want to be able to insert into the middle of merged cells
     // the patch comes from maoyg
-  
+
     while( !qDecreaseRange.empty() )
     {
         ScRange aRange = qDecreaseRange.back();
-        
+
         long nDecreaseRowCount = 0;
         long nDecreaseColCount = 0;
         if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
@@ -3516,9 +3521,8 @@ BOOL ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
 //------------------------------------------------------------------------
 
 BOOL ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
-                                const ScTokenArray* pTokenArray,
-                                const String& rString, BOOL bApi, BOOL bEnglish,
-                                const formula::FormulaGrammar::Grammar eGrammar )
+        const ScTokenArray* pTokenArray, const String& rString, BOOL bApi, BOOL bEnglish,
+        const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
     ScDocShellModificator aModificator( rDocShell );
 
@@ -3565,7 +3569,7 @@ BOOL ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
         }
         else if ( pDoc->IsImportingXML() )
         {
-            ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString );
+            ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
             pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
                     aMark, EMPTY_STRING, pCode, eGrammar);
             delete pCode;
@@ -4495,11 +4499,11 @@ BOOL ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd
         if ( DeleteContents( aMark, IDF_CONTENTS, TRUE, bApi ) )
         {
             // GRAM_PODF_A1 for API compatibility.
-            bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, FALSE,formula::FormulaGrammar::GRAM_PODF_A1 );
+            bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
             if (!bRet)
             {
                 //	versuchen, alten Zustand wiederherzustellen
-                EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, FALSE,formula::FormulaGrammar::GRAM_PODF_A1 );
+                EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
             }
         }
 
diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx
index 6ec338a..e88625e 100644
--- a/sc/source/ui/docshell/docsh3.cxx
+++ b/sc/source/ui/docshell/docsh3.cxx
@@ -1051,8 +1051,8 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheck
                                     aValue.Erase( 0, 1 );
                                     aValue.Erase( aValue.Len()-1, 1 );
                                     GetDocFunc().EnterMatrix( aSourceRange,
-                                            NULL, NULL, aValue, FALSE, FALSE,
-                                           formula::FormulaGrammar::GRAM_DEFAULT );
+                                        NULL, NULL, aValue, FALSE, FALSE,
+                                        EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
                                 }
                                 break;
                                 case MM_REFERENCE :		// do nothing
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
index 8fd0792..be4578f 100644
--- a/sc/source/ui/formdlg/formula.cxx
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -126,8 +126,7 @@ ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
     m_xParser.set(ScServiceProvider::MakeInstance(SC_SERVICE_FORMULAPARS,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
     uno::Reference< beans::XPropertySet> xSet(m_xParser,uno::UNO_QUERY);
     xSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COMPILEFAP)),uno::makeAny(sal_True));
-    xSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REFERENCEPOS)),uno::makeAny(table::CellAddress(aCursorPos.Tab(),aCursorPos.Col(),aCursorPos.Row())));
-    
+
     m_xOpCodeMapper.set(ScServiceProvider::MakeInstance(SC_SERVICE_OPCODEMAPPER,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
 
     ScInputHandler*	pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
@@ -144,7 +143,7 @@ ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
 
     notifyChange();
     fill();
-    
+
     ScFormEditData* pData = pScMod->GetFormEditData();
     if (!pData)
     {
@@ -197,7 +196,7 @@ ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
             String aNewFormula = '=';
             if ( aFormula.Len() > 0 && aFormula.GetChar(0) == '=' )
                 aNewFormula=aFormula;
-            
+
             pScMod->InputReplaceSelection( aNewFormula );
             pScMod->InputSetSelection( 1, aNewFormula.Len()+1 );
             xub_StrLen PrivStart, PrivEnd;
@@ -272,7 +271,7 @@ void ScFormulaDlg::fill()
         Update();
         // Jetzt nochmals zurueckschalten, da evtl. neues Doc geoeffnet wurde!
         pScMod->SetRefInputHdl(NULL);
-    }	
+    }
 }
 
 __EXPORT ScFormulaDlg::~ScFormulaDlg()
@@ -530,7 +529,7 @@ void ScFormulaDlg::ViewShellChanged( ScTabViewShell* pScViewShell )
 }
 void ScFormulaDlg::AddRefEntry( )
 {
-    
+
 }
 BOOL ScFormulaDlg::IsTableLocked( ) const
 {
@@ -559,14 +558,14 @@ void ScFormulaDlg::dispatch(BOOL _bOK,BOOL _bMartixChecked)
     m_aHelper.SetDispatcherLock( FALSE ); // Modal-Modus ausschalten
 
     clear();
-    
+
     GetBindings().GetDispatcher()->Execute( SID_INS_FUNCTION,
                               SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
                               &aRetItem, &aStrItem, &aMatItem, 0L );
 }
 void ScFormulaDlg::setDispatcherLock( BOOL bLock )
 {
-    m_aHelper.SetDispatcherLock( bLock ); 
+    m_aHelper.SetDispatcherLock( bLock );
 }
 void ScFormulaDlg::setReferenceInput(const formula::FormEditData* _pData)
 {
@@ -657,6 +656,12 @@ uno::Reference< sheet::XFormulaOpCodeMapper> ScFormulaDlg::getFormulaOpCodeMappe
 {
     return m_xOpCodeMapper;
 }
+
+table::CellAddress ScFormulaDlg::getReferencePosition() const
+{
+    return table::CellAddress(aCursorPos.Tab(),aCursorPos.Col(),aCursorPos.Row());
+}
+
 ::std::auto_ptr<formula::FormulaTokenArray> ScFormulaDlg::convertToTokenArray(const uno::Sequence< sheet::FormulaToken >& _aTokenList)
 {
     ::std::auto_ptr<formula::FormulaTokenArray> pArray(new ScTokenArray());
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index 8daa034..0f85153 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -89,11 +89,12 @@ public:
                                 BOOL bInterpret, BOOL bApi );
     BOOL			SetCellText( const ScAddress& rPos, const String& rText,
                                     BOOL bInterpret, BOOL bEnglish, BOOL bApi,
+                                    const String& rFormulaNmsp,
                                     const formula::FormulaGrammar::Grammar eGrammar );
 
                     // creates a new cell for use with PutCell
     ScBaseCell*		InterpretEnglishString( const ScAddress& rPos, const String& rText,
-                                            const formula::FormulaGrammar::Grammar eGrammar );
+                        const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar );
 
     bool			ShowNote( const ScAddress& rPos, bool bShow = true );
     inline bool		HideNote( const ScAddress& rPos ) { return ShowNote( rPos, false ); }
@@ -147,6 +148,7 @@ public:
     BOOL			EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
                                     const ScTokenArray* pTokenArray,
                                     const String& rString, BOOL bApi, BOOL bEnglish,
+                                    const String& rFormulaNmsp,
                                     const formula::FormulaGrammar::Grammar );
 
     BOOL			TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
index 800437b..81d0517 100644
--- a/sc/source/ui/inc/formula.hxx
+++ b/sc/source/ui/inc/formula.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -100,11 +100,12 @@ public:
     virtual void setSelection(xub_StrLen _nStart,xub_StrLen _nEnd);
     virtual void getSelection(xub_StrLen& _nStart,xub_StrLen& _nEnd) const;
     virtual String getCurrentFormula() const;
-    
+
     virtual formula::IFunctionManager* getFunctionManager();
     virtual ::std::auto_ptr<formula::FormulaTokenArray> convertToTokenArray(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& _aTokenList);
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser> getFormulaParser() const;
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaOpCodeMapper> getFormulaOpCodeMapper() const;
+    virtual ::com::sun::star::table::CellAddress getReferencePosition() const;
 
     virtual BOOL	Close();
 
@@ -118,7 +119,7 @@ public:
     virtual void RefInputDone( BOOL bForced = FALSE );
     virtual BOOL IsTableLocked() const;
     virtual BOOL IsRefInputMode() const;
-    
+
     virtual BOOL IsDocAllowed( SfxObjectShell* pDocSh ) const;
     virtual void AddRefEntry();
     virtual void SetActive();
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 1531c08..7c2c29e 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -1170,8 +1170,8 @@ BOOL lcl_PutDataArray( ScDocShell& rDocShell, const ScRange& rRange,
 }
 
 BOOL lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
-                        const uno::Sequence< uno::Sequence<rtl::OUString> >& aData,
-                        const formula::FormulaGrammar::Grammar eGrammar )
+        const uno::Sequence< uno::Sequence<rtl::OUString> >& aData,
+        const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
 //	BOOL bApi = TRUE;
 
@@ -1226,7 +1226,7 @@ BOOL lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
             {
                 String aText(pColArr[nCol]);
                 ScAddress aPos( nDocCol, nDocRow, nTab );
-                ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aPos, aText, eGrammar );
+                ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aPos, aText, rFormulaNmsp, eGrammar );
                 pDoc->PutCell( aPos, pNewCell );
 
                 ++nDocCol;
@@ -5052,15 +5052,14 @@ rtl::OUString SAL_CALL ScCellRangeObj::getArrayFormula() throw(uno::RuntimeExcep
     return aFormula;
 }
 
-void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& aFormula,
-        const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
+void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& rFormula,
+        const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
 {
     ScDocShell* pDocSh = GetDocShell();
     if (pDocSh)
     {
-        String aString(aFormula);
         ScDocFunc aFunc(*pDocSh);
-        if ( aString.Len() )
+        if ( rFormula.getLength() )
         {
             if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
             {
@@ -5068,7 +5067,7 @@ void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& aFormula,
                 throw uno::RuntimeException();
             }
 
-            aFunc.EnterMatrix( aRange, NULL, NULL, aString, TRUE, TRUE, eGrammar );
+            aFunc.EnterMatrix( aRange, NULL, NULL, rFormula, TRUE, TRUE, rFormulaNmsp, eGrammar );
         }
         else
         {
@@ -5086,14 +5085,14 @@ void SAL_CALL ScCellRangeObj::setArrayFormula( const rtl::OUString& aFormula )
 {
     ScUnoGuard aGuard;
     // GRAM_PODF_A1 for API compatibility.
-    SetArrayFormula_Impl( aFormula,formula::FormulaGrammar::GRAM_PODF_A1);
+    SetArrayFormula_Impl( aFormula, ::rtl::OUString(), formula::FormulaGrammar::GRAM_PODF_A1);
 }
 
-void ScCellRangeObj::SetArrayFormulaWithGrammar( const rtl::OUString& aFormula,
-        const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
+void ScCellRangeObj::SetArrayFormulaWithGrammar( const rtl::OUString& rFormula,
+        const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
 {
     ScUnoGuard aGuard;
-    SetArrayFormula_Impl( aFormula, eGrammar);
+    SetArrayFormula_Impl( rFormula, rFormulaNmsp, eGrammar);
 }
 
 // XArrayFormulaTokens
@@ -5153,7 +5152,7 @@ void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::Formula
             // Actually GRAM_PODF_A1 is a don't-care here because of the token
             // array being set, it fits with other API compatibility grammars
             // though.
-            aFunc.EnterMatrix( aRange, NULL, &aTokenArray, EMPTY_STRING, TRUE, TRUE,formula::FormulaGrammar::GRAM_PODF_A1 );
+            aFunc.EnterMatrix( aRange, NULL, &aTokenArray, EMPTY_STRING, TRUE, TRUE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
         }
         else
         {
@@ -5269,7 +5268,7 @@ void SAL_CALL ScCellRangeObj::setFormulaArray(
     if (pDocSh)
     {
         // GRAM_PODF_A1 for API compatibility.
-        bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray,formula::FormulaGrammar::GRAM_PODF_A1 );
+        bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
     }
 
     if (!bDone)
@@ -6206,7 +6205,7 @@ void ScCellObj::SetString_Impl(const String& rString, BOOL bInterpret, BOOL bEng
     {
         ScDocFunc aFunc(*pDocSh);
         // GRAM_PODF_A1 for API compatibility.
-        (void)aFunc.SetCellText( aCellPos, rString, bInterpret, bEnglish, TRUE,formula::FormulaGrammar::GRAM_PODF_A1 );
+        (void)aFunc.SetCellText( aCellPos, rString, bInterpret, bEnglish, TRUE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
     }
 }
 
@@ -6254,13 +6253,13 @@ void ScCellObj::SetFormulaResultDouble( double fResult )
 }
 
 void ScCellObj::SetFormulaWithGrammar( const ::rtl::OUString& rFormula,
-                                        const formula::FormulaGrammar::Grammar eGrammar )
+        const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
     ScDocShell* pDocSh = GetDocShell();
     if ( pDocSh )
     {
         ScDocFunc aFunc(*pDocSh);
-        aFunc.SetCellText( aCellPos, String( rFormula), TRUE, TRUE, TRUE, eGrammar);
+        aFunc.SetCellText( aCellPos, rFormula, TRUE, TRUE, TRUE, rFormulaNmsp, eGrammar);
     }
 }
 
diff --git a/sc/source/ui/unoobj/fmtuno.cxx b/sc/source/ui/unoobj/fmtuno.cxx
index 59cd90e..5ea1c34 100644
--- a/sc/source/ui/unoobj/fmtuno.cxx
+++ b/sc/source/ui/unoobj/fmtuno.cxx
@@ -42,7 +42,6 @@
 
 #include "fmtuno.hxx"
 #include "miscuno.hxx"
-#include "conditio.hxx"
 #include "validat.hxx"
 #include "document.hxx"
 #include "unoguard.hxx"
@@ -51,7 +50,8 @@
 #include "tokenarray.hxx"
 #include "tokenuno.hxx"
 
-using namespace com::sun::star;
+using namespace ::com::sun::star;
+using namespace ::formula;
 
 //------------------------------------------------------------------------
 
@@ -130,12 +130,17 @@ ScConditionMode lcl_ConditionOperatorToMode( sheet::ConditionOperator eOper )
 
 //------------------------------------------------------------------------
 
-//UNUSED2008-05  ScTableConditionalFormat::ScTableConditionalFormat()
-//UNUSED2008-05  {
-//UNUSED2008-05  }
+ScCondFormatEntryItem::ScCondFormatEntryItem() :
+    meGrammar1( FormulaGrammar::GRAM_UNSPECIFIED ),
+    meGrammar2( FormulaGrammar::GRAM_UNSPECIFIED ),
+    meMode( SC_COND_NONE )
+{
+}
+
+//------------------------------------------------------------------------
 
-ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
-                                                    const formula::FormulaGrammar::Grammar eGrammar)
+ScTableConditionalFormat::ScTableConditionalFormat(
+        ScDocument* pDoc, ULONG nKey, FormulaGrammar::Grammar eGrammar)
 {
     //	Eintrag aus dem Dokument lesen...
 
@@ -156,11 +161,11 @@ ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
                 {
                     ScCondFormatEntryItem aItem;
                     const ScCondFormatEntry* pFormatEntry = pFormat->GetEntry(i);
-                    aItem.mnMode = sal::static_int_cast<USHORT>(pFormatEntry->GetOperation());
+                    aItem.meMode = pFormatEntry->GetOperation();
                     aItem.maPos = pFormatEntry->GetValidSrcPos();
                     aItem.maExpr1 = pFormatEntry->GetExpression(aItem.maPos, 0, 0, eGrammar);
                     aItem.maExpr2 = pFormatEntry->GetExpression(aItem.maPos, 1, 0, eGrammar);
-                    aItem.meGrammar = eGrammar;
+                    aItem.meGrammar1 = aItem.meGrammar2 = eGrammar;
                     aItem.maStyle = pFormatEntry->GetStyle();
 
                     AddEntry_Impl(aItem);
@@ -170,8 +175,20 @@ ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
     }
 }
 
+namespace {
+
+FormulaGrammar::Grammar lclResolveGrammar( FormulaGrammar::Grammar eExtGrammar, FormulaGrammar::Grammar eIntGrammar )
+{
+    if( eExtGrammar != FormulaGrammar::GRAM_UNSPECIFIED )
+        return eExtGrammar;
+    OSL_ENSURE( eIntGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "lclResolveGrammar - unspecified grammar, using GRAM_PODF_A1" );
+    return (eIntGrammar == FormulaGrammar::GRAM_UNSPECIFIED) ? FormulaGrammar::GRAM_PODF_A1 : eIntGrammar;
+}
+
+} // namespace
+
 void ScTableConditionalFormat::FillFormat( ScConditionalFormat& rFormat,
-                                            ScDocument* pDoc, formula::FormulaGrammar::Grammar eGrammar ) const
+        ScDocument* pDoc, FormulaGrammar::Grammar eGrammar) const
 {
     //	ScConditionalFormat = Core-Struktur, muss leer sein
 
@@ -185,15 +202,12 @@ void ScTableConditionalFormat::FillFormat( ScConditionalFormat& rFormat,
 
         ScCondFormatEntryItem aData;
         pEntry->GetData(aData);
-        if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
-            eGrammar = aData.meGrammar;
-        if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
-        {
-            DBG_ERRORFILE("FillFormat: unspecified grammar, using GRAM_PODF_A1");
-            eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
-        }
-        ScCondFormatEntry aCoreEntry( static_cast<ScConditionMode>(aData.mnMode),
-            aData.maExpr1, aData.maExpr2, pDoc, aData.maPos, aData.maStyle, eGrammar );
+
+        FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, aData.meGrammar1 );
+        FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, aData.meGrammar2 );
+
+        ScCondFormatEntry aCoreEntry( aData.meMode, aData.maExpr1, aData.maExpr2,
+            pDoc, aData.maPos, aData.maStyle, aData.maExprNmsp1, aData.maExprNmsp2, eGrammar1, eGrammar2 );
 
         if ( aData.maPosStr.Len() )
             aCoreEntry.SetSrcString( aData.maPosStr );
@@ -248,69 +262,86 @@ void SAL_CALL ScTableConditionalFormat::addNew(
 {
     ScUnoGuard aGuard;
     ScCondFormatEntryItem aEntry;
-    aEntry.mnMode = sal::static_int_cast<USHORT>(SC_COND_NONE);
+    aEntry.meMode = SC_COND_NONE;
 
     const beans::PropertyValue* pPropArray = aConditionalEntry.getConstArray();
     long nPropCount = aConditionalEntry.getLength();
     for (long i = 0; i < nPropCount; i++)
     {
         const beans::PropertyValue& rProp = pPropArray[i];
-        String aPropName(rProp.Name);
 
-        if ( aPropName.EqualsAscii( SC_UNONAME_OPERATOR ) )
+        if ( rProp.Name.equalsAscii( SC_UNONAME_OPERATOR ) )
         {
             sheet::ConditionOperator eOper = (sheet::ConditionOperator)
                             ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
-            aEntry.mnMode = sal::static_int_cast<USHORT>(lcl_ConditionOperatorToMode( eOper ));
+            aEntry.meMode = lcl_ConditionOperatorToMode( eOper );
         }
-        else if ( aPropName.EqualsAscii( SC_UNONAME_FORMULA1 ) )
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULA1 ) )
         {
             rtl::OUString aStrVal;
             uno::Sequence<sheet::FormulaToken> aTokens;
             if ( rProp.Value >>= aStrVal )
-                aEntry.maExpr1 = String( aStrVal );
+                aEntry.maExpr1 = aStrVal;
             else if ( rProp.Value >>= aTokens )
             {
                 aEntry.maExpr1.Erase();
                 aEntry.maTokens1 = aTokens;
             }
         }
-        else if ( aPropName.EqualsAscii( SC_UNONAME_FORMULA2 ) )
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULA2 ) )
         {
             rtl::OUString aStrVal;
             uno::Sequence<sheet::FormulaToken> aTokens;
             if ( rProp.Value >>= aStrVal )
-                aEntry.maExpr2 = String( aStrVal );
+                aEntry.maExpr2 = aStrVal;
             else if ( rProp.Value >>= aTokens )
             {
                 aEntry.maExpr2.Erase();
                 aEntry.maTokens2 = aTokens;
             }
         }
-        else if ( aPropName.EqualsAscii( SC_UNONAME_SOURCEPOS ) )
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_SOURCEPOS ) )
         {
             table::CellAddress aAddress;
             if ( rProp.Value >>= aAddress )
                 aEntry.maPos = ScAddress( (SCCOL)aAddress.Column, (SCROW)aAddress.Row, aAddress.Sheet );
         }
-        else if ( aPropName.EqualsAscii( SC_UNONAME_SOURCESTR ) )
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_SOURCESTR ) )
         {
             rtl::OUString aStrVal;
             if ( rProp.Value >>= aStrVal )
                 aEntry.maPosStr = String( aStrVal );
         }
-        else if ( aPropName.EqualsAscii( SC_UNONAME_STYLENAME ) )
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_STYLENAME ) )
         {
             rtl::OUString aStrVal;
             if ( rProp.Value >>= aStrVal )
                 aEntry.maStyle = ScStyleNameConversion::ProgrammaticToDisplayName(
                                                 aStrVal, SFX_STYLE_FAMILY_PARA );
         }
-        else if ( aPropName.EqualsAscii( SC_UNONAME_GRAMMAR ) )
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULANMSP1 ) )
+        {
+            rtl::OUString aStrVal;
+            if ( rProp.Value >>= aStrVal )
+                aEntry.maExprNmsp1 = aStrVal;
+        }
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULANMSP2 ) )
+        {
+            rtl::OUString aStrVal;
+            if ( rProp.Value >>= aStrVal )
+                aEntry.maExprNmsp2 = aStrVal;
+        }
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_GRAMMAR1 ) )
         {
             sal_Int32 nVal = 0;
             if ( rProp.Value >>= nVal )
-                aEntry.meGrammar = static_cast<formula::FormulaGrammar::Grammar>(nVal);
+                aEntry.meGrammar1 = static_cast< FormulaGrammar::Grammar >( nVal );
+        }
+        else if ( rProp.Name.equalsAscii( SC_UNONAME_GRAMMAR2 ) )
+        {
+            sal_Int32 nVal = 0;
+            if ( rProp.Value >>= nVal )
+                aEntry.meGrammar2 = static_cast< FormulaGrammar::Grammar >( nVal );
         }
         else
         {
@@ -523,14 +554,14 @@ sheet::ConditionOperator SAL_CALL ScTableConditionalEntry::getOperator()
                                                 throw(uno::RuntimeException)
 {
     ScUnoGuard aGuard;
-    return lcl_ConditionModeToOperator( static_cast<ScConditionMode>(aData.mnMode) );
+    return lcl_ConditionModeToOperator( aData.meMode );
 }
 
 void SAL_CALL ScTableConditionalEntry::setOperator( sheet::ConditionOperator nOperator )
                                                 throw(uno::RuntimeException)
 {
     ScUnoGuard aGuard;
-    aData.mnMode = sal::static_int_cast<USHORT>( lcl_ConditionOperatorToMode( nOperator ) );
+    aData.meMode = lcl_ConditionOperatorToMode( nOperator );
     if (pParent)
         pParent->DataChanged();
 }
@@ -619,7 +650,7 @@ ScTableValidationObj::ScTableValidationObj(ScDocument* pDoc, ULONG nKey,
             aSrcPos = pData->GetValidSrcPos();  // #b4974740# valid pos for expressions
             aExpr1 = pData->GetExpression( aSrcPos, 0, 0, eGrammar );
             aExpr2 = pData->GetExpression( aSrcPos, 1, 0, eGrammar );
-            meGrammar = eGrammar;
+            meGrammar1 = meGrammar2 = eGrammar;
             nValMode = sal::static_int_cast<USHORT>( pData->GetDataMode() );
             bIgnoreBlank = pData->IsIgnoreBlank();
             nShowList = pData->GetListType();
@@ -628,9 +659,9 @@ ScTableValidationObj::ScTableValidationObj(ScDocument* pDoc, ULONG nKey,
             bShowError = pData->GetErrMsg( aErrorTitle, aErrorMessage, eStyle );
             nErrorStyle = sal::static_int_cast<USHORT>( eStyle );
 
-            // During save to XML, sheet::ValidationType_ANY formulas are not 
-            // saved, even if in the list, see  
-            // ScMyValidationsContainer::GetCondition(), so shall not mark 
+            // During save to XML, sheet::ValidationType_ANY formulas are not
+            // saved, even if in the list, see
+            // ScMyValidationsContainer::GetCondition(), so shall not mark
             // anything in use.
             if (nValMode != SC_VALID_ANY && pDoc->IsInExternalReferenceMarking())
                 pData->MarkUsedExternalReferences();
@@ -647,18 +678,14 @@ ScValidationData* ScTableValidationObj::CreateValidationData( ScDocument* pDoc,
 {
     //	ScValidationData = Core-Struktur
 
-    if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
-        eGrammar = meGrammar;
-    if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
-    {
-        DBG_ERRORFILE("CreateValidationData: unspecified grammar, using GRAM_PODF_A1");
-        eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
-    }
+    FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, meGrammar1 );
+    FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, meGrammar2 );
 
     ScValidationData* pRet = new ScValidationData( (ScValidationMode)nValMode,
                                                    (ScConditionMode)nMode,
                                                    aExpr1, aExpr2, pDoc, aSrcPos,
-                                                   eGrammar );
+                                                   maExprNmsp1, maExprNmsp2,
+                                                   eGrammar1, eGrammar2 );
     pRet->SetIgnoreBlank(bIgnoreBlank);
     pRet->SetListType(nShowList);
 
@@ -702,7 +729,9 @@ void ScTableValidationObj::ClearData_Impl()
     aSrcPos.Set(0,0,0);
     aExpr1.Erase();
     aExpr2.Erase();
-    meGrammar = formula::FormulaGrammar::GRAM_UNSPECIFIED;  // will be overriden when needed
+    maExprNmsp1.Erase();
+    maExprNmsp2.Erase();
+    meGrammar1 = meGrammar2 = FormulaGrammar::GRAM_UNSPECIFIED;  // will be overriden when needed
     aInputTitle.Erase();
     aInputMessage.Erase();
     aErrorTitle.Erase();
@@ -905,13 +934,37 @@ void SAL_CALL ScTableValidationObj::setPropertyValue(
         if ( aValue >>= aStrVal )
             aPosString = String( aStrVal );
     }
-    else if ( aString.EqualsAscii( SC_UNONAME_GRAMMAR ) )
+    else if ( aString.EqualsAscii( SC_UNONAME_FORMULANMSP1 ) )
+    {
+        // internal - only for XML filter, not in PropertySetInfo, only set
+
+        rtl::OUString aStrVal;
+        if ( aValue >>= aStrVal )
+            maExprNmsp1 = aStrVal;
+    }
+    else if ( aString.EqualsAscii( SC_UNONAME_FORMULANMSP2 ) )
+    {
+        // internal - only for XML filter, not in PropertySetInfo, only set
+
+        rtl::OUString aStrVal;
+        if ( aValue >>= aStrVal )
+            maExprNmsp2 = aStrVal;
+    }
+    else if ( aString.EqualsAscii( SC_UNONAME_GRAMMAR1 ) )
+    {
+        // internal - only for XML filter, not in PropertySetInfo, only set
+
+        sal_Int32 nVal = 0;
+        if ( aValue >>= nVal )
+            meGrammar1 = static_cast< FormulaGrammar::Grammar >(nVal);
+    }
+    else if ( aString.EqualsAscii( SC_UNONAME_GRAMMAR2 ) )
     {
         // internal - only for XML filter, not in PropertySetInfo, only set
 
         sal_Int32 nVal = 0;
         if ( aValue >>= nVal )
-            meGrammar = static_cast<formula::FormulaGrammar::Grammar>(nVal);
+            meGrammar2 = static_cast< FormulaGrammar::Grammar >(nVal);
     }
 
     DataChanged();
diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx
index c543b58..e6e194d 100644
--- a/sc/source/ui/unoobj/tokenuno.cxx
+++ b/sc/source/ui/unoobj/tokenuno.cxx
@@ -51,17 +51,16 @@
 #include "docsh.hxx"
 #include "rangeseq.hxx"
 #include "externalrefmgr.hxx"
-using namespace formula;
 
-using namespace com::sun::star;
+using namespace ::formula;
+using namespace ::com::sun::star;
 
-//------------------------------------------------------------------------
+// ============================================================================
 
 const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap()
 {
     static SfxItemPropertyMapEntry aFormulaParserMap_Impl[] =
     {
-        {MAP_CHAR_LEN(SC_UNO_REFERENCEPOS),         0,  &getCppuType((table::CellAddress*)0),    0, 0 },
         {MAP_CHAR_LEN(SC_UNO_COMPILEFAP),           0,  &getBooleanCppuType(),                   0, 0 },
         {MAP_CHAR_LEN(SC_UNO_COMPILEENGLISH),       0,  &getBooleanCppuType(),                   0, 0 },
         {MAP_CHAR_LEN(SC_UNO_IGNORELEADING),        0,  &getBooleanCppuType(),                   0, 0 },
@@ -74,7 +73,7 @@ const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap()
 
 SC_SIMPLE_SERVICE_INFO( ScFormulaParserObj, "ScFormulaParserObj", SC_SERVICENAME_FORMULAPARS )
 
-//------------------------------------------------------------------------
+// ============================================================================
 
 ScFormulaParserObj::ScFormulaParserObj(ScDocShell* pDocSh) :
     mpDocShell( pDocSh ),
@@ -135,7 +134,8 @@ void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
     rCompiler.SetExternalLinks( maExternalLinks);
 }
 
-uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( const rtl::OUString& aFormula )
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula(
+        const rtl::OUString& aFormula, const table::CellAddress& rReferencePos )
                                 throw (uno::RuntimeException)
 {
     ScUnoGuard aGuard;
@@ -143,8 +143,10 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( co
 
     if (mpDocShell)
     {
+        ScAddress aRefPos( ScAddress::UNINITIALIZED );
+        ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
         ScDocument* pDoc = mpDocShell->GetDocument();
-        ScCompiler aCompiler( pDoc, maRefPos);
+        ScCompiler aCompiler( pDoc, aRefPos);
         aCompiler.SetGrammar(pDoc->GetGrammar());
         SetCompilerFlags( aCompiler );
 
@@ -156,7 +158,8 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( co
     return aRet;
 }
 
-rtl::OUString SAL_CALL ScFormulaParserObj::printFormula( const uno::Sequence<sheet::FormulaToken>& aTokens )
+rtl::OUString SAL_CALL ScFormulaParserObj::printFormula(
+        const uno::Sequence<sheet::FormulaToken>& aTokens, const table::CellAddress& rReferencePos )
                                 throw (uno::RuntimeException)
 {
     ScUnoGuard aGuard;
@@ -167,7 +170,9 @@ rtl::OUString SAL_CALL ScFormulaParserObj::printFormula( const uno::Sequence<she
         ScDocument* pDoc = mpDocShell->GetDocument();
         ScTokenArray aCode;
         (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aCode, aTokens );
-        ScCompiler aCompiler( pDoc, maRefPos, aCode);
+        ScAddress aRefPos( ScAddress::UNINITIALIZED );
+        ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
+        ScCompiler aCompiler( pDoc, aRefPos, aCode);
         aCompiler.SetGrammar(pDoc->GetGrammar());
         SetCompilerFlags( aCompiler );
 
@@ -197,13 +202,7 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
 {
     ScUnoGuard aGuard;
     String aString(aPropertyName);
-    if ( aString.EqualsAscii( SC_UNO_REFERENCEPOS ) )
-    {
-        table::CellAddress aAddress;
-        aValue >>= aAddress;
-        ScUnoConversion::FillScAddress( maRefPos, aAddress );
-    } // if ( aString.EqualsAscii( SC_UNO_REFERENCEPOS ) )
-    else if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
+    if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
     {
         aValue >>= mbCompileFAP;
     }
@@ -218,7 +217,7 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
             if (mxOpCodeMap.get() && mbEnglish != bOldEnglish)
             {
                 ScDocument* pDoc = mpDocShell->GetDocument();
-                ScCompiler aCompiler( pDoc, maRefPos);
+                ScCompiler aCompiler( pDoc, ScAddress());
                 aCompiler.SetGrammar(pDoc->GetGrammar());
                 mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
             }
@@ -239,7 +238,7 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
         if (aValue >>= maOpCodeMapping)
         {
             ScDocument* pDoc = mpDocShell->GetDocument();
-            ScCompiler aCompiler( pDoc, maRefPos);
+            ScCompiler aCompiler( pDoc, ScAddress());
             aCompiler.SetGrammar(pDoc->GetGrammar());
             mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
         }
@@ -262,13 +261,7 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
     ScUnoGuard aGuard;
     uno::Any aRet;
     String aString(aPropertyName);
-    if ( aString.EqualsAscii( SC_UNO_REFERENCEPOS ) )
-    {
-        table::CellAddress aAddress;
-        ScUnoConversion::FillApiAddress( aAddress, maRefPos );
-        aRet <<= aAddress;
-    }
-    else if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
+    if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
     {
         aRet <<= mbCompileFAP;
     }
@@ -299,7 +292,7 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
 
 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFormulaParserObj )
 
-//------------------------------------------------------------------------
+// ============================================================================
 
 void lcl_ExternalRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef )
 {
@@ -463,9 +456,13 @@ bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc,
 
     return !bError;
 }
-// -----------------------------------------------------------------------------
+
+// ============================================================================
+
 ScFormulaOpCodeMapperObj::ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler)
 : formula::FormulaOpCodeMapperObj(_pCompiler)
 {
 }
 
+// ============================================================================
+
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 4f52f31..2842e50 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -926,7 +926,7 @@ void ScViewFunc::EnterMatrix( const String& rString )
     if (pData->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
     {
         ScDocShell* pDocSh = pData->GetDocShell();
-        BOOL bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, FALSE, FALSE,formula::FormulaGrammar::GRAM_DEFAULT );
+        BOOL bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, FALSE, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
         if (bSuccess)
             pDocSh->UpdateOle(GetViewData());
     }


More information about the ooo-build-commit mailing list