[Libreoffice-commits] .: 2 commits - sc/inc sc/source

Noel Power noelp at kemper.freedesktop.org
Wed Mar 28 14:56:31 PDT 2012


 sc/inc/document.hxx                          |    2 
 sc/inc/tokenuno.hxx                          |    2 
 sc/source/filter/inc/defnamesbuffer.hxx      |    4 
 sc/source/filter/inc/numberformatsbuffer.hxx |    5 
 sc/source/filter/inc/sheetdatabuffer.hxx     |    3 
 sc/source/filter/inc/stylesbuffer.hxx        |   36 +
 sc/source/filter/inc/workbookhelper.hxx      |   12 
 sc/source/filter/oox/defnamesbuffer.cxx      |   28 -
 sc/source/filter/oox/numberformatsbuffer.cxx |   22 
 sc/source/filter/oox/sheetdatabuffer.cxx     |  153 ++++++
 sc/source/filter/oox/stylesbuffer.cxx        |  600 +++++++++++++++++++++++++--
 sc/source/filter/oox/workbookhelper.cxx      |   79 +++
 12 files changed, 858 insertions(+), 88 deletions(-)

New commits:
commit 2cd77ac75ad16a0eb7ee2e3df30e5cb0950bf673
Author: Noel Power <noel.power at novell.com>
Date:   Wed Mar 28 22:55:40 2012 +0100

    don't use uno when importing styles ( xlsx,xlsm) )
    
    Attempt to move away from uno calls, added AVOID_UNO define in sc/source/filter/inc/workbookhelper.hxx to aid with transition ( AVOID_UNO = 0 runs the old code and uses the uno api )

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index bc48fab..6b2139b 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1279,7 +1279,7 @@ public:
                             SCCOL nVCol, SCROW nVRow, SCTAB nVTab,
                             const rtl::OUString& sValStr, double& nX);
 
-    void            ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark,
+    SC_DLLPUBLIC void            ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark,
                                            ScEditDataArray* pDataArray = NULL );
     void            DeleteSelection( sal_uInt16 nDelFlag, const ScMarkData& rMark );
     void            DeleteSelectionTab( SCTAB nTab, sal_uInt16 nDelFlag, const ScMarkData& rMark );
diff --git a/sc/source/filter/inc/numberformatsbuffer.hxx b/sc/source/filter/inc/numberformatsbuffer.hxx
index 5914ab9..6df9586 100644
--- a/sc/source/filter/inc/numberformatsbuffer.hxx
+++ b/sc/source/filter/inc/numberformatsbuffer.hxx
@@ -30,6 +30,7 @@
 #define OOX_XLS_NUMBERFORMATSBUFFER_HXX
 
 #include <com/sun/star/lang/Locale.hpp>
+#include <svl/itemset.hxx>
 #include "workbookhelper.hxx"
 
 namespace com { namespace sun { namespace star {
@@ -85,7 +86,7 @@ public:
     sal_Int32           finalizeImport(
                             const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats >& rxNumFmts,
                             const ::com::sun::star::lang::Locale& rFromLocale );
-
+    void                fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const;
     /** Writes the number format to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap ) const;
 
@@ -116,6 +117,8 @@ public:
     /** Final processing after import of all style settings. */
     void                finalizeImport();
 
+    void                fillToItemSet( SfxItemSet& rItemSet, sal_Int32 nNumFmtId, bool bSkipPoolDefs = false ) const;
+
     /** Writes the specified number format to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const;
 
diff --git a/sc/source/filter/inc/sheetdatabuffer.hxx b/sc/source/filter/inc/sheetdatabuffer.hxx
index 743c6c0..9046a2f 100644
--- a/sc/source/filter/inc/sheetdatabuffer.hxx
+++ b/sc/source/filter/inc/sheetdatabuffer.hxx
@@ -269,7 +269,7 @@ private:
 
     /** Writes all cell formatting attributes to the passed cell range list. (depreciates writeXfIdRangeProperties) */
     void                writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const;
-
+    void                applyCellMerging( const ::com::sun::star::table::CellRangeAddress& rRange );
     /** Merges the passed merged range and updates right/bottom cell borders. */
     void                finalizeMergedRange( const ::com::sun::star::table::CellRangeAddress& rRange );
 
diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx
index af5d6ff..9906c61 100644
--- a/sc/source/filter/inc/stylesbuffer.hxx
+++ b/sc/source/filter/inc/stylesbuffer.hxx
@@ -40,7 +40,12 @@
 #include "oox/helper/refmap.hxx"
 #include "oox/helper/refvector.hxx"
 #include "numberformatsbuffer.hxx"
+#include "patattr.hxx"
+#include "stlsheet.hxx"
+#include <editeng/svxenum.hxx>
+#include <editeng/frmdir.hxx>
 
+class ScMarkData;
 namespace com { namespace sun { namespace star {
     namespace awt { struct FontDescrtiptor; }
 } } }
@@ -303,6 +308,7 @@ public:
         needs an rich text cell for this attribute. */
     bool                needsRichTextFormat() const;
 
+    void                fillToItemSet( SfxItemSet& rItemSet, FontPropertyType ePropType, bool bSkipPoolDefs = false ) const;
     /** Writes all font attributes to the passed property map. */
     void                writeToPropertyMap(
                             PropertyMap& rPropMap,
@@ -411,10 +417,14 @@ public:
     /** Returns the converted API alignment data struct. */
     inline const ApiAlignmentData& getApiData() const { return maApiData; }
 
+    void                fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs = false ) const;
     /** Writes all alignment attributes to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap ) const;
 
 private:
+    ::SvxCellHorJustify GetScHorAlign() const;
+    ::SvxCellVerJustify GetScVerAlign() const;
+    ::SvxFrameDirection GetScFrameDir() const;
     AlignmentModel      maModel;            /// Alignment model data.
     ApiAlignmentData    maApiData;          /// Alignment data converted to API constants.
 };
@@ -473,7 +483,7 @@ public:
 
     /** Writes all protection attributes to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap ) const;
-
+    void                fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs = false ) const;
 private:
     ProtectionModel     maModel;            /// Protection model data.
     ApiProtectionData   maApiData;          /// Protection data converted to API constants.
@@ -576,6 +586,8 @@ public:
     /** Returns the converted API border data struct. */
     inline const ApiBorderData& getApiData() const { return maApiData; }
 
+    void                fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const;
+
     /** Writes all border attributes to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap ) const;
 
@@ -708,6 +720,7 @@ public:
     /** Returns the converted API fill data struct. */
     inline const ApiSolidFillData& getApiData() const { return maApiData; }
 
+    void                fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs = false ) const;
     /** Writes all fill attributes to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap ) const;
 
@@ -790,6 +803,7 @@ public:
     /** Returns the cell protection data of this style. */
     inline const Protection& getProtection() const { return maProtection; }
 
+    void  writeToMarkData( ::ScMarkData& rMarkData, sal_Int32 nNumFmtId  );
     /** Writes all formatting attributes to the passed property map. */
     void                writeToPropertyMap( PropertyMap& rPropMap ) const;
     /** Writes all formatting attributes to the passed property set. */
@@ -799,15 +813,23 @@ public:
     static void         writeBiff2CellFormatToPropertySet(
                             const WorkbookHelper& rHelper, PropertySet& rPropSet,
                             sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 );
+
+    const ::ScPatternAttr& createPattern( bool bSkipPoolDefs = false );
+
 private:
     /** Sets 'attribute used' flags from the passed BIFF bit field. */
     void                setBiffUsedFlags( sal_uInt8 nUsedFlags );
 
 private:
+    typedef ::std::auto_ptr< ::ScPatternAttr > ScPatternAttrPtr;
+
+    ScPatternAttrPtr    mpPattern;          /// Calc item set.
+
     XfModel             maModel;            /// Cell XF or style XF model data.
     Alignment           maAlignment;        /// Cell alignment data.
     Protection          maProtection;       /// Cell protection data.
     sal_Int32           meRotationRef;      /// Rotation reference dependent on border.
+    ::ScStyleSheet*       mpStyleSheet;       /// Calc cell style sheet.
 };
 
 bool operator==( const Xf& rXf1,  const Xf& rXf2 );
@@ -901,11 +923,14 @@ public:
     inline const CellStyleModel& getModel() const { return maModel; }
     /** Returns the final style name used in the document. */
     inline const ::rtl::OUString& getFinalStyleName() const { return maFinalName; }
+    ::ScStyleSheet*       createStyleSheet();
 
 private:
     CellStyleModel      maModel;
     ::rtl::OUString     maFinalName;        /// Final style name used in API.
     bool                mbCreated;          /// True = style sheet created.
+    ::ScStyleSheet*     mpStyleSheet;       /// Calc cell style sheet.
+
 };
 
 typedef ::boost::shared_ptr< CellStyle > CellStyleRef;
@@ -1053,14 +1078,19 @@ public:
     /** Creates the style sheet described by the DXF with the passed identifier. */
     ::rtl::OUString     createDxfStyle( sal_Int32 nDxfId ) const;
 
+    void                writeFontToItemSet( SfxItemSet& rItemSet, sal_Int32 nFontId, bool bSkipPoolDefs = false ) const;
     /** Writes the font attributes of the specified font data to the passed property map. */
     void                writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const;
+    void                writeNumFmtToItemSet( SfxItemSet& rItemSet, sal_Int32 nNumFmtId, bool bSkipPoolDefs = false ) const;
     /** Writes the specified number format to the passed property map. */
     void                writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const;
+    void                writeBorderToItemSet( SfxItemSet& rItemSet, sal_Int32 nBorderId, bool bSkipPoolDefs = false ) const;
     /** Writes the border attributes of the specified border data to the passed property map. */
     void                writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const;
     /** Writes the fill attributes of the specified fill data to the passed property map. */
+    void                writeFillToItemSet( SfxItemSet& rItemSet, sal_Int32 nFillId, bool bSkipPoolDefs = false ) const;
     void                writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const;
+    void                writeCellXfToMarkData( ::ScMarkData& rMark, sal_Int32 nXfId, sal_Int32 nNumFmtId );
     /** Writes the cell formatting attributes of the specified XF to the passed property map. */
     void                writeCellXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const;
 
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index 1bdd96d..8a048c5 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -34,6 +34,9 @@
 #include "oox/helper/storagebase.hxx"
 #include "biffhelper.hxx"
 
+// use AVOID_UNO = 1 to prefer core calls over uno
+#define AVOID_UNO 1
+
 namespace com { namespace sun { namespace star {
     namespace container { class XNameAccess; }
     namespace container { class XNameContainer; }
diff --git a/sc/source/filter/oox/numberformatsbuffer.cxx b/sc/source/filter/oox/numberformatsbuffer.cxx
index e8a9ca5..1eab9e5 100644
--- a/sc/source/filter/oox/numberformatsbuffer.cxx
+++ b/sc/source/filter/oox/numberformatsbuffer.cxx
@@ -38,10 +38,14 @@
 #include <rtl/string.hxx>
 #include <osl/thread.h>
 #include <rtl/ustrbuf.hxx>
+#include <svl/intitem.hxx>
 #include "oox/core/filterbase.hxx"
 #include "oox/helper/attributelist.hxx"
 #include "oox/helper/propertymap.hxx"
 #include "biffinputstream.hxx"
+#include "scitems.hxx"
+#include "document.hxx"
+#include "ftools.hxx"
 
 namespace oox {
 namespace xls {
@@ -1935,6 +1939,18 @@ sal_Int32 NumberFormat::finalizeImport( const Reference< XNumberFormats >& rxNum
     return maApiData.mnIndex;
 }
 
+void NumberFormat::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+    ScDocument& rDoc = getScDocument();
+    static sal_uLong  nDflt = rDoc.GetFormatTable()->GetStandardFormat( ScGlobal::eLnge );
+    sal_uLong nScNumFmt = nDflt;
+    if ( maApiData.mnIndex )
+        nScNumFmt = maApiData.mnIndex;
+    ScfTools::PutItem( rItemSet, SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ), bSkipPoolDefs );
+    if( rItemSet.GetItemState( ATTR_VALUE_FORMAT, false ) == SFX_ITEM_SET )
+        ScGlobal::AddLanguage( rItemSet, *(rDoc.GetFormatTable()) );
+}
+
 void NumberFormat::writeToPropertyMap( PropertyMap& rPropMap ) const
 {
     rPropMap[ PROP_NumberFormat ] <<= maApiData.mnIndex;
@@ -2036,6 +2052,12 @@ void NumberFormatsBuffer::finalizeImport()
     maNumFmts.forEach( NumberFormatFinalizer( *this ) );
 }
 
+void NumberFormatsBuffer::fillToItemSet( SfxItemSet& rItemSet, sal_Int32 nNumFmtId, bool bSkipPoolDefs ) const
+{
+    if( const NumberFormat* pNumFmt = maNumFmts.get( nNumFmtId ).get() )
+        pNumFmt->fillToItemSet( rItemSet, bSkipPoolDefs);
+}
+
 void NumberFormatsBuffer::writeToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const
 {
     if( const NumberFormat* pNumFmt = maNumFmts.get( nNumFmtId ).get() )
diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx
index 4904a0c..05ff3bb 100644
--- a/sc/source/filter/oox/sheetdatabuffer.cxx
+++ b/sc/source/filter/oox/sheetdatabuffer.cxx
@@ -41,6 +41,9 @@
 #include <com/sun/star/util/XNumberFormatTypes.hpp>
 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
 #include <rtl/ustrbuf.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/editobj.hxx>
+#include <svl/eitem.hxx>
 #include "oox/helper/containerhelper.hxx"
 #include "oox/helper/propertymap.hxx"
 #include "oox/helper/propertyset.hxx"
@@ -50,6 +53,12 @@
 #include "formulaparser.hxx"
 #include "sharedstringsbuffer.hxx"
 #include "unitconverter.hxx"
+#include "convuno.hxx"
+#include "markdata.hxx"
+#include "rangelst.hxx"
+#include "document.hxx"
+#include "scitems.hxx"
+#include "cell.hxx"
 
 namespace oox {
 namespace xls {
@@ -279,7 +288,7 @@ void SheetDataBuffer::setStringCell( const CellModel& rModel, sal_Int32 nStringI
         setBlankCell( rModel );
 }
 
-void SheetDataBuffer::setDateTimeCell( const CellModel& rModel, const DateTime& rDateTime )
+void SheetDataBuffer::setDateTimeCell( const CellModel& rModel, const ::com::sun::star::util::DateTime& rDateTime )
 {
     // write serial date/time value into the cell
     double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime );
@@ -478,8 +487,22 @@ void SheetDataBuffer::finalizeImport()
             CellRangeAddress aRange( getSheetIndex(), 0, rangeIter->mnFirst, rAddrConv.getMaxApiAddress().Column, rangeIter->mnLast );
             rangeList.push_back( aRange );
         }
+#if AVOID_UNO
+        ScRangeList aList;
+        for ( ApiCellRangeList::const_iterator itRange = rangeList.begin(), itRange_end = rangeList.end(); itRange!=itRange_end; ++itRange )
+        {
+            ScRange* pRange = new ScRange();
+            ScUnoConversion::FillScRange( *pRange, *itRange );
+            aList.push_back( pRange );
+        }
+        ScMarkData aMark;
+        aMark.MarkFromRangeList( aList, false );
+
+        getStyles().writeCellXfToMarkData( aMark, it->first, -1 );
+#else
         PropertySet aPropSet( getCellRangeList( rangeList ) );
         getStyles().writeCellXfToPropertySet( aPropSet, it->first );
+#endif
     }
     std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList > rangeStyleListMap;
     // gather all ranges that have the same style and apply them in bulk
@@ -489,9 +512,17 @@ void SheetDataBuffer::finalizeImport()
         writeXfIdRangeListProperties( it->first.first, it->first.second, it->second );
     // merge all cached merged ranges and update right/bottom cell borders
     for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt )
+#if AVOID_UNO
+        applyCellMerging( aIt->maRange );
+#else
         finalizeMergedRange( aIt->maRange );
+#endif
     for( MergedRangeList::iterator aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt )
+#if AVOID_UNO
+        applyCellMerging( aIt->maRange );
+#else
         finalizeMergedRange( aIt->maRange );
+#endif
 }
 
 // private --------------------------------------------------------------------
@@ -756,6 +787,18 @@ void SheetDataBuffer::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowR
 void SheetDataBuffer::writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const
 {
     StylesBuffer& rStyles = getStyles();
+#if AVOID_UNO
+    ScRangeList aList;
+    for ( ApiCellRangeList::const_iterator it = rRanges.begin(), it_end = rRanges.end(); it!=it_end; ++it )
+    {
+        ScRange* pRange = new ScRange();
+        ScUnoConversion::FillScRange( *pRange, *it );
+        aList.push_back( pRange );
+    }
+    ScMarkData aMark;
+    aMark.MarkFromRangeList( aList, false );
+    rStyles.writeCellXfToMarkData( aMark, nXfId, nNumFmtId );
+#else
     PropertyMap aPropMap;
     if( nXfId >= 0 )
         rStyles.writeCellXfToPropertyMap( aPropMap, nXfId );
@@ -763,6 +806,55 @@ void SheetDataBuffer::writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 n
         rStyles.writeNumFmtToPropertyMap( aPropMap, nNumFmtId );
     PropertySet aPropSet( getCellRangeList( rRanges ) );
     aPropSet.setProperties( aPropMap );
+#endif
+}
+
+void lcl_SetBorderLine( ScDocument& rDoc, ScRange& rRange, SCTAB nScTab, sal_uInt16 nLine )
+{
+    SCCOL nFromScCol = (nLine == BOX_LINE_RIGHT) ? rRange.aEnd.Col() : rRange.aStart.Col();
+    SCROW nFromScRow = (nLine == BOX_LINE_BOTTOM) ? rRange.aEnd.Row() : rRange.aStart.Row();
+
+    const SvxBoxItem* pFromItem = static_cast< const SvxBoxItem* >(
+        rDoc.GetAttr( nFromScCol, nFromScRow, nScTab, ATTR_BORDER ) );
+    const SvxBoxItem* pToItem = static_cast< const SvxBoxItem* >(
+        rDoc.GetAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, ATTR_BORDER ) );
+
+    SvxBoxItem aNewItem( *pToItem );
+    aNewItem.SetLine( pFromItem->GetLine( nLine ), nLine );
+    rDoc.ApplyAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, aNewItem );
+}
+
+void SheetDataBuffer::applyCellMerging( const CellRangeAddress& rRange )
+{
+    bool bMultiCol = rRange.StartColumn < rRange.EndColumn;
+    bool bMultiRow = rRange.StartRow < rRange.EndRow;
+
+    ScRange aRange;
+    ScUnoConversion::FillScRange( aRange, rRange );
+    const ScAddress& rStart = aRange.aStart;
+    const ScAddress& rEnd = aRange.aEnd;
+    ScDocument& rDoc = getScDocument();
+    // set correct right border
+    if( bMultiCol )
+        lcl_SetBorderLine( rDoc, aRange, getSheetIndex(), BOX_LINE_RIGHT );
+        // set correct lower border
+    if( bMultiRow )
+        lcl_SetBorderLine( rDoc, aRange, getSheetIndex(), BOX_LINE_BOTTOM );
+    // do merge
+    if( bMultiCol || bMultiRow )
+        rDoc.DoMerge( getSheetIndex(), rStart.Col(), rStart.Row(), rEnd.Col(), rEnd.Row() );
+    // #i93609# merged range in a single row: test if manual row height is needed
+    if( !bMultiRow )
+    {
+        bool bTextWrap = static_cast< const SfxBoolItem* >( rDoc.GetAttr( rStart.Col(), rStart.Row(), rStart.Tab(), ATTR_LINEBREAK ) )->GetValue();
+        if( !bTextWrap && (rDoc.GetCellType( rStart ) == CELLTYPE_EDIT) )
+        {
+            if( const EditTextObject* pEditObj = static_cast< const ScEditCell* >( rDoc.GetCell( rStart ) )->GetData() )
+                bTextWrap = pEditObj->GetParagraphCount() > 1;
+            if( bTextWrap )
+                setManualRowHeight(  rStart.Row() );
+        }
+    }
 }
 
 void SheetDataBuffer::finalizeMergedRange( const CellRangeAddress& rRange )
diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx
index 4d2b618..b9bcdd8 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -46,18 +46,44 @@
 #include <com/sun/star/table/CellVertJustify2.hpp>
 #include <com/sun/star/table/CellJustifyMethod.hpp>
 #include <com/sun/star/table/TableBorder.hpp>
+#include <editeng/justifyitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <tools/fontenum.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
 #include <rtl/tencinfo.h>
 #include <rtl/ustrbuf.hxx>
-#include "oox/core/filterbase.hxx"
-#include "oox/helper/attributelist.hxx"
-#include "oox/helper/containerhelper.hxx"
-#include "oox/helper/propertymap.hxx"
-#include "oox/helper/propertyset.hxx"
+#include <oox/core/filterbase.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/helper/containerhelper.hxx>
+#include <oox/helper/propertymap.hxx>
+#include <oox/helper/propertyset.hxx>
 #include "biffinputstream.hxx"
 #include "condformatbuffer.hxx"
 #include "excelhandlers.hxx"
 #include "themebuffer.hxx"
 #include "unitconverter.hxx"
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "docpool.hxx"
+#include "ftools.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
 
 using ::com::sun::star::table::BorderLine2;
 namespace oox {
@@ -1099,6 +1125,134 @@ bool Font::needsRichTextFormat() const
 {
     return maApiData.mnEscapement != API_ESCAPE_NONE;
 }
+::FontFamily lcl_getFontFamily( sal_Int32 nFamily )
+{
+    namespace cssawt = ::com::sun::star::awt;
+
+    ::FontFamily eScFamily = FAMILY_DONTKNOW;
+    switch( nFamily )
+    {
+        case cssawt::FontFamily::DONTKNOW:
+            eScFamily = FAMILY_DONTKNOW;
+            break;
+        case cssawt::FontFamily::ROMAN:
+            eScFamily = FAMILY_ROMAN;
+            break;
+        case cssawt::FontFamily::SWISS:
+            eScFamily = FAMILY_SWISS;
+            break;
+        case cssawt::FontFamily::MODERN:
+            eScFamily = FAMILY_MODERN;
+            break;
+        case cssawt::FontFamily::SCRIPT:
+            eScFamily = FAMILY_SCRIPT;
+            break;
+        case cssawt::FontFamily::DECORATIVE:
+            eScFamily = FAMILY_DECORATIVE;
+            break;
+    }
+    return eScFamily;
+}
+
+void Font::fillToItemSet( SfxItemSet& rItemSet, FontPropertyType ePropType, bool bSkipPoolDefs ) const
+{
+    namespace cssawt = ::com::sun::star::awt;
+    if ( maUsedFlags.mbNameUsed )
+    {
+        if( !maApiData.maLatinFont.maName.isEmpty() )
+        {
+            rtl_TextEncoding eFontEnc = maApiData.maLatinFont.mnTextEnc;
+            SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maLatinFont.mnFamily ), maApiData.maLatinFont.maName, rtl::OUString(),
+                PITCH_DONTKNOW, eFontEnc, ATTR_FONT );
+        }
+        if( !maApiData.maAsianFont.maName.isEmpty() )
+        {
+            rtl_TextEncoding eFontEnc = maApiData.maAsianFont.mnTextEnc;
+            SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maAsianFont.mnFamily ), maApiData.maAsianFont.maName, rtl::OUString(),
+                PITCH_DONTKNOW, eFontEnc, ATTR_FONT );
+        }
+        if( !maApiData.maCmplxFont.maName.isEmpty() )
+        {
+            rtl_TextEncoding eFontEnc = maApiData.maCmplxFont.mnTextEnc;
+            SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maCmplxFont.mnFamily ), maApiData.maCmplxFont.maName, rtl::OUString(),
+                PITCH_DONTKNOW, eFontEnc, ATTR_FONT );
+        }
+    }
+    // font height
+    if( maUsedFlags.mbHeightUsed )
+    {
+        // leave in twips ?
+        SvxFontHeightItem aHeightItem( maApiData.maDesc.Height, 100, ATTR_FONT_HEIGHT );
+        ScfTools::PutItem( rItemSet, aHeightItem, ATTR_FONT_HEIGHT, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aHeightItem, ATTR_CJK_FONT_HEIGHT, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aHeightItem, ATTR_CTL_FONT_HEIGHT, bSkipPoolDefs );
+    }
+    // font weight
+    if( maUsedFlags.mbWeightUsed )
+    {
+        ::FontWeight fWeight = VCLUnoHelper::ConvertFontWeight( maApiData.maDesc.Weight );
+        SvxWeightItem aWeightItem( fWeight, ATTR_FONT_WEIGHT );
+        ScfTools::PutItem( rItemSet, aWeightItem, ATTR_FONT_WEIGHT, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aWeightItem, ATTR_CTL_FONT_WEIGHT, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aWeightItem, ATTR_CJK_FONT_WEIGHT, bSkipPoolDefs );
+    }
+    // font posture
+    if( maUsedFlags.mbPostureUsed )
+    {
+        SvxPostureItem aPostItem( ( maApiData.maDesc.Slant == cssawt::FontSlant_ITALIC ) ? ITALIC_NORMAL :  ITALIC_NONE,  ATTR_FONT_POSTURE);
+        ScfTools::PutItem( rItemSet, aPostItem, ATTR_FONT_POSTURE, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aPostItem, ATTR_CJK_FONT_POSTURE, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aPostItem, ATTR_CTL_FONT_POSTURE, bSkipPoolDefs );
+    }
+    // character color
+    if( maUsedFlags.mbColorUsed )
+    {
+        ScfTools::PutItem( rItemSet,SvxColorItem( maApiData.mnColor, ATTR_FONT_COLOR  ) , bSkipPoolDefs );
+    }
+    // underline style
+    if( maUsedFlags.mbUnderlineUsed )
+    {
+        ::FontUnderline eScUnderl;
+        if ( maApiData.maDesc.Underline == cssawt::FontUnderline::DOUBLE )
+            eScUnderl = UNDERLINE_DOUBLE;
+        else if ( maApiData.maDesc.Underline == cssawt::FontUnderline::SINGLE )
+            eScUnderl = UNDERLINE_SINGLE;
+        else
+            eScUnderl = UNDERLINE_NONE;
+        SvxUnderlineItem aUnderlItem( eScUnderl, ATTR_FONT_UNDERLINE );
+        ScfTools::PutItem( rItemSet, aUnderlItem, ATTR_FONT_UNDERLINE, bSkipPoolDefs );
+    }
+    // strike out style
+    if( maUsedFlags.mbStrikeoutUsed )
+    {
+        ScfTools::PutItem( rItemSet, SvxCrossedOutItem( maModel.mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, ATTR_FONT_CROSSEDOUT ), ATTR_FONT_CROSSEDOUT, bSkipPoolDefs );
+    }
+
+    // outline style
+    if( maUsedFlags.mbOutlineUsed )
+    {
+        ScfTools::PutItem( rItemSet, SvxContourItem( maApiData.mbOutline, ATTR_FONT_CONTOUR ), ATTR_FONT_CONTOUR, bSkipPoolDefs );
+    }
+
+    // shadow style
+    if( maUsedFlags.mbShadowUsed )
+    {
+        ScfTools::PutItem( rItemSet, SvxShadowedItem( maApiData.mbShadow, ATTR_FONT_SHADOWED ), ATTR_FONT_SHADOWED, bSkipPoolDefs );
+    }
+    if( maUsedFlags.mbEscapementUsed )
+    {
+        SvxEscapement eScEscapem = SVX_ESCAPEMENT_OFF;
+        if ( maApiData.mnEscapement == API_ESCAPE_SUPERSCRIPT )
+            eScEscapem = SVX_ESCAPEMENT_SUPERSCRIPT;
+        else if ( maApiData.mnEscapement == API_ESCAPE_SUBSCRIPT )
+            eScEscapem = SVX_ESCAPEMENT_SUBSCRIPT;
+        rItemSet.Put( SvxEscapementItem( eScEscapem, EE_CHAR_ESCAPEMENT ) );
+        if( ePropType == FONT_PROPTYPE_TEXT )
+        {
+           // #TODO handle EscapementHeight
+        }
+    }
+}
 
 void Font::writeToPropertyMap( PropertyMap& rPropMap, FontPropertyType ePropType ) const
 {
@@ -1428,6 +1582,105 @@ void Alignment::finalizeImport()
 
 }
 
+::SvxCellVerJustify Alignment::GetScVerAlign() const
+{
+    namespace csstab = ::com::sun::star::table;
+    ::SvxCellVerJustify nVert = ::SVX_VER_JUSTIFY_STANDARD;
+    switch ( maApiData.mnVerJustify )
+    {
+        case csstab::CellVertJustify2::BOTTOM:
+            nVert = ::SVX_VER_JUSTIFY_BOTTOM;
+            break;
+        case csstab::CellVertJustify2::CENTER:
+            nVert = ::SVX_VER_JUSTIFY_CENTER;
+            break;
+        case csstab::CellVertJustify2::TOP:
+            nVert = ::SVX_VER_JUSTIFY_TOP;
+            break;
+        case csstab::CellVertJustify2::BLOCK:
+            nVert = ::SVX_VER_JUSTIFY_BLOCK;
+            break;
+        case csstab::CellVertJustify2::STANDARD:
+        default:
+            nVert = ::SVX_VER_JUSTIFY_STANDARD;
+            break;
+    }
+    return nVert;
+}
+
+::SvxCellHorJustify Alignment::GetScHorAlign() const
+{
+    namespace csstab = ::com::sun::star::table;
+    ::SvxCellHorJustify nHori = ::SVX_HOR_JUSTIFY_STANDARD;
+    switch( maApiData.meHorJustify )
+    {
+        case csstab::CellHoriJustify_LEFT:
+            nHori = ::SVX_HOR_JUSTIFY_LEFT;
+            break;
+        case csstab::CellHoriJustify_CENTER:
+            nHori = ::SVX_HOR_JUSTIFY_CENTER;
+            break;
+        case csstab::CellHoriJustify_RIGHT:
+            nHori = ::SVX_HOR_JUSTIFY_RIGHT;
+            break;
+        case csstab::CellHoriJustify_BLOCK:
+            nHori = ::SVX_HOR_JUSTIFY_BLOCK;
+            break;
+        case csstab::CellHoriJustify_REPEAT:
+            nHori = ::SVX_HOR_JUSTIFY_REPEAT;
+            break;
+        case csstab::CellHoriJustify_STANDARD:
+        default:
+            nHori = ::SVX_HOR_JUSTIFY_STANDARD;
+            break;
+    }
+    return nHori;
+}
+
+::SvxFrameDirection Alignment::GetScFrameDir() const
+{
+    namespace csstxt = ::com::sun::star::text;
+    ::SvxFrameDirection eFrameDir = ::FRMDIR_ENVIRONMENT;
+    switch( maApiData.mnWritingMode )
+    {
+        case csstxt::WritingMode2::PAGE:
+            eFrameDir = ::FRMDIR_ENVIRONMENT;
+            break;
+        case csstxt::WritingMode2::LR_TB:
+            eFrameDir = ::FRMDIR_HORI_LEFT_TOP;
+            break;
+        case csstxt::WritingMode2::RL_TB:
+            eFrameDir = ::FRMDIR_HORI_RIGHT_TOP;
+            break;
+        default:
+            OSL_FAIL( "GetScFrameDir - unknown CTL text direction" );
+    }
+    return eFrameDir;
+}
+
+void Alignment::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+    namespace csstab = ::com::sun::star::table;
+    // horizontal alignment
+    ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
+    ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnHorJustifyMethod == csstab::CellJustifyMethod::DISTRIBUTE ) ? ::SVX_JUSTIFY_METHOD_DISTRIBUTE : ::SVX_JUSTIFY_METHOD_AUTO, ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
+    ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
+    // vertical alignment
+    ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnVerJustifyMethod == csstab::CellJustifyMethod::DISTRIBUTE ) ? ::SVX_JUSTIFY_METHOD_DISTRIBUTE : ::SVX_JUSTIFY_METHOD_AUTO, ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
+
+    // CTL text direction
+    ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
+    // set an angle in the range from -90 to 90 degrees
+    ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, maApiData.mnRotation ), bSkipPoolDefs );
+    // Orientation
+    ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, maApiData.meOrientation == csstab::CellOrientation_STACKED ), bSkipPoolDefs );
+    // indent
+    ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, maApiData.mnIndent ), bSkipPoolDefs );
+    // line wrap
+    ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, maApiData.mbWrapText ), bSkipPoolDefs );
+    ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, maApiData.mbShrink ), bSkipPoolDefs );
+}
+
 void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const
 {
     rPropMap[ PROP_HoriJustify ]     <<= maApiData.meHorJustify;
@@ -1508,6 +1761,11 @@ void Protection::writeToPropertyMap( PropertyMap& rPropMap ) const
     rPropMap[ PROP_CellProtection ] <<= maApiData.maCellProt;
 }
 
+void Protection::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+    ScfTools::PutItem( rItemSet, ScProtectionAttr( maApiData.maCellProt.IsLocked, maApiData.maCellProt.IsFormulaHidden ), bSkipPoolDefs );
+}
+
 // ============================================================================
 
 namespace {
@@ -1748,6 +2006,49 @@ void Border::finalizeImport()
         convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal );
 }
 
+void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+    if( maApiData.mbBorderUsed )
+    {
+         SvxBoxItem aBoxItem( ATTR_BORDER );
+         ::editeng::SvxBorderLine aLine;
+
+         if ( SvxBoxItem::LineToSvxLine(maApiData.maLeft, aLine, true ) )
+         {
+             aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
+         }
+         if ( SvxBoxItem::LineToSvxLine(maApiData.maRight, aLine, true ) )
+         {
+             aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
+         }
+         if ( SvxBoxItem::LineToSvxLine(maApiData.maTop, aLine, true ) )
+         {
+             aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
+         }
+         if ( SvxBoxItem::LineToSvxLine(maApiData.maBottom, aLine, true ) )
+         {
+             aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
+         }
+         ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
+    }
+    if ( maApiData.mbDiagUsed )
+    {
+        SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
+        SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
+        ::editeng::SvxBorderLine aLine;
+        if ( SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, true ) )
+        {
+            aTLBRItem.SetLine( &aLine );
+        }
+        if ( SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, true ) )
+        {
+            aBLTRItem.SetLine( &aLine );
+        }
+        ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
+        ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
+    }
+}
+
 void Border::writeToPropertyMap( PropertyMap& rPropMap ) const
 {
     if( maApiData.mbBorderUsed )
@@ -2194,6 +2495,23 @@ void Fill::finalizeImport()
     }
 }
 
+void Fill::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+    if( maApiData.mbUsed )
+    {
+        SvxBrushItem aBrushItem( ATTR_BACKGROUND );
+        if ( maApiData.mbTransparent )
+        {
+            aBrushItem.SetColor( ::Color( COL_TRANSPARENT ) );
+        }
+        else
+        {
+            aBrushItem.SetColor( maApiData.mnColor  );
+        }
+        ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
+    }
+}
+
 void Fill::writeToPropertyMap( PropertyMap& rPropMap ) const
 {
     if( maApiData.mbUsed )
@@ -2227,7 +2545,8 @@ Xf::Xf( const WorkbookHelper& rHelper ) :
     WorkbookHelper( rHelper ),
     maAlignment( rHelper ),
     maProtection( rHelper ),
-    meRotationRef( ::com::sun::star::table::CellVertJustify2::STANDARD )
+    meRotationRef( ::com::sun::star::table::CellVertJustify2::STANDARD ),
+    mpStyleSheet( NULL )
 {
 }
 
@@ -2410,46 +2729,10 @@ void Xf::importXf( BiffInputStream& rStrm )
 
 void Xf::finalizeImport()
 {
-    StylesBuffer& rStyles = getStyles();
-
     // alignment and protection
     maAlignment.finalizeImport();
     maProtection.finalizeImport();
-
-    /*  Enables the used flags, if the formatting attributes differ from the
-        style XF. In cell XFs Excel uses the cell attributes, if they differ
-        from the parent style XF (even if the used flag is switched off).
-        #109899# ...or if the respective flag is not set in parent style XF.
-     */
-    const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0;
-    if( pStyleXf )
-    {
-        const XfModel& rStyleData = pStyleXf->maModel;
-        if( !maModel.mbFontUsed )
-            maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
-        if( !maModel.mbNumFmtUsed )
-            maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
-        if( !maModel.mbAlignUsed )
-            maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
-        if( !maModel.mbProtUsed )
-            maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
-        if( !maModel.mbBorderUsed )
-            maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
-        if( !maModel.mbAreaUsed )
-            maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId );
-    }
-
-    /*  #i38709# Decide which rotation reference mode to use. If any outer
-        border line of the cell is set (either explicitly or via cell style),
-        and the cell contents are rotated, set rotation reference to bottom of
-        cell. This causes the borders to be painted rotated with the text. */
-    if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) )
-    {
-        sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
-        if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
-            if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
-                meRotationRef = ::com::sun::star::table::CellVertJustify2::BOTTOM;
-    }
+    createPattern();
 }
 
 FontRef Xf::getFont() const
@@ -2457,6 +2740,41 @@ FontRef Xf::getFont() const
     return getStyles().getFont( maModel.mnFontId );
 }
 
+void Xf::writeToMarkData( ::ScMarkData& rMarkData, sal_Int32 nNumFmtId  )
+{
+    createPattern();
+    ScPatternAttr& rPat = *mpPattern;
+    ScDocument& rDoc = getScDocument();
+    if ( isCellXf() )
+    {
+        if ( mpStyleSheet )
+        {
+            // Apply style sheet.  Don't clear the direct formats.
+            rPat.SetStyleSheet(mpStyleSheet, false);
+        }
+        else
+        {
+            ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
+            if (pStylePool)
+            {
+                ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(
+                    pStylePool->Find(
+                        ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA));
+
+                if (pStyleSheet)
+                    rPat.SetStyleSheet(pStyleSheet, false);
+            }
+        }
+    }
+    if ( nNumFmtId >= 0 )
+    {
+        ScPatternAttr aNumPat(rDoc.GetPool());
+        getStyles().writeNumFmtToItemSet( aNumPat.GetItemSet(), nNumFmtId );
+        rPat.GetItemSet().Put(aNumPat.GetItemSet());
+    }
+    rDoc.ApplySelectionPattern( rPat, rMarkData );
+}
+
 void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const
 {
     StylesBuffer& rStyles = getStyles();
@@ -2545,6 +2863,95 @@ void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags )
     maModel.mbAreaUsed   = isCellXf() == getFlag( nUsedFlags, BIFF_XF_AREA_USED );
 }
 
+const ::ScPatternAttr&
+Xf::createPattern( bool bSkipPoolDefs )
+{
+    if( mpPattern.get() )
+        return *mpPattern;
+    // create new pattern attribute set
+    mpPattern.reset( new ::ScPatternAttr( getScDocument().GetPool() ) );
+    SfxItemSet& rItemSet = mpPattern->GetItemSet();
+    /*  Enables the used flags, if the formatting attributes differ from the
+        style XF. In cell XFs Excel uses the cell attributes, if they differ
+        from the parent style XF (even if the used flag is switched off).
+        #109899# ...or if the respective flag is not set in parent style XF.
+     */
+    StylesBuffer& rStyles = getStyles();
+
+    const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0;
+    if( pStyleXf )
+    {
+        const XfModel& rStyleData = pStyleXf->maModel;
+        if( !maModel.mbFontUsed )
+            maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
+        if( !maModel.mbNumFmtUsed )
+            maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
+        if( !maModel.mbAlignUsed )
+            maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
+        if( !maModel.mbProtUsed )
+            maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
+        if( !maModel.mbBorderUsed )
+            maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
+        if( !maModel.mbAreaUsed )
+            maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId );
+    }
+    // cell protection
+    if( maModel.mbProtUsed )
+    {
+        maProtection.fillToItemSet( rItemSet, bSkipPoolDefs );
+    }
+
+    // font
+    if( maModel.mbFontUsed )
+    {
+        rStyles.writeFontToItemSet( rItemSet, maModel.mnFontId, bSkipPoolDefs );
+    }
+
+    // value format
+    if( maModel.mbNumFmtUsed )
+    {
+        rStyles.writeNumFmtToItemSet( rItemSet, maModel.mnNumFmtId, bSkipPoolDefs );
+    }
+    // alignment
+    if( maModel.mbAlignUsed )
+    {
+        maAlignment.fillToItemSet( rItemSet, bSkipPoolDefs );
+    }
+
+    // border
+    if( maModel.mbBorderUsed )
+    {
+        rStyles.writeBorderToItemSet( rItemSet, maModel.mnBorderId, bSkipPoolDefs );
+    }
+
+    // area
+    if( maModel.mbAreaUsed )
+    {
+        rStyles.writeFillToItemSet( rItemSet, maModel.mnFillId, bSkipPoolDefs );
+    }
+
+    /*  #i38709# Decide which rotation reference mode to use. If any outer
+        border line of the cell is set (either explicitly or via cell style),
+        and the cell contents are rotated, set rotation reference to bottom of
+        cell. This causes the borders to be painted rotated with the text. */
+    if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) )
+    {
+        SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
+        sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
+        if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
+        {
+            if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
+            {
+                meRotationRef = ::com::sun::star::table::CellVertJustify2::BOTTOM;
+                eRotateMode = SVX_ROTATE_MODE_BOTTOM;
+            }
+        }
+        ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
+    }
+
+    return *mpPattern;
+}
+
 // ============================================================================
 
 Dxf::Dxf( const WorkbookHelper& rHelper ) :
@@ -2798,7 +3205,8 @@ bool CellStyleModel::isDefaultStyle() const
 
 CellStyle::CellStyle( const WorkbookHelper& rHelper ) :
     WorkbookHelper( rHelper ),
-    mbCreated( false )
+    mbCreated( false ),
+    mpStyleSheet( NULL )
 {
 }
 
@@ -2860,10 +3268,41 @@ void CellStyle::importStyle( BiffInputStream& rStrm )
 
 void CellStyle::createCellStyle()
 {
+
     // #i1624# #i1768# ignore unnamed user styles
     if( !mbCreated )
         mbCreated = maFinalName.isEmpty();
+#if AVOID_UNO
+    ::ScDocument& rDoc = getScDocument();
+    if( !mbCreated && !mpStyleSheet )
+    {
+        bool bCreatePattern = false;
+        Xf* pXF = getStyles().getStyleXf( maModel.mnXfId ).get();
 
+        bool bDefStyle = maModel.isDefaultStyle();
+        if( bDefStyle )
+        {
+            // use existing "Default" style sheet
+            mpStyleSheet = static_cast< ScStyleSheet* >( static_cast< ScStyleSheetPool* >( rDoc.GetStyleSheetPool() )->Find(
+                getStyles().getDefaultStyleName(), SFX_STYLE_FAMILY_PARA ) );
+            OSL_ENSURE( mpStyleSheet, "CellStyle::createStyle - Default style not found" );
+            bCreatePattern = true;
+        }
+        else
+        {
+            mpStyleSheet = static_cast< ScStyleSheet* >( static_cast< ScStyleSheetPool* >( rDoc.GetStyleSheetPool() )->Find( maFinalName, SFX_STYLE_FAMILY_PARA ) );
+            if( !mpStyleSheet )
+            {
+                mpStyleSheet = &static_cast< ScStyleSheet& >( rDoc.GetStyleSheetPool()->Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) );
+                bCreatePattern = true;
+            }
+        }
+
+        // bDefStyle==true omits default pool items in CreatePattern()
+        if( bCreatePattern && mpStyleSheet && pXF )
+            mpStyleSheet->GetItemSet().Put( pXF->createPattern( bDefStyle ).GetItemSet() );
+    }
+#else
     /*  #i103281# do not create another style of the same name, if it exists
         already. This is needed to prevent that styles pasted from clipboard
         get duplicated over and over. */
@@ -2890,6 +3329,15 @@ void CellStyle::createCellStyle()
     catch( Exception& )
     {
     }
+#endif
+}
+
+ScStyleSheet*
+CellStyle::createStyleSheet()
+{
+    if ( !mpStyleSheet )
+        createCellStyle();
+    return mpStyleSheet;
 }
 
 void CellStyle::finalizeImport( const OUString& rFinalName )
@@ -3383,29 +3831,58 @@ OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
     return rStyleName;
 }
 
+void StylesBuffer::writeFontToItemSet( SfxItemSet& rItemSet, sal_Int32 nFontId, bool bSkipPoolDefs ) const
+{
+    if( Font* pFont = maFonts.get( nFontId ).get() )
+        pFont->fillToItemSet( rItemSet, FONT_PROPTYPE_CELL, bSkipPoolDefs );
+}
+
 void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const
 {
     if( Font* pFont = maFonts.get( nFontId ).get() )
         pFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL );
 }
 
+void StylesBuffer::writeNumFmtToItemSet( SfxItemSet& rItemSet, sal_Int32 nNumFmtId, bool bSkipPoolDefs ) const
+{
+    maNumFmts.fillToItemSet( rItemSet, nNumFmtId, bSkipPoolDefs );
+}
+
 void StylesBuffer::writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const
 {
     maNumFmts.writeToPropertyMap( rPropMap, nNumFmtId );
 }
 
+void StylesBuffer::writeBorderToItemSet( SfxItemSet& rItemSet, sal_Int32 nBorderId, bool bSkipPoolDefs ) const
+{
+    if( Border* pBorder = maBorders.get( nBorderId ).get() )
+        pBorder->fillToItemSet( rItemSet, bSkipPoolDefs );
+}
+
 void StylesBuffer::writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const
 {
     if( Border* pBorder = maBorders.get( nBorderId ).get() )
         pBorder->writeToPropertyMap( rPropMap );
 }
 
+void StylesBuffer::writeFillToItemSet( SfxItemSet& rItemSet, sal_Int32 nFillId, bool bSkipPoolDefs ) const
+{
+    if( Fill* pFill = maFills.get( nFillId ).get() )
+        pFill->fillToItemSet( rItemSet, bSkipPoolDefs );
+}
+
 void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const
 {
     if( Fill* pFill = maFills.get( nFillId ).get() )
         pFill->writeToPropertyMap( rPropMap );
 }
 
+void StylesBuffer::writeCellXfToMarkData( ScMarkData& rMark,  sal_Int32 nXfId, sal_Int32 nNumFmtId  )
+{
+    if( Xf* pXf = maCellXfs.get( nXfId ).get() )
+        pXf->writeToMarkData( rMark, nNumFmtId );
+}
+
 bool operator==( const XfModel& rXfModel1,  const XfModel& rXfModel2 )
 {
     return ( rXfModel1.mbCellXf == rXfModel2.mbCellXf &&
commit 3043cc87ad5570eaea404f220e42547b5efa7713
Author: Noel Power <noel.power at novell.com>
Date:   Wed Mar 28 22:47:22 2012 +0100

    some performance improvements
    
    a) directly access core for creating named ranges ( the import code still uses uno for accessing the named ranges )
    b) combine ranges with equal formats so that format can be applied to a multirange ( to avoid multiple uno calls )

diff --git a/sc/inc/tokenuno.hxx b/sc/inc/tokenuno.hxx
index 8f68d07..36486c4 100644
--- a/sc/inc/tokenuno.hxx
+++ b/sc/inc/tokenuno.hxx
@@ -49,7 +49,7 @@ class ScDocShell;
 class ScTokenConversion
 {
 public:
-    static bool ConvertToTokenArray(
+    static SC_DLLPUBLIC bool ConvertToTokenArray(
                         ScDocument& rDoc,
                         ScTokenArray& rTokenArray,
                         const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence );
diff --git a/sc/source/filter/inc/defnamesbuffer.hxx b/sc/source/filter/inc/defnamesbuffer.hxx
index 0d28b6a..5ef1a40 100644
--- a/sc/source/filter/inc/defnamesbuffer.hxx
+++ b/sc/source/filter/inc/defnamesbuffer.hxx
@@ -128,10 +128,10 @@ public:
     void                importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet );
 
     /** Creates a defined name in the Calc document. */
-    void                createNameObject();
+    void                createNameObject( sal_Int32 nIndex );
     /** Converts the formula string or BIFF token array for this defined name. */
     void                convertFormula();
-
+    ApiTokenSequence    getTokens();
     /** Returns true, if this defined name is global in the document. */
     inline bool         isGlobalName() const { return mnCalcSheet < 0; }
     /** Returns true, if this defined name is a special builtin name. */
diff --git a/sc/source/filter/inc/sheetdatabuffer.hxx b/sc/source/filter/inc/sheetdatabuffer.hxx
index 3e83420..743c6c0 100644
--- a/sc/source/filter/inc/sheetdatabuffer.hxx
+++ b/sc/source/filter/inc/sheetdatabuffer.hxx
@@ -323,6 +323,7 @@ private:
     MergedRangeList     maMergedRanges;         /// Merged cell ranges.
     MergedRangeList     maCenterFillRanges;     /// Merged cell ranges from 'center across' or 'fill' alignment.
     bool                mbPendingSharedFmla;    /// True = maSharedFmlaAddr and maSharedBaseAddr are valid.
+    std::map< sal_Int32, std::vector< ValueRange > > maXfIdRowRangeList; /// Cached XF identifiers for a ranges of rows, we try and process rowranges with the same XF id together
 };
 
 // ============================================================================
diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx
index 59895e5..af5d6ff 100644
--- a/sc/source/filter/inc/stylesbuffer.hxx
+++ b/sc/source/filter/inc/stylesbuffer.hxx
@@ -744,6 +744,8 @@ struct XfModel
     explicit            XfModel();
 };
 
+bool operator==( const XfModel& rXfModel1,  const XfModel& rXfModel2 );
+
 // ============================================================================
 
 /** Represents a cell format or a cell style (called XF, extended format).
@@ -755,6 +757,7 @@ struct XfModel
  */
 class Xf : public WorkbookHelper
 {
+    friend bool operator==( const Xf& rXf1,  const Xf& rXf2 );
 public:
     explicit            Xf( const WorkbookHelper& rHelper );
 
@@ -796,7 +799,6 @@ public:
     static void         writeBiff2CellFormatToPropertySet(
                             const WorkbookHelper& rHelper, PropertySet& rPropSet,
                             sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 );
-
 private:
     /** Sets 'attribute used' flags from the passed BIFF bit field. */
     void                setBiffUsedFlags( sal_uInt8 nUsedFlags );
@@ -808,6 +810,8 @@ private:
     sal_Int32           meRotationRef;      /// Rotation reference dependent on border.
 };
 
+bool operator==( const Xf& rXf1,  const Xf& rXf2 );
+
 typedef ::boost::shared_ptr< Xf > XfRef;
 
 // ============================================================================
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index 89b180e..1bdd96d 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -42,6 +42,7 @@ namespace com { namespace sun { namespace star {
     namespace sheet { class XNamedRange; }
     namespace sheet { class XSpreadsheet; }
     namespace sheet { class XSpreadsheetDocument; }
+    namespace sheet { struct FormulaToken; }
     namespace style { class XStyle; }
     namespace table { struct CellAddress; }
     namespace table { struct CellRangeAddress; }
@@ -66,6 +67,8 @@ namespace oox { namespace drawingml {
     class Theme;
 } }
 
+class ScDocument;
+
 namespace oox {
 namespace xls {
 
@@ -154,7 +157,7 @@ public:
     void                finalizeWorkbookImport();
 
     // document model ---------------------------------------------------------
-
+    ScDocument& getScDocument() const;
     /** Returns a reference to the source/target spreadsheet document model. */
     ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
                         getDocument() const;
@@ -184,6 +187,8 @@ public:
     ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange >
                         createNamedRangeObject(
                             ::rtl::OUString& orName,
+                            const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken>& rTokens,
+                            sal_Int32 nIndex,
                             sal_Int32 nNameFlags = 0 ) const;
 
     /** Creates and returns a defined name on-the-fly in the sheet.
@@ -192,6 +197,8 @@ public:
     ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange >
                         createLocalNamedRangeObject(
                             ::rtl::OUString& orName,
+                            const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken>& rTokens,
+                            sal_Int32 nIndex,
                             sal_Int32 nNameFlags = 0, sal_Int32 nTab = -1 ) const;
 
     /** Creates and returns a database range on-the-fly in the Calc document.
diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx
index ab0ed19..e823e73 100644
--- a/sc/source/filter/oox/defnamesbuffer.cxx
+++ b/sc/source/filter/oox/defnamesbuffer.cxx
@@ -474,7 +474,7 @@ void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcShee
     }
 }
 
-void DefinedName::createNameObject()
+void DefinedName::createNameObject( sal_Int32 nIndex )
 {
     // do not create names for (macro) functions or VBA procedures
     // #163146# do not ignore hidden names (may be regular names created by VBA scripts)
@@ -502,20 +502,15 @@ void DefinedName::createNameObject()
 
     // create the name and insert it into the document, maCalcName will be changed to the resulting name
     if (maModel.mnSheet >= 0)
-        mxNamedRange = createLocalNamedRangeObject( maCalcName, nNameFlags, maModel.mnSheet );
+        mxNamedRange = createLocalNamedRangeObject( maCalcName, getTokens(), nIndex, nNameFlags, maModel.mnSheet );
     else
-        mxNamedRange = createNamedRangeObject( maCalcName, nNameFlags );
-    // index of this defined name used in formula token arrays
-    PropertySet aPropSet( mxNamedRange );
-    aPropSet.getProperty( mnTokenIndex, PROP_TokenIndex );
+        mxNamedRange = createNamedRangeObject( maCalcName, getTokens(), nIndex, nNameFlags );
+    mnTokenIndex = nIndex;
 }
 
-void DefinedName::convertFormula()
+ApiTokenSequence
+DefinedName::getTokens()
 {
-    Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
-    if( !xTokens.is() )
-        return;
-
     // convert and set formula of the defined name
     ApiTokenSequence aTokens;
     switch( getFilterType() )
@@ -546,8 +541,14 @@ void DefinedName::convertFormula()
         case FILTER_UNKNOWN:
         break;
     }
-    xTokens->setTokens( aTokens );
+    return aTokens;
+}
 
+void DefinedName::convertFormula()
+{
+    Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
+    if( !xTokens.is() )
+        return;
     // set built-in names (print ranges, repeated titles, filter ranges)
     if( !isGlobalName() ) switch( mcBuiltinId )
     {
@@ -636,10 +637,11 @@ void DefinedNamesBuffer::importDefinedName( BiffInputStream& rStrm )
 void DefinedNamesBuffer::finalizeImport()
 {
     // first insert all names without formula definition into the document, and insert them into the maps
+    int index = 0;
     for( DefNameVector::iterator aIt = maDefNames.begin(), aEnd = maDefNames.end(); aIt != aEnd; ++aIt )
     {
         DefinedNameRef xDefName = *aIt;
-        xDefName->createNameObject();
+        xDefName->createNameObject( ++index );
         // map by sheet index and original model name
         maModelNameMap[ SheetNameKey( xDefName->getLocalCalcSheet(), xDefName->getUpcaseModelName() ) ] = xDefName;
         // map by sheet index and built-in identifier
diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx
index 3b15243..4904a0c 100644
--- a/sc/source/filter/oox/sheetdatabuffer.cxx
+++ b/sc/source/filter/oox/sheetdatabuffer.cxx
@@ -396,14 +396,15 @@ void SheetDataBuffer::setRowFormat( sal_Int32 nRow, sal_Int32 nXfId, bool bCusto
         // try to expand cached row range, if formatting is equal
         if( (maXfIdRowRange.maRowRange.mnLast < 0) || !maXfIdRowRange.tryExpand( nRow, nXfId ) )
         {
-            writeXfIdRowRangeProperties( maXfIdRowRange );
+
+            maXfIdRowRangeList[ maXfIdRowRange.mnXfId ].push_back( maXfIdRowRange.maRowRange );
             maXfIdRowRange.set( nRow, nXfId );
         }
     }
     else if( maXfIdRowRange.maRowRange.mnLast >= 0 )
     {
         // finish last cached row range
-        writeXfIdRowRangeProperties( maXfIdRowRange );
+        maXfIdRowRangeList[ maXfIdRowRange.mnXfId ].push_back( maXfIdRowRange.maRowRange );
         maXfIdRowRange.set( -1, -1 );
     }
 }
@@ -428,6 +429,30 @@ void SheetDataBuffer::setStandardNumFmt( const CellAddress& rCellAddr, sal_Int16
     }
 }
 
+void addIfNotInMyMap( StylesBuffer& rStyles, std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList >& rMap, sal_Int32 nXfId, sal_Int32 nFormatId, const ApiCellRangeList& rRangeList )
+{
+    Xf* pXf1 = rStyles.getCellXf( nXfId ).get();
+    if ( pXf1 )
+    {
+        for ( std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList >::iterator it = rMap.begin(), it_end = rMap.end(); it != it_end; ++it )
+        {
+            if ( it->first.second == nFormatId )
+            {
+                Xf* pXf2 = rStyles.getCellXf( it->first.first ).get();
+                if ( *pXf1 == *pXf2 ) // already exists
+                {
+                    // add ranges from the rangelist to the existing rangelist for the
+                    // matching style ( should we check if they overlap ? )
+                    for ( ApiCellRangeList::const_iterator iter = rRangeList.begin(), iter_end =  rRangeList.end(); iter != iter_end; ++iter )
+                       it->second.push_back( *iter );
+                    return;
+                }
+            }
+        }
+        rMap[ std::pair<sal_Int32, sal_Int32>( nXfId, nFormatId ) ] = rRangeList;
+    }
+}
+
 void SheetDataBuffer::finalizeImport()
 {
     // insert all cells of all open cell blocks
@@ -442,11 +467,26 @@ void SheetDataBuffer::finalizeImport()
         finalizeTableOperation( aIt->first, aIt->second );
 
     // write default formatting of remaining row range
-    writeXfIdRowRangeProperties( maXfIdRowRange );
-
+    maXfIdRowRangeList[ maXfIdRowRange.mnXfId ].push_back( maXfIdRowRange.maRowRange );
+    for ( std::map< sal_Int32, std::vector< ValueRange > >::iterator it = maXfIdRowRangeList.begin(), it_end =  maXfIdRowRangeList.end(); it != it_end; ++it )
+    {
+        ApiCellRangeList rangeList;
+        AddressConverter& rAddrConv = getAddressConverter();
+        // get all row ranges for id
+        for ( std::vector< ValueRange >::iterator rangeIter = it->second.begin(), rangeIter_end = it->second.end(); rangeIter != rangeIter_end; ++rangeIter )
+        {
+            CellRangeAddress aRange( getSheetIndex(), 0, rangeIter->mnFirst, rAddrConv.getMaxApiAddress().Column, rangeIter->mnLast );
+            rangeList.push_back( aRange );
+        }
+        PropertySet aPropSet( getCellRangeList( rangeList ) );
+        getStyles().writeCellXfToPropertySet( aPropSet, it->first );
+    }
+    std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList > rangeStyleListMap;
+    // gather all ranges that have the same style and apply them in bulk
     for( XfIdRangeListMap::const_iterator aIt = maXfIdRangeLists.begin(), aEnd = maXfIdRangeLists.end(); aIt != aEnd; ++aIt )
-        writeXfIdRangeListProperties( aIt->first.first, aIt->first.second, aIt->second );
-
+        addIfNotInMyMap( getStyles(), rangeStyleListMap, aIt->first.first, aIt->first.second, aIt->second );
+    for (  std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList >::iterator it = rangeStyleListMap.begin(), it_end = rangeStyleListMap.end(); it != it_end; ++it )
+        writeXfIdRangeListProperties( it->first.first, it->first.second, it->second );
     // merge all cached merged ranges and update right/bottom cell borders
     for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt )
         finalizeMergedRange( aIt->maRange );
@@ -530,7 +570,7 @@ void SheetDataBuffer::createSharedFormula( const BinAddress& rMapKey, const ApiT
         append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ).
         append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ).
         append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear();
-    Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName );
+    Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName, rTokens, 0 );
     OSL_ENSURE( xNamedRange.is(), "SheetDataBuffer::createSharedFormula - cannot create shared formula" );
     PropertySet aNameProps( xNamedRange );
     aNameProps.setProperty( PROP_IsSharedFormula, true );
@@ -542,9 +582,6 @@ void SheetDataBuffer::createSharedFormula( const BinAddress& rMapKey, const ApiT
     {
         // store the token index in the map
         maSharedFormulas[ rMapKey ] = nTokenIndex;
-        // set the formula definition
-        Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW );
-        xTokens->setTokens( rTokens );
         // retry to insert a pending shared formula cell
         if( mbPendingSharedFmla )
             setCellFormula( maSharedFmlaAddr, resolveSharedFormula( maSharedBaseAddr ) );
@@ -737,8 +774,8 @@ void SheetDataBuffer::finalizeMergedRange( const CellRangeAddress& rRange )
     {
         // merge the cell range
         Reference< XMergeable > xMerge( getCellRange( rRange ), UNO_QUERY_THROW );
-        xMerge->merge( sal_True );
 
+        xMerge->merge( sal_True );
         // if merging this range worked (no overlapping merged ranges), update cell borders
         Reference< XCell > xTopLeft( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW );
         PropertySet aTopLeftProp( xTopLeft );
diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx
index 21bb1e1..4d2b618 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -3406,6 +3406,41 @@ void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFil
         pFill->writeToPropertyMap( rPropMap );
 }
 
+bool operator==( const XfModel& rXfModel1,  const XfModel& rXfModel2 )
+{
+    return ( rXfModel1.mbCellXf == rXfModel2.mbCellXf &&
+        rXfModel1.mnStyleXfId == rXfModel2.mnStyleXfId &&
+        rXfModel1.mbFontUsed == rXfModel2.mbFontUsed &&
+        rXfModel1.mnFontId == rXfModel2.mnFontId &&
+        rXfModel1.mbNumFmtUsed == rXfModel2.mbNumFmtUsed &&
+        rXfModel1.mnNumFmtId == rXfModel2.mnNumFmtId &&
+        rXfModel1.mbAlignUsed == rXfModel2.mbAlignUsed &&
+        rXfModel1.mbBorderUsed == rXfModel2.mbBorderUsed &&
+        rXfModel1.mnBorderId == rXfModel2.mnBorderId &&
+        rXfModel1.mbAreaUsed == rXfModel2.mbAreaUsed &&
+        rXfModel1.mnFillId == rXfModel2.mnFillId &&
+        rXfModel1.mbProtUsed == rXfModel2.mbProtUsed );
+}
+
+bool operator==( const Xf& rXf1, const Xf& rXf2 )
+{
+    if ( rXf1.maModel == rXf2.maModel )
+    {
+        if ( rXf1.maModel.mbAlignUsed )
+        {
+            if ( !( rXf1.maAlignment.getApiData() == rXf2.maAlignment.getApiData() ) )
+                return false;
+        }
+        if ( rXf1.maModel.mbProtUsed )
+        {
+            if ( !( rXf1.maProtection.getApiData() == rXf2.maProtection.getApiData() ) )
+                return false;
+        }
+        return true;
+    }
+    return false;
+}
+
 void StylesBuffer::writeCellXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const
 {
     if( Xf* pXf = maCellXfs.get( nXfId ).get() )
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 9760b45..c3c5134 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -38,6 +38,7 @@
 #include <com/sun/star/sheet/XNamedRanges.hpp>
 #include <com/sun/star/sheet/XSpreadsheet.hpp>
 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
 #include <com/sun/star/style/XStyle.hpp>
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
@@ -68,6 +69,13 @@
 #include "viewsettings.hxx"
 #include "workbooksettings.hxx"
 #include "worksheetbuffer.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "rangenam.hxx"
+#include "tokenarray.hxx"
+#include "tokenuno.hxx"
 
 namespace oox {
 namespace xls {
@@ -132,6 +140,25 @@ public:
 
     // document model ---------------------------------------------------------
 
+    inline ScDocument& getScDocument() const
+    {
+        if ( !mpDoc )
+        {
+            if ( mxDoc.get() )
+            {
+                ScModelObj* pModel = dynamic_cast< ScModelObj* >( mxDoc.get() );
+                ScDocShell* pDocShell = NULL;
+                if ( pModel )
+                    pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
+                if ( pDocShell )
+                    mpDoc = pDocShell->GetDocument();
+            }
+        }
+        if ( !mpDoc )
+            throw RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Workbookhelper::getScDocument(): Failed to access ScDocument from model" ) ), Reference< XInterface >() );
+        return *mpDoc;
+    }
+
     /** Returns a reference to the source/target spreadsheet document model. */
     inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; }
     /** Returns the cell or page styles container from the Calc document. */
@@ -139,9 +166,9 @@ public:
     /** Returns the specified cell or page style from the Calc document. */
     Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const;
     /** Creates and returns a defined name on-the-fly in the Calc document. */
-    Reference< XNamedRange > createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const;
+    Reference< XNamedRange > createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags ) const;
     /** Creates and returns a defined name on the-fly in the correct Calc sheet. */
-    Reference< XNamedRange > createLocalNamedRangeObject( OUString& orName, sal_Int32 nNameFlags, sal_Int32 nTab ) const;
+    Reference< XNamedRange > createLocalNamedRangeObject( OUString& orName, const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab ) const;
     /** Creates and returns a database range on-the-fly in the Calc document. */
     Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const;
     /** Creates and returns an unnamed database range on-the-fly in the Calc document. */
@@ -289,6 +316,7 @@ private:
     BiffType            meBiff;                 /// BIFF version for BIFF import/export.
     rtl_TextEncoding    meTextEnc;              /// BIFF byte string text encoding.
     bool                mbHasCodePage;          /// True = CODEPAGE record exists in imported stream.
+    mutable ScDocument* mpDoc;
 };
 
 // ----------------------------------------------------------------------------
@@ -299,7 +327,8 @@ WorkbookGlobals::WorkbookGlobals( ExcelFilter& rFilter ) :
     meFilterType( FILTER_OOXML ),
     mpOoxFilter( &rFilter ),
     mpBiffFilter( 0 ),
-    meBiff( BIFF_UNKNOWN )
+    meBiff( BIFF_UNKNOWN ),
+    mpDoc( NULL )
 {
     // register at the filter, needed for virtual callbacks (even during construction)
     mrExcelBase.registerWorkbookGlobals( *this );
@@ -344,8 +373,27 @@ Reference< XStyle > WorkbookGlobals::getStyleObject( const OUString& rStyleName,
     OSL_ENSURE( xStyle.is(), "WorkbookGlobals::getStyleObject - cannot access style object" );
     return xStyle;
 }
+void lcl_addNewByNameAndTokens( ScDocument& rDoc, ScRangeName* pNames, const OUString& rName, const Sequence<FormulaToken>& rTokens, sal_Int16 nIndex, sal_Int32 nUnoType )
+{
+    bool bDone = false;
+    sal_uInt16 nNewType = RT_NAME;
+    if ( nUnoType & NamedRangeFlag::FILTER_CRITERIA )    nNewType |= RT_CRITERIA;
+    if ( nUnoType & NamedRangeFlag::PRINT_AREA )         nNewType |= RT_PRINTAREA;
+    if ( nUnoType & NamedRangeFlag::COLUMN_HEADER )      nNewType |= RT_COLHEADER;
+    if ( nUnoType & NamedRangeFlag::ROW_HEADER )         nNewType |= RT_ROWHEADER;
+    ScTokenArray aTokenArray;
+    (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
+    ScRangeData* pNew = new ScRangeData( &rDoc, rName, aTokenArray, ScAddress(), nNewType );
+    pNew->GuessPosition();
+    if ( nIndex )
+        pNew->SetIndex( nIndex );
+    if ( pNames->insert(pNew) )
+        bDone = true;
+    if (!bDone)
+        throw RuntimeException();
+}
 
-Reference< XNamedRange > WorkbookGlobals::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const
+Reference< XNamedRange > WorkbookGlobals::createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags ) const
 {
     // create the name and insert it into the Calc document
     Reference< XNamedRange > xNamedRange;
@@ -357,7 +405,9 @@ Reference< XNamedRange > WorkbookGlobals::createNamedRangeObject( OUString& orNa
         Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW );
         orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
         // create the named range
-        xNamedRanges->addNewByName( orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags );
+        ScDocument& rDoc =  getScDocument();
+        ScRangeName* pNames = rDoc.GetRangeName();
+        lcl_addNewByNameAndTokens( rDoc, pNames, orName, rTokens, nIndex, nNameFlags );
         xNamedRange.set( xNamedRanges->getByName( orName ), UNO_QUERY );
     }
     catch( Exception& )
@@ -367,7 +417,7 @@ Reference< XNamedRange > WorkbookGlobals::createNamedRangeObject( OUString& orNa
     return xNamedRange;
 }
 
-Reference< XNamedRange > WorkbookGlobals::createLocalNamedRangeObject( OUString& orName, sal_Int32 nNameFlags, sal_Int32 nTab ) const
+Reference< XNamedRange > WorkbookGlobals::createLocalNamedRangeObject( OUString& orName, const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken>&  rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab ) const
 {
     // create the name and insert it into the Calc document
     Reference< XNamedRange > xNamedRange;
@@ -383,7 +433,9 @@ Reference< XNamedRange > WorkbookGlobals::createLocalNamedRangeObject( OUString&
         Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW );
         orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
         // create the named range
-        xNamedRanges->addNewByName( orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags );
+        ScDocument& rDoc =  getScDocument();
+        ScRangeName* pNames = rDoc.GetRangeName( nTab );
+        lcl_addNewByNameAndTokens( rDoc, pNames, orName, rTokens, nIndex, nNameFlags );
         xNamedRange.set( xNamedRanges->getByName( orName ), UNO_QUERY );
     }
     catch( Exception& )
@@ -704,6 +756,11 @@ void WorkbookHelper::finalizeWorkbookImport()
 
 // document model -------------------------------------------------------------
 
+ScDocument& WorkbookHelper::getScDocument() const
+{
+    return mrBookGlob.getScDocument();
+}
+
 Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
 {
     return mrBookGlob.getDocument();
@@ -761,14 +818,14 @@ Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName,
     return mrBookGlob.getStyleObject( rStyleName, bPageStyle );
 }
 
-Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const
+Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags ) const
 {
-    return mrBookGlob.createNamedRangeObject( orName, nNameFlags );
+    return mrBookGlob.createNamedRangeObject( orName, rTokens, nIndex, nNameFlags );
 }
 
-Reference< XNamedRange > WorkbookHelper::createLocalNamedRangeObject( OUString& orName, sal_Int32 nNameFlags, sal_Int32 nTab ) const
+Reference< XNamedRange > WorkbookHelper::createLocalNamedRangeObject( OUString& orName, const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab ) const
 {
-    return mrBookGlob.createLocalNamedRangeObject( orName, nNameFlags, nTab );
+    return mrBookGlob.createLocalNamedRangeObject( orName, rTokens, nIndex, nNameFlags, nTab );
 }
 
 Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const


More information about the Libreoffice-commits mailing list