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

Kohei Yoshida kohei at kemper.freedesktop.org
Thu Mar 31 21:13:24 PDT 2011


 sc/inc/datauno.hxx                               |    4 
 sc/inc/dbcolect.hxx                              |   29 -
 sc/inc/document.hxx                              |    4 
 sc/inc/globalnames.hxx                           |   34 +
 sc/inc/rangeutl.hxx                              |    1 
 sc/inc/sortparam.hxx                             |   53 +-
 sc/inc/table.hxx                                 |    6 
 sc/source/core/data/document.cxx                 |   28 +
 sc/source/core/data/sortparam.cxx                |  156 +++---
 sc/source/core/data/table1.cxx                   |   15 
 sc/source/core/data/table2.cxx                   |    4 
 sc/source/core/tool/dbcolect.cxx                 |  368 ++++++++++++---
 sc/source/core/tool/rangeutl.cxx                 |   10 
 sc/source/filter/xml/XMLExportDatabaseRanges.cxx |  556 ++++++++++++++++++++++-
 sc/source/filter/xml/xmldrani.cxx                |  234 +++++++++
 sc/source/filter/xml/xmldrani.hxx                |    6 
 sc/source/ui/dbgui/dbnamdlg.cxx                  |    3 
 sc/source/ui/dbgui/foptmgr.cxx                   |    1 
 sc/source/ui/dbgui/pfiltdlg.cxx                  |    4 
 sc/source/ui/dbgui/tpsort.cxx                    |    6 
 sc/source/ui/docshell/dbdocfun.cxx               |   33 +
 sc/source/ui/docshell/docsh5.cxx                 |  102 +---
 sc/source/ui/inc/dbfunc.hxx                      |    1 
 sc/source/ui/inc/docsh.hxx                       |    1 
 sc/source/ui/inc/pfiltdlg.hxx                    |    1 
 sc/source/ui/inc/tpsort.hxx                      |    1 
 sc/source/ui/inc/undobase.hxx                    |    1 
 sc/source/ui/navipi/content.cxx                  |    4 
 sc/source/ui/undo/undobase.cxx                   |   14 
 sc/source/ui/undo/undodat.cxx                    |   19 
 sc/source/ui/undo/undoutil.cxx                   |   15 
 sc/source/ui/unoobj/datauno.cxx                  |  147 +++---
 sc/source/ui/view/cellsh1.cxx                    |   15 
 sc/source/ui/view/cellsh2.cxx                    |    3 
 sc/source/ui/view/dbfunc.cxx                     |   26 +
 sc/source/ui/view/dbfunc3.cxx                    |   11 
 36 files changed, 1541 insertions(+), 375 deletions(-)

New commits:
commit 2366721c2edb864bf9754623d645d220321bf24a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Apr 1 00:09:18 2011 -0400

    Added bits for subtotals to make use of anonymous db ranges.
    
    This change allows multiple subtotal ranges to be created on the same
    sheet.

diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
index 2e64109..2ccf38b 100644
--- a/sc/source/ui/docshell/docsh5.cxx
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -329,6 +329,23 @@ ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGe
     return pData;
 }
 
+ScDBData* ScDocShell::GetAnonymousDBData(const ScRange& rRange)
+{
+    bool bHasHeader = aDocument.HasColHeader(
+        rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab());
+
+    ScDBCollection* pColl = aDocument.GetDBCollection();
+    if (!pColl)
+        return NULL;
+
+    ScDBData* pData = pColl->getAnonByRange(rRange);
+    if (!pData)
+        return NULL;
+
+    pData->SetHeader(bHasHeader);
+    return pData;
+}
+
 ScDBData* ScDocShell::GetOldAutoDBRange()
 {
     ScDBData* pRet = pOldAutoDBRange;
diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx
index adc4a04..ff168d0 100644
--- a/sc/source/ui/inc/dbfunc.hxx
+++ b/sc/source/ui/inc/dbfunc.hxx
@@ -79,6 +79,7 @@ public:
 
                     // DB-Bereich vom Cursor
     ScDBData* 		GetDBData( sal_Bool bMarkArea = true, ScGetDBMode eMode = SC_DB_MAKE, ScGetDBSelection eSel = SC_DBSEL_KEEP, bool bShrinkToData = false, bool bExpandRows = false );
+    ScDBData*       GetAnonymousDBData();
 
     void			NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList );
 
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 86c525e..f3ffaa0 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -319,6 +319,7 @@ public:
 
     void			DBAreaDeleted( SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 );
     ScDBData*		GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGetDBSelection eSel );
+    ScDBData*       GetAnonymousDBData(const ScRange& rRange);
     ScDBData*       GetOldAutoDBRange();    // has to be deleted by caller!
     void            CancelAutoDBRange();    // called when dialog is cancelled
 
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 3f462b7..30d3933 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -2322,7 +2322,20 @@ void ScCellShell::ExecuteSubtotals(SfxRequest& rReq)
     ScSubTotalParam aSubTotalParam;
     SfxItemSet aArgSet( GetPool(), SCITEM_SUBTDATA, SCITEM_SUBTDATA );
 
-    ScDBData* pDBData = pTabViewShell->GetDBData();
+    // Only get existing named database range.
+    ScDBData* pDBData = pTabViewShell->GetDBData(true, SC_DB_OLD);
+    if (!pDBData)
+    {
+        // No existing DB data at this position.  Create an
+        // anonymous DB.
+        pDBData = pTabViewShell->GetAnonymousDBData();
+        ScRange aDataRange;
+        pDBData->GetArea(aDataRange);
+        pTabViewShell->MarkRange(aDataRange, false);
+    }
+    if (!pDBData)
+        return;
+
     pDBData->GetSubTotalParam( aSubTotalParam );
     aSubTotalParam.bRemoveOnly = false;
 
diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
index 3ea0b35..2965a7f 100644
--- a/sc/source/ui/view/dbfunc.cxx
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -196,6 +196,32 @@ ScDBData* ScDBFunc::GetDBData( sal_Bool bMark, ScGetDBMode eMode, ScGetDBSelecti
     return pData;
 }
 
+ScDBData* ScDBFunc::GetAnonymousDBData()
+{
+    ScDocShell* pDocSh = GetViewData()->GetDocShell();
+    ScRange aRange;
+    ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
+    if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+        return NULL;
+
+    // Expand to used data area if not explicitly marked.
+    const ScMarkData& rMarkData = GetViewData()->GetMarkData();
+    if (!rMarkData.IsMarked() && !rMarkData.IsMultiMarked())
+    {
+        SCCOL nCol1 = aRange.aStart.Col();
+        SCCOL nCol2 = aRange.aEnd.Col();
+        SCROW nRow1 = aRange.aStart.Row();
+        SCROW nRow2 = aRange.aEnd.Row();
+        pDocSh->GetDocument()->GetDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2, false, false);
+        aRange.aStart.SetCol(nCol1);
+        aRange.aStart.SetRow(nRow1);
+        aRange.aEnd.SetCol(nCol2);
+        aRange.aEnd.SetRow(nRow2);
+    }
+
+    return pDocSh->GetAnonymousDBData(aRange);
+}
+
 //	Datenbankbereiche aendern (Dialog)
 
 void ScDBFunc::NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList )
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index d0cb93b..1fa24c1 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -496,7 +496,16 @@ void ScDBFunc::DoSubTotals( const ScSubTotalParam& rParam, sal_Bool bRecord,
 
         ScOutlineTable*	pOut = pDoc->GetOutlineTable( nTab );
         if (pOut)
-            pOut->GetRowArray()->RemoveAll();		// nur Zeilen-Outlines loeschen
+        {
+            // Remove all existing outlines in the specified range.
+            ScOutlineArray* pRowArray = pOut->GetRowArray();
+            sal_uInt16 nDepth = pRowArray->GetDepth();
+            for (sal_uInt16 i = 0; i < nDepth; ++i)
+            {
+                sal_Bool bSize;
+                pRowArray->Remove(aNewParam.nRow1, aNewParam.nRow2, bSize);
+            }
+        }
 
         if (rParam.bReplace)
             pDoc->RemoveSubTotals( nTab, aNewParam );
commit 39af6b13319c49dc7fe252708765651a7c1869d8
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 23:52:33 2011 -0400

    Added container to store global anonymous db ranges.
    
    This is needed to support multiple subtotal ranges.

diff --git a/sc/inc/dbcolect.hxx b/sc/inc/dbcolect.hxx
index 1b40d9e..ba0d7f6 100644
--- a/sc/inc/dbcolect.hxx
+++ b/sc/inc/dbcolect.hxx
@@ -38,6 +38,8 @@
 #include "scdllapi.h"
 #include "subtotalparam.hxx"
 
+#include <boost/ptr_container/ptr_vector.hpp>
+
 class ScDocument;
 
 class ScDBData : public ScDataObject, public ScRefreshTimer
@@ -178,22 +180,25 @@ public:
             void		SetModified(sal_Bool bMod)		{ bModified = bMod; }
 
             void	UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
-            void	UpdateReference(UpdateRefMode eUpdateRefMode,
+            void	UpdateReference(ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
                                 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
-                                SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-                                ScDocument* pDoc  );
+                                SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
 };
 
 
 //------------------------------------------------------------------------
 class SC_DLLPUBLIC ScDBCollection : public ScSortedCollection
 {
+    typedef ::boost::ptr_vector<ScDBData> DBRangesType;
+public:
+    typedef DBRangesType AnonDBsType;
 
 private:
     Link		aRefreshHandler;
     ScDocument* pDoc;
     sal_uInt16 nEntryIndex;			// counter for unique indices
+    AnonDBsType maAnonDBs;
 
 public:
     ScDBCollection(sal_uInt16 nLim = 4, sal_uInt16 nDel = 4, sal_Bool bDup = false, ScDocument* pDocument = NULL) :
@@ -201,11 +206,8 @@ public:
                     pDoc				( pDocument ),
                     nEntryIndex			( SC_START_INDEX_DB_COLL )	// see above for the names
                     {}
-    ScDBCollection(const ScDBCollection& rScDBCollection) :
-                    ScSortedCollection	( rScDBCollection ),
-                    pDoc 				( rScDBCollection.pDoc ),
-                    nEntryIndex			( rScDBCollection.nEntryIndex)
-                    {}
+
+    ScDBCollection(const ScDBCollection& r);
 
     virtual	ScDataObject*	Clone() const { return new ScDBCollection(*this); }
             ScDBData*	operator[]( const sal_uInt16 nIndex) const {return (ScDBData*)At(nIndex);}
@@ -232,6 +234,13 @@ public:
     void			SetRefreshHandler( const Link& rLink )
                         { aRefreshHandler = rLink; }
     const Link&		GetRefreshHandler() const	{ return aRefreshHandler; }
+
+    const ScDBData* findAnonAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const;
+    const ScDBData* findAnonByRange(const ScRange& rRange) const;
+    ScDBData* getAnonByRange(const ScRange& rRange);
+    void insertAnonRange(ScDBData* pData);
+
+    const AnonDBsType& getAnonRanges() const;
 };
 
 #endif
diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx
index 9294e58..be160de 100644
--- a/sc/source/core/tool/dbcolect.cxx
+++ b/sc/source/core/tool/dbcolect.cxx
@@ -43,6 +43,13 @@
 #include "globstr.hrc"
 #include "subtotalparam.hxx"
 
+#include <memory>
+
+using ::std::unary_function;
+using ::std::for_each;
+using ::std::find_if;
+using ::std::remove_if;
+
 //---------------------------------------------------------------------------------------
 
 ScDBData::ScDBData( const String& rName,
@@ -612,11 +619,10 @@ void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos)
 
 }
 
-void ScDBData::UpdateReference(UpdateRefMode eUpdateRefMode,
+void ScDBData::UpdateReference(ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
                                 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
-                                SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-                                ScDocument* pDoc )
+                                SCsCOL nDx, SCsROW nDy, SCsTAB nDz)
 {
     SCCOL theCol1;
     SCROW theRow1;
@@ -653,8 +659,99 @@ void ScDBData::UpdateReference(UpdateRefMode eUpdateRefMode,
 
     //!		Testen, ob mitten aus dem Bereich geloescht/eingefuegt wurde !!!
 }
-//---------------------------------------------------------------------------------------
-//	Compare zum Sortieren
+
+namespace {
+
+class FindByTable : public ::std::unary_function<ScDBData, bool>
+{
+    SCTAB mnTab;
+public:
+    FindByTable(SCTAB nTab) : mnTab(nTab) {}
+
+    bool operator() (const ScDBData& r) const
+    {
+        ScRange aRange;
+        r.GetArea(aRange);
+        return aRange.aStart.Tab() == mnTab;
+    }
+};
+
+class UpdateRefFunc : public unary_function<ScDBData, void>
+{
+    ScDocument* mpDoc;
+    UpdateRefMode meMode;
+    SCCOL mnCol1;
+    SCROW mnRow1;
+    SCTAB mnTab1;
+    SCCOL mnCol2;
+    SCROW mnRow2;
+    SCTAB mnTab2;
+    SCsCOL mnDx;
+    SCsROW mnDy;
+    SCsTAB mnDz;
+
+public:
+    UpdateRefFunc(ScDocument* pDoc, UpdateRefMode eMode,
+                    SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+                    SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz) :
+        mpDoc(pDoc), meMode(eMode),
+        mnCol1(nCol1), mnRow1(nRow1), mnTab1(nTab1),
+        mnCol2(nCol2), mnRow2(nRow2), mnTab2(nTab2),
+        mnDx(nDx), mnDy(nDy), mnDz(nDz) {}
+
+    void operator() (ScDBData& r)
+    {
+        r.UpdateReference(mpDoc, meMode, mnCol1, mnRow1, mnTab1, mnCol2, mnRow2, mnTab2, mnDx, mnDy, mnDz);
+    }
+};
+
+class UpdateMoveTabFunc : public unary_function<ScDBData, void>
+{
+    SCTAB mnOldTab;
+    SCTAB mnNewTab;
+public:
+    UpdateMoveTabFunc(SCTAB nOld, SCTAB nNew) : mnOldTab(nOld), mnNewTab(nNew) {}
+    void operator() (ScDBData& r)
+    {
+        r.UpdateMoveTab(mnOldTab, mnNewTab);
+    }
+};
+
+class FindByCursor : public unary_function<ScDBData, bool>
+{
+    SCCOL mnCol;
+    SCROW mnRow;
+    SCTAB mnTab;
+    bool mbStartOnly;
+public:
+    FindByCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) :
+        mnCol(nCol), mnRow(nRow), mnTab(nTab), mbStartOnly(bStartOnly) {}
+
+    bool operator() (const ScDBData& r)
+    {
+        return r.IsDBAtCursor(mnCol, mnRow, mnTab, mbStartOnly);
+    }
+};
+
+class FindByRange : public unary_function<ScDBData, bool>
+{
+    const ScRange& mrRange;
+public:
+    FindByRange(const ScRange& rRange) : mrRange(rRange) {}
+
+    bool operator() (const ScDBData& r)
+    {
+        return r.IsDBAtArea(
+            mrRange.aStart.Tab(), mrRange.aStart.Col(), mrRange.aStart.Row(), mrRange.aEnd.Col(), mrRange.aEnd.Row());
+    }
+};
+
+}
+
+ScDBCollection::ScDBCollection(const ScDBCollection& r) :
+    ScSortedCollection(r), pDoc(r.pDoc), nEntryIndex(r.nEntryIndex), maAnonDBs(r.maAnonDBs)
+{}
 
 short ScDBCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
 {
@@ -687,6 +784,12 @@ ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_
     if (pNoNameData)
         if (pNoNameData->IsDBAtCursor(nCol,nRow,nTab,bStartOnly))
             return pNoNameData;
+
+    // Check the anonymous db ranges.
+    const ScDBData* pData = findAnonAtCursor(nCol, nRow, nTab, bStartOnly);
+    if (pData)
+        return const_cast<ScDBData*>(pData);
+
     return NULL;
 }
 
@@ -705,6 +808,13 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO
     if (pNoNameData)
         if (pNoNameData->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
             return pNoNameData;
+
+    // Check the anonymous db ranges.
+    ScRange aRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
+    const ScDBData* pData = findAnonByRange(aRange);
+    if (pData)
+        return const_cast<ScDBData*>(pData);
+
     return NULL;	
 }
 
@@ -732,6 +842,8 @@ void ScDBCollection::DeleteOnTab( SCTAB nTab )
         else
             ++nPos;
     }
+
+    remove_if(maAnonDBs.begin(), maAnonDBs.end(), FindByTable(nTab));
 }
 
 void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
@@ -741,26 +853,27 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
 {
     for (sal_uInt16 i=0; i<nCount; i++)
     {
-        ((ScDBData*)pItems[i])->UpdateReference(eUpdateRefMode,
-                                                nCol1, nRow1, nTab1,
-                                                nCol2, nRow2, nTab2,
-                                                nDx, nDy, nDz, pDoc);
+        ((ScDBData*)pItems[i])->UpdateReference(
+            pDoc, eUpdateRefMode,
+            nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
     }
     ScDBData* pData = pDoc->GetAnonymousDBData(nTab1);
     if (pData)
     {
-        if (nTab1==nTab2&&nDz==0)
+        if (nTab1 == nTab2 && nDz == 0)
         {
-            pData->UpdateReference(eUpdateRefMode,
-                                                nCol1, nRow1, nTab1,
-                                                nCol2, nRow2, nTab2,
-                                                nDx, nDy, nDz, pDoc);
+            pData->UpdateReference(
+                pDoc, eUpdateRefMode,
+                nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
         }
         else
         {
             //this will perhabs break undo
         }
     }
+
+    UpdateRefFunc func(pDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
+    for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
 }
 
 
@@ -773,6 +886,9 @@ void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
         ScDBData* pData = (ScDBData*)pItems[i];
         pData->UpdateMoveTab(nOldPos, nNewPos);
     }
+
+    UpdateMoveTabFunc func(nOldPos, nNewPos);
+    for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
 }
 
 
@@ -829,5 +945,46 @@ ScDBData* ScDBCollection::GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab )
     return pDoc->GetAnonymousDBData(nTab);					// "unbenannt" nur zurueck, wenn sonst nichts gefunden
 }
 
+const ScDBData* ScDBCollection::findAnonAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const
+{
+    AnonDBsType::const_iterator itr = find_if(
+        maAnonDBs.begin(), maAnonDBs.end(), FindByCursor(nCol, nRow, nTab, bStartOnly));
+    return itr == maAnonDBs.end() ? NULL : &(*itr);
+}
+
+const ScDBData* ScDBCollection::findAnonByRange(const ScRange& rRange) const
+{
+    AnonDBsType::const_iterator itr = find_if(
+        maAnonDBs.begin(), maAnonDBs.end(), FindByRange(rRange));
+    return itr == maAnonDBs.end() ? NULL : &(*itr);
+}
+
+ScDBData* ScDBCollection::getAnonByRange(const ScRange& rRange)
+{
+    const ScDBData* pData = findAnonByRange(rRange);
+    if (!pData)
+    {
+        // Insert a new db data.  They all have identical names.
+        rtl::OUString aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_GLOBAL_NONAME));
+        ::std::auto_ptr<ScDBData> pNew(new ScDBData(
+            aName, rRange.aStart.Tab(), rRange.aStart.Col(), rRange.aStart.Row(),
+            rRange.aEnd.Col(), rRange.aEnd.Row(), true, false));
+        pData = pNew.get();
+        maAnonDBs.push_back(pNew);
+    }
+    return const_cast<ScDBData*>(pData);
+}
+
+void ScDBCollection::insertAnonRange(ScDBData* pData)
+{
+    rtl::OUString aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_GLOBAL_NONAME));
+    ::std::auto_ptr<ScDBData> pNew(pData);
+    maAnonDBs.push_back(pNew);
+}
+
+const ScDBCollection::AnonDBsType& ScDBCollection::getAnonRanges() const
+{
+    return maAnonDBs;
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 146951c..2b5ae66 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -1109,8 +1109,9 @@ void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::R
 
         // See if we have global ranges.
         ScDBCollection* pDBCollection = pDoc->GetDBCollection();
-        if (pDBCollection && pDBCollection->GetCount() > 0)
-            bHasRanges = true;
+        if (pDBCollection)
+            if (pDBCollection->GetCount() > 0 || !pDBCollection->getAnonRanges().empty())
+                bHasRanges = true;
 
         if (!bHasRanges)
             // No ranges to export. Bail out.
@@ -1209,8 +1210,13 @@ void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::R
         }
 
         WriteDatabaseRange func(rExport, pDoc);
+
         // Write sheet-local ranges.
         ::std::for_each(aSheetDBs.begin(), aSheetDBs.end(), func);
+
+        // Add global anonymous DB ranges.
+        const ScDBCollection::AnonDBsType& rAnonDBs = pDBCollection->getAnonRanges();
+        ::std::for_each(rAnonDBs.begin(), rAnonDBs.end(), func);
     }
 }
 
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index 723daa0..7e91218 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -224,6 +224,8 @@ ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
 
     if (sDatabaseRangeName.matchAsciiL(STR_DB_LOCAL_NONAME, strlen(STR_DB_LOCAL_NONAME)))
         meRangeType = SheetAnonymous;
+    else if (sDatabaseRangeName.matchAsciiL(STR_DB_GLOBAL_NONAME, strlen(STR_DB_GLOBAL_NONAME)))
+        meRangeType = GlobalAnonymous;
 }
 
 ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
@@ -482,6 +484,27 @@ void ScXMLDatabaseRangeContext::EndElement()
         }
         return;
     }
+    else if (meRangeType == GlobalAnonymous)
+    {
+        OUString aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_GLOBAL_NONAME));
+        ::std::auto_ptr<ScDBData> pData(ConvertToDBData(aName));
+
+        if (pData.get())
+        {
+            if (pData->HasAutoFilter())
+            {
+                // Set autofilter flags so that the buttons get displayed.
+                ScRange aRange;
+                pData->GetArea(aRange);
+                pDoc->ApplyFlagsTab(
+                    aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
+                    aRange.aStart.Tab(), SC_MF_AUTO);
+            }
+
+            pDoc->GetDBCollection()->insertAnonRange(pData.release());
+        }
+        return;
+    }
 
     if (GetScImport().GetModel().is())
     {
commit c86918c76da5ad4458ee2623982b4f1dbecf6dc8
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 22:48:35 2011 -0400

    Finally, export the import mode parameters.

diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 99b6803..146951c 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -50,6 +50,8 @@
 #include "subtotalparam.hxx"
 #include "queryparam.hxx"
 
+#include "svx/dataaccessdescriptor.hxx"
+
 #include <com/sun/star/sheet/DataImportMode.hpp>
 #include <com/sun/star/table/TableSortField.hpp>
 #include <com/sun/star/table/TableSortFieldType.hpp>
@@ -655,6 +657,83 @@ private:
 
     void writeImport(const ScDBData& rData)
     {
+        ScImportParam aParam;
+        rData.GetImportParam(aParam);
+
+        OUString sDatabaseName;
+        OUString sConRes;
+
+        ::svx::ODataAccessDescriptor aDescriptor;
+        aDescriptor.setDataSource(aParam.aDBName);
+        if (aDescriptor.has(::svx::daDataSource))
+        {
+            sDatabaseName = aParam.aDBName;
+        }
+        else if (aDescriptor.has(::svx::daConnectionResource))
+        {
+            sConRes = aParam.aDBName;
+        }
+
+        sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
+        if (aParam.bImport)
+        {
+            if (aParam.bSql)
+                nSourceType = sheet::DataImportMode_SQL;
+            else if (aParam.nType == ScDbQuery)
+                nSourceType = sheet::DataImportMode_QUERY;
+            else
+                nSourceType = sheet::DataImportMode_TABLE;
+        }
+
+        switch (nSourceType)
+        {
+            case sheet::DataImportMode_NONE : break;
+            case sheet::DataImportMode_QUERY :
+            {
+                if (sDatabaseName.getLength())
+                    mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, aParam.aStatement);
+                SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, true, true);
+                if (sConRes.getLength())
+                {
+                    mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+                    SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
+                }
+            }
+            break;
+            case sheet::DataImportMode_TABLE :
+            {
+                if (sDatabaseName.getLength())
+                    mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, aParam.aStatement);
+                SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, true, true);
+                if (sConRes.getLength())
+                {
+                    mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+                    SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
+                }
+            }
+            break;
+            case sheet::DataImportMode_SQL :
+            {
+                if (sDatabaseName.getLength())
+                    mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, aParam.aStatement);
+                if (!aParam.bNative)
+                    mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
+                SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, true, true);
+                if (sConRes.getLength())
+                {
+                    mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+                    SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
+                }
+            }
+            break;
+            default:
+            {
+                // added to avoid warnings
+            }
+        }
     }
 
     void writeSort(const ScDBData& rData)
commit aeb4a5f2ad4ba756c766b2686b3fffb06980653a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 22:28:11 2011 -0400

    Import the data import mode.  This concludes the task on the import side.

diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index 1c4ee76..723daa0 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -55,6 +55,7 @@
 #include <xmloff/xmlnmspe.hxx>
 #include <xmloff/xmluconv.hxx>
 #include <xmloff/xmlerror.hxx>
+#include <com/sun/star/sheet/DataImportMode.hpp>
 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
 #include <com/sun/star/sheet/XDatabaseRanges.hpp>
 #include <com/sun/star/sheet/XDatabaseRange.hpp>
@@ -302,7 +303,37 @@ ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
     pData->SetDoSize(bMoveCells);
     pData->SetStripData(bStripData);
 
-    // TODO: Properly import other paramters as well.
+    {
+        ScImportParam aParam;
+        aParam.bNative = bNative;
+        aParam.aDBName = sDatabaseName.isEmpty() ? sConnectionRessource : sDatabaseName;
+        aParam.aStatement = sSourceObject;
+        sheet::DataImportMode eMode = static_cast<sheet::DataImportMode>(nSourceType);
+        switch (eMode)
+        {
+            case sheet::DataImportMode_NONE:
+                aParam.bImport = false;
+                break;
+            case sheet::DataImportMode_SQL:
+                aParam.bImport = true;
+                aParam.bSql    = true;
+                break;
+            case sheet::DataImportMode_TABLE:
+                aParam.bImport = true;
+                aParam.bSql    = false;
+                aParam.nType   = ScDbTable;
+                break;
+            case sheet::DataImportMode_QUERY:
+                aParam.bImport = true;
+                aParam.bSql    = false;
+                aParam.nType   = ScDbQuery;
+                break;
+            default:
+                OSL_FAIL("Unknown data import mode");
+                aParam.bImport = false;
+        }
+        pData->SetImportParam(aParam);
+    }
 
     {
         ScQueryParam aParam;
@@ -410,6 +441,13 @@ ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
         pData->SetSubTotalParam(aParam);
     }
 
+    if (pData->HasImportParam() && !pData->HasImportSelection())
+    {
+        pData->SetRefreshDelay(nRefresh);
+        pData->SetRefreshHandler(pDoc->GetDBCollection()->GetRefreshHandler());
+        pData->SetRefreshControl(pDoc->GetRefreshTimerControlAddress());
+    }
+
     return pData.release();
 }
 
commit 95cc42e537332e73bf27746a9cb4360c0ebd365a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 22:10:44 2011 -0400

    Moved up the user index data member.

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 05e2d8f..56c50a3 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -46,12 +46,12 @@ struct SC_DLLPUBLIC ScSortParam
     SCROW       nRow1;
     SCCOL       nCol2;
     SCROW       nRow2;
+    sal_uInt16  nUserIndex;
     bool        bHasHeader;
     bool        bByRow;
     bool        bCaseSens;
     bool        bNaturalSort;
     bool        bUserDef;
-    sal_uInt16  nUserIndex;
     bool        bIncludePattern;
     bool        bInplace;
     SCTAB       nDestTab;
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 7876293..4a8c3ff 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -50,10 +50,10 @@ ScSortParam::ScSortParam()
 //------------------------------------------------------------------------
 
 ScSortParam::ScSortParam( const ScSortParam& r ) :
-        nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),
-        bHasHeader(r.bHasHeader),bByRow(r.bByRow),bCaseSens(r.bCaseSens),bNaturalSort(r.bNaturalSort),
-        bUserDef(r.bUserDef),nUserIndex(r.nUserIndex),bIncludePattern(r.bIncludePattern),
-        bInplace(r.bInplace),
+        nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nUserIndex(r.nUserIndex),
+        bHasHeader(r.bHasHeader),bByRow(r.bByRow),bCaseSens(r.bCaseSens),
+        bNaturalSort(r.bNaturalSort),bUserDef(r.bUserDef),
+        bIncludePattern(r.bIncludePattern),bInplace(r.bInplace),
         nDestTab(r.nDestTab),nDestCol(r.nDestCol),nDestRow(r.nDestRow),
         aCollatorLocale( r.aCollatorLocale ), aCollatorAlgorithm( r.aCollatorAlgorithm ),
         nCompatHeader( r.nCompatHeader )
@@ -96,12 +96,12 @@ ScSortParam& ScSortParam::operator=( const ScSortParam& r )
     nRow1           = r.nRow1;
     nCol2           = r.nCol2;
     nRow2           = r.nRow2;
+    nUserIndex      = r.nUserIndex;
     bHasHeader      = r.bHasHeader;
     bByRow          = r.bByRow;
     bCaseSens       = r.bCaseSens;
     bNaturalSort    = r.bNaturalSort;
     bUserDef        = r.bUserDef;
-    nUserIndex      = r.nUserIndex;
     bIncludePattern = r.bIncludePattern;
     bInplace        = r.bInplace;
     nDestTab        = r.nDestTab;
@@ -167,9 +167,9 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
 //------------------------------------------------------------------------
 
 ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld ) :
-        nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),
+        nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),nUserIndex(rSub.nUserIndex),
         bHasHeader(true),bByRow(true),bCaseSens(rSub.bCaseSens),bNaturalSort(rOld.bNaturalSort),
-        bUserDef(rSub.bUserDef),nUserIndex(rSub.nUserIndex),bIncludePattern(rSub.bIncludePattern),
+        bUserDef(rSub.bUserDef),bIncludePattern(rSub.bIncludePattern),
         bInplace(true),
         nDestTab(0),nDestCol(0),nDestRow(0),
         aCollatorLocale( rOld.aCollatorLocale ), aCollatorAlgorithm( rOld.aCollatorAlgorithm ),
@@ -224,11 +224,11 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld )
 //------------------------------------------------------------------------
 
 ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
-        nCol1(nCol),nRow1(rParam.nRow1),nCol2(nCol),nRow2(rParam.nRow2),
+        nCol1(nCol),nRow1(rParam.nRow1),nCol2(nCol),nRow2(rParam.nRow2),nUserIndex(0),
         bHasHeader(rParam.bHasHeader),bByRow(true),bCaseSens(rParam.bCaseSens),
         bNaturalSort(false),
 //! TODO: what about Locale and Algorithm?
-        bUserDef(false),nUserIndex(0),bIncludePattern(false),
+        bUserDef(false),bIncludePattern(false),
         bInplace(true),
         nDestTab(0),nDestCol(0),nDestRow(0), nCompatHeader(2)
 {
commit 2b23fb8a5ef3424c542936711c58abd11f2ae872
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 22:05:47 2011 -0400

    Cleaned up ScSortParam.
    
    Tabs and sal_Bool madness.

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 35df2d9..05e2d8f 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -35,35 +35,34 @@
 #include <com/sun/star/lang/Locale.hpp>
 #include "scdllapi.h"
 
-#define MAXSORT		3
-
+#define MAXSORT 3
 
 struct ScSubTotalParam;
 struct ScQueryParam;
 
 struct SC_DLLPUBLIC ScSortParam
 {
-    SCCOL		nCol1;
-    SCROW		nRow1;
-    SCCOL		nCol2;
-    SCROW		nRow2;
-    sal_Bool		bHasHeader;
-    sal_Bool		bByRow;
-    sal_Bool		bCaseSens;
-    sal_Bool		bNaturalSort;
-    sal_Bool		bUserDef;
-    sal_uInt16		nUserIndex;
-    sal_Bool		bIncludePattern;
-    sal_Bool		bInplace;
-    SCTAB		nDestTab;
-    SCCOL		nDestCol;
-    SCROW		nDestRow;
-    sal_Bool		bDoSort[MAXSORT];
-    SCCOLROW	nField[MAXSORT];
-    sal_Bool		bAscending[MAXSORT];
-    ::com::sun::star::lang::Locale		aCollatorLocale;
+    SCCOL       nCol1;
+    SCROW       nRow1;
+    SCCOL       nCol2;
+    SCROW       nRow2;
+    bool        bHasHeader;
+    bool        bByRow;
+    bool        bCaseSens;
+    bool        bNaturalSort;
+    bool        bUserDef;
+    sal_uInt16  nUserIndex;
+    bool        bIncludePattern;
+    bool        bInplace;
+    SCTAB       nDestTab;
+    SCCOL       nDestCol;
+    SCROW       nDestRow;
+    bool        bDoSort[MAXSORT];
+    SCCOLROW    nField[MAXSORT];
+    bool        bAscending[MAXSORT];
+    ::com::sun::star::lang::Locale aCollatorLocale;
     ::rtl::OUString aCollatorAlgorithm;
-    sal_uInt16		nCompatHeader;
+    sal_uInt16  nCompatHeader;
 
     ScSortParam();
     ScSortParam( const ScSortParam& r );
@@ -72,11 +71,11 @@ struct SC_DLLPUBLIC ScSortParam
     /// TopTen sort
     ScSortParam( const ScQueryParam&, SCCOL nCol );
 
-    ScSortParam&	operator=	( const ScSortParam& r );
-    sal_Bool			operator==	( const ScSortParam& rOther ) const;
-    void			Clear		();
+    ScSortParam&    operator=  ( const ScSortParam& r );
+    bool            operator== ( const ScSortParam& rOther ) const;
+    void            Clear       ();
 
-    void			MoveToDest();
+    void            MoveToDest();
 };
 
 
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 411ac48..7876293 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -60,8 +60,8 @@ ScSortParam::ScSortParam( const ScSortParam& r ) :
 {
     for (sal_uInt16 i=0; i<MAXSORT; i++)
     {
-        bDoSort[i]	  = r.bDoSort[i];
-        nField[i]	  = r.nField[i];
+        bDoSort[i]    = r.bDoSort[i];
+        nField[i]     = r.nField[i];
         bAscending[i] = r.bAscending[i];
     }
 }
@@ -76,15 +76,15 @@ void ScSortParam::Clear()
     nDestTab = 0;
     nUserIndex = 0;
     bHasHeader=bCaseSens=bUserDef=bNaturalSort = false;
-    bByRow=bIncludePattern=bInplace	= true;
+    bByRow=bIncludePattern=bInplace = true;
     aCollatorLocale = ::com::sun::star::lang::Locale();
     aCollatorAlgorithm = ::rtl::OUString();
 
     for (sal_uInt16 i=0; i<MAXSORT; i++)
     {
-        bDoSort[i]	  = false;
-        nField[i]	  = 0;
-        bAscending[i] = sal_True;
+        bDoSort[i]    = false;
+        nField[i]     = 0;
+        bAscending[i] = true;
     }
 }
 
@@ -92,29 +92,29 @@ void ScSortParam::Clear()
 
 ScSortParam& ScSortParam::operator=( const ScSortParam& r )
 {
-    nCol1			= r.nCol1;
-    nRow1			= r.nRow1;
-    nCol2			= r.nCol2;
-    nRow2			= r.nRow2;
-    bHasHeader		= r.bHasHeader;
-    bByRow			= r.bByRow;
-    bCaseSens		= r.bCaseSens;
-    bNaturalSort	= r.bNaturalSort;
-    bUserDef		= r.bUserDef;
-    nUserIndex		= r.nUserIndex;
-    bIncludePattern	= r.bIncludePattern;
-    bInplace		= r.bInplace;
-    nDestTab		= r.nDestTab;
-    nDestCol		= r.nDestCol;
-    nDestRow		= r.nDestRow;
-    aCollatorLocale			= r.aCollatorLocale;
-    aCollatorAlgorithm		= r.aCollatorAlgorithm;
+    nCol1           = r.nCol1;
+    nRow1           = r.nRow1;
+    nCol2           = r.nCol2;
+    nRow2           = r.nRow2;
+    bHasHeader      = r.bHasHeader;
+    bByRow          = r.bByRow;
+    bCaseSens       = r.bCaseSens;
+    bNaturalSort    = r.bNaturalSort;
+    bUserDef        = r.bUserDef;
+    nUserIndex      = r.nUserIndex;
+    bIncludePattern = r.bIncludePattern;
+    bInplace        = r.bInplace;
+    nDestTab        = r.nDestTab;
+    nDestCol        = r.nDestCol;
+    nDestRow        = r.nDestRow;
+    aCollatorLocale         = r.aCollatorLocale;
+    aCollatorAlgorithm      = r.aCollatorAlgorithm;
     nCompatHeader   = r.nCompatHeader;
 
     for (sal_uInt16 i=0; i<MAXSORT; i++)
     {
-        bDoSort[i]	  = r.bDoSort[i];
-        nField[i]	  = r.nField[i];
+        bDoSort[i]    = r.bDoSort[i];
+        nField[i]     = r.nField[i];
         bAscending[i] = r.bAscending[i];
     }
 
@@ -123,42 +123,42 @@ ScSortParam& ScSortParam::operator=( const ScSortParam& r )
 
 //------------------------------------------------------------------------
 
-sal_Bool ScSortParam::operator==( const ScSortParam& rOther ) const
+bool ScSortParam::operator==( const ScSortParam& rOther ) const
 {
-    sal_Bool bEqual = false;
+    bool bEqual = false;
     // Anzahl der Sorts gleich?
-    sal_uInt16 nLast 	  = 0;
+    sal_uInt16 nLast      = 0;
     sal_uInt16 nOtherLast = 0;
     while ( bDoSort[nLast++] && nLast < MAXSORT ) ;
     while ( rOther.bDoSort[nOtherLast++] && nOtherLast < MAXSORT ) ;
     nLast--;
     nOtherLast--;
-    if (   (nLast 			== nOtherLast)
-        && (nCol1			== rOther.nCol1)
-        && (nRow1			== rOther.nRow1)
-        && (nCol2			== rOther.nCol2)
-        && (nRow2			== rOther.nRow2)
-        && (bHasHeader		== rOther.bHasHeader)
-        && (bByRow			== rOther.bByRow)
-        && (bCaseSens		== rOther.bCaseSens)
-        && (bNaturalSort	== rOther.bNaturalSort)
-        && (bUserDef		== rOther.bUserDef)
-        && (nUserIndex		== rOther.nUserIndex)
+    if (   (nLast           == nOtherLast)
+        && (nCol1           == rOther.nCol1)
+        && (nRow1           == rOther.nRow1)
+        && (nCol2           == rOther.nCol2)
+        && (nRow2           == rOther.nRow2)
+        && (bHasHeader      == rOther.bHasHeader)
+        && (bByRow          == rOther.bByRow)
+        && (bCaseSens       == rOther.bCaseSens)
+        && (bNaturalSort    == rOther.bNaturalSort)
+        && (bUserDef        == rOther.bUserDef)
+        && (nUserIndex      == rOther.nUserIndex)
         && (bIncludePattern == rOther.bIncludePattern)
-        && (bInplace		== rOther.bInplace)
-        && (nDestTab		== rOther.nDestTab)
-        && (nDestCol		== rOther.nDestCol)
-        && (nDestRow		== rOther.nDestRow)
-        && (aCollatorLocale.Language	== rOther.aCollatorLocale.Language)
-        && (aCollatorLocale.Country		== rOther.aCollatorLocale.Country)
-        && (aCollatorLocale.Variant		== rOther.aCollatorLocale.Variant)
-        && (aCollatorAlgorithm			== rOther.aCollatorAlgorithm)
+        && (bInplace        == rOther.bInplace)
+        && (nDestTab        == rOther.nDestTab)
+        && (nDestCol        == rOther.nDestCol)
+        && (nDestRow        == rOther.nDestRow)
+        && (aCollatorLocale.Language    == rOther.aCollatorLocale.Language)
+        && (aCollatorLocale.Country     == rOther.aCollatorLocale.Country)
+        && (aCollatorLocale.Variant     == rOther.aCollatorLocale.Variant)
+        && (aCollatorAlgorithm          == rOther.aCollatorAlgorithm)
         )
     {
-        bEqual = sal_True;
+        bEqual = true;
         for ( sal_uInt16 i=0; i<=nLast && bEqual; i++ )
         {
-            bEqual = (nField[i] == rOther.nField[i]) && (bAscending[i]	== rOther.bAscending[i]);
+            bEqual = (nField[i] == rOther.nField[i]) && (bAscending[i]  == rOther.bAscending[i]);
         }
     }
     return bEqual;
@@ -170,7 +170,7 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld )
         nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),
         bHasHeader(true),bByRow(true),bCaseSens(rSub.bCaseSens),bNaturalSort(rOld.bNaturalSort),
         bUserDef(rSub.bUserDef),nUserIndex(rSub.nUserIndex),bIncludePattern(rSub.bIncludePattern),
-        bInplace(sal_True),
+        bInplace(true),
         nDestTab(0),nDestCol(0),nDestRow(0),
         aCollatorLocale( rOld.aCollatorLocale ), aCollatorAlgorithm( rOld.aCollatorAlgorithm ),
         nCompatHeader( rOld.nCompatHeader )
@@ -178,46 +178,46 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld )
     sal_uInt16 nNewCount = 0;
     sal_uInt16 i;
 
-    //	zuerst die Gruppen aus den Teilergebnissen
+    //  zuerst die Gruppen aus den Teilergebnissen
     if (rSub.bDoSort)
         for (i=0; i<MAXSUBTOTAL; i++)
             if (rSub.bGroupActive[i])
             {
                 if (nNewCount < MAXSORT)
                 {
-                    bDoSort[nNewCount]	  = sal_True;
-                    nField[nNewCount]	  = rSub.nField[i];
+                    bDoSort[nNewCount]    = true;
+                    nField[nNewCount]     = rSub.nField[i];
                     bAscending[nNewCount] = rSub.bAscending;
                     ++nNewCount;
                 }
             }
 
-    //	dann dahinter die alten Einstellungen
+    //  dann dahinter die alten Einstellungen
     for (i=0; i<MAXSORT; i++)
         if (rOld.bDoSort[i])
         {
             SCCOLROW nThisField = rOld.nField[i];
-            sal_Bool bDouble = false;
+            bool bDouble = false;
             for (sal_uInt16 j=0; j<nNewCount; j++)
                 if ( nField[j] == nThisField )
-                    bDouble = sal_True;
-            if (!bDouble)				// ein Feld nicht zweimal eintragen
+                    bDouble = true;
+            if (!bDouble)               // ein Feld nicht zweimal eintragen
             {
                 if (nNewCount < MAXSORT)
                 {
-                    bDoSort[nNewCount]	  = sal_True;
-                    nField[nNewCount]	  = nThisField;
+                    bDoSort[nNewCount]    = true;
+                    nField[nNewCount]     = nThisField;
                     bAscending[nNewCount] = rOld.bAscending[i];
                     ++nNewCount;
                 }
             }
         }
 
-    for (i=nNewCount; i<MAXSORT; i++)		// Rest loeschen
+    for (i=nNewCount; i<MAXSORT; i++)       // Rest loeschen
     {
-        bDoSort[i]	  = false;
-        nField[i]	  = 0;
-        bAscending[i] = sal_True;
+        bDoSort[i]    = false;
+        nField[i]     = 0;
+        bAscending[i] = true;
     }
 }
 
@@ -232,14 +232,14 @@ ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
         bInplace(true),
         nDestTab(0),nDestCol(0),nDestRow(0), nCompatHeader(2)
 {
-    bDoSort[0] = sal_True;
+    bDoSort[0] = true;
     nField[0] = nCol;
-    bAscending[0] = sal_True;
+    bAscending[0] = true;
     for (sal_uInt16 i=1; i<MAXSORT; i++)
     {
-        bDoSort[i]	  = false;
-        nField[i]	  = 0;
-        bAscending[i] = sal_True;
+        bDoSort[i]    = false;
+        nField[i]     = 0;
+        bAscending[i] = true;
     }
 }
 
@@ -262,7 +262,7 @@ void ScSortParam::MoveToDest()
             else
                 nField[i] += nDifY;
 
-        bInplace = sal_True;
+        bInplace = true;
     }
     else
     {
commit 4ad6710509252443407d86c21239a6d7f562b57b
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 21:56:37 2011 -0400

    Import sort paramters for the anonymous database ranges.

diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index 69bd85a..1c4ee76 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -341,6 +341,24 @@ ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
 
     if (bContainsSort)
     {
+        size_t nOldSize = aSortSequence.getLength();
+        aSortSequence.realloc(nOldSize + 1);
+        beans::PropertyValue aProperty;
+        aProperty.Name = OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT));
+        aProperty.Value <<= eOrientation;
+        aSortSequence[nOldSize] = aProperty;
+        ScSortParam aParam;
+        ScSortDescriptor::FillSortParam(aParam, aSortSequence);
+
+        SCCOLROW nStartPos = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+        for (size_t i = 0; i < MAXSORT; ++i)
+        {
+            if (!aParam.bDoSort[i])
+                break;
+            aParam.nField[i] += nStartPos;
+        }
+
+        pData->SetSortParam(aParam);
     }
 
     if (bContainsSubTotal)
commit a0f524c3b2eb975bc52f4877e0709de6b9bbebd2
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 20:37:57 2011 -0400

    Convert field positions from absolute to relative upon export.

diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index acd5f59..99b6803 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -699,10 +699,15 @@ private:
 
         SvXMLElementExport aElemS(mrExport, XML_NAMESPACE_TABLE, XML_SORT, true, true);
 
+        ScRange aRange;
+        rData.GetArea(aRange);
+        SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+
         for (size_t i = 0; i < nSortCount; ++i)
         {
-            // TODO: Convert field value.
-            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aParam.nField[i]));
+            // Convert field value from absolute to relative.
+            SCCOLROW nField = aParam.nField[i] - nFieldStart;
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nField));
 
             if (!aParam.bAscending[i])
                 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
commit efee92582729319c74bea6bca62cc5d37ae419c6
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 20:26:56 2011 -0400

    First cut on exporting sort parameters.

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 32991c9..35df2d9 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -62,7 +62,7 @@ struct SC_DLLPUBLIC ScSortParam
     SCCOLROW	nField[MAXSORT];
     sal_Bool		bAscending[MAXSORT];
     ::com::sun::star::lang::Locale		aCollatorLocale;
-    String		aCollatorAlgorithm;
+    ::rtl::OUString aCollatorAlgorithm;
     sal_uInt16		nCompatHeader;
 
     ScSortParam();
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 900fff4..411ac48 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -78,7 +78,7 @@ void ScSortParam::Clear()
     bHasHeader=bCaseSens=bUserDef=bNaturalSort = false;
     bByRow=bIncludePattern=bInplace	= true;
     aCollatorLocale = ::com::sun::star::lang::Locale();
-    aCollatorAlgorithm.Erase();
+    aCollatorAlgorithm = ::rtl::OUString();
 
     for (sal_uInt16 i=0; i<MAXSORT; i++)
     {
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index d2ee414..acd5f59 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -659,6 +659,70 @@ private:
 
     void writeSort(const ScDBData& rData)
     {
+        ScSortParam aParam;
+        rData.GetSortParam(aParam);
+
+        // Count sort items first.
+        size_t nSortCount = 0;
+        for (; nSortCount < MAXSORT; ++nSortCount)
+        {
+            if (!aParam.bDoSort[nSortCount])
+                break;
+        }
+
+        if (!nSortCount)
+            // Nothing to export.
+            return;
+
+        ScAddress aOutPos(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab);
+
+        if (!aParam.bIncludePattern)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+
+        if (!aParam.bInplace)
+        {
+            OUString aStr;
+            ScRangeStringConverter::GetStringFromAddress(
+                aStr, aOutPos, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aStr);
+        }
+
+        if (aParam.bCaseSens)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+
+        if (!aParam.aCollatorLocale.Language.isEmpty())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aParam.aCollatorLocale.Language);
+        if (!aParam.aCollatorLocale.Country.isEmpty())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aParam.aCollatorLocale.Country);
+        if (!aParam.aCollatorAlgorithm.isEmpty())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aParam.aCollatorAlgorithm);
+
+        SvXMLElementExport aElemS(mrExport, XML_NAMESPACE_TABLE, XML_SORT, true, true);
+
+        for (size_t i = 0; i < nSortCount; ++i)
+        {
+            // TODO: Convert field value.
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aParam.nField[i]));
+
+            if (!aParam.bAscending[i])
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+
+            if (aParam.bUserDef)
+            {
+                OUStringBuffer aBuf;
+                aBuf.appendAscii(SC_USERLIST);
+                aBuf.append(aParam.nUserIndex);
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
+            }
+            else
+            {
+                // Right now we only support automatic field type.  In the
+                // future we may support numeric or alphanumeric field type.
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
+            }
+
+            SvXMLElementExport aElemSb(mrExport, XML_NAMESPACE_TABLE, XML_SORT_BY, true, true);
+        }
     }
 
     OUString getOperatorXML(const ScQueryEntry& rEntry, bool bRegExp) const
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index 2450abb..8cc4a37 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -766,7 +766,7 @@ void ScTabPageSortOptions::Reset( const SfxItemSet& /* rArgSet */ )
         eLang = LANGUAGE_SYSTEM;
     aLbLanguage.SelectLanguage( eLang );
     FillAlgorHdl( &aLbLanguage );				// get algorithms, select default
-    if ( rSortData.aCollatorAlgorithm.Len() )
+    if ( !rSortData.aCollatorAlgorithm.isEmpty() )
         aLbAlgorithm.SelectEntry( pColRes->GetTranslation( rSortData.aCollatorAlgorithm ) );
 
     if ( pDoc && !rSortData.bInplace )
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 0d7b7f1..edc7fea 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -346,7 +346,7 @@ void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq
             pFieldArray[i].FieldType	 = table::TableSortFieldType_AUTOMATIC;		// immer Automatic
             pFieldArray[i].IsCaseSensitive = rParam.bCaseSens;
             pFieldArray[i].CollatorLocale = rParam.aCollatorLocale;
-            pFieldArray[i].CollatorAlgorithm = rtl::OUString( rParam.aCollatorAlgorithm );
+            pFieldArray[i].CollatorAlgorithm = rParam.aCollatorAlgorithm;
         }
     }
 
commit 598f3fc2d59bcd38beb88487959e02a307a5af14
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 19:23:05 2011 -0400

    Let's check the db data itself instead of using the old flag value.

diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index c7879fe..69bd85a 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -412,7 +412,7 @@ void ScXMLDatabaseRangeContext::EndElement()
             OUString aStrNum = sDatabaseRangeName.copy(aName.getLength());
             SCTAB nTab = static_cast<SCTAB>(aStrNum.toInt32());
 
-            if (bAutoFilter)
+            if (pData->HasAutoFilter())
             {
                 // Set autofilter flags so that the buttons get displayed.
                 ScRange aRange;
commit 74af1151d5429a1ebce08e190f1daaab00094343
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 19:17:38 2011 -0400

    Convert field positions from relative to absolute on import.

diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index c1d6f8d..c7879fe 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -317,6 +317,18 @@ ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
         aParam.nDestCol = aFilterOutputPosition.Column;
         aParam.nDestRow = aFilterOutputPosition.Row;
         ScFilterDescriptorBase::fillQueryParam(aParam, pDoc, aFilterFields);
+
+        // Convert from relative to absolute column IDs for the fields. Calc
+        // core expects the field positions to be absolute column IDs.
+        SCCOLROW nStartPos = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+        for (size_t i = 0; i < MAXQUERY; ++i)
+        {
+            ScQueryEntry& rEntry = aParam.GetEntry(i);
+            if (!rEntry.bDoQuery)
+                break;
+            rEntry.nField += nStartPos;
+        }
+
         pData->SetQueryParam(aParam);
     }
 
commit 208e1b9ac1ad10f6be5eb144e34666a92ac8f989
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 15:17:28 2011 -0400

    Initial cut on trying to import the filtering properties of anonymous db.
    
    Still not quite working right.  Something must be broken.

diff --git a/sc/inc/datauno.hxx b/sc/inc/datauno.hxx
index b93569b..429ca3a 100644
--- a/sc/inc/datauno.hxx
+++ b/sc/inc/datauno.hxx
@@ -353,6 +353,10 @@ private:
     ScDocShell*             pDocSh;
 
 public:
+    static void fillQueryParam(
+        ScQueryParam& rParam, ScDocument* pDoc,
+        const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::TableFilterField2>& aFilterFields);
+
                             ScFilterDescriptorBase(ScDocShell* pDocShell);
     virtual					~ScFilterDescriptorBase();
 
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index c9dad19..c1d6f8d 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -304,6 +304,33 @@ ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
 
     // TODO: Properly import other paramters as well.
 
+    {
+        ScQueryParam aParam;
+        pData->GetQueryParam(aParam);
+        aParam.bByRow = (eOrientation == table::TableOrientation_ROWS);
+        aParam.bHasHeader = bContainsHeader;
+        aParam.bInplace = !bFilterCopyOutputData;
+        aParam.bCaseSens = bFilterIsCaseSensitive;
+        aParam.bDuplicate = !bFilterSkipDuplicates;
+        aParam.bRegExp = bFilterUseRegularExpressions;
+        aParam.nDestTab = aFilterOutputPosition.Sheet;
+        aParam.nDestCol = aFilterOutputPosition.Column;
+        aParam.nDestRow = aFilterOutputPosition.Row;
+        ScFilterDescriptorBase::fillQueryParam(aParam, pDoc, aFilterFields);
+        pData->SetQueryParam(aParam);
+    }
+
+    if (bFilterConditionSourceRange)
+    {
+        ScRange aAdvSource;
+        ScUnoConversion::FillScRange(aAdvSource, aFilterConditionSourceRangeAddress);
+        pData->SetAdvancedQuerySource(&aAdvSource);
+    }
+
+    if (bContainsSort)
+    {
+    }
+
     if (bContainsSubTotal)
     {
         ScSubTotalParam aParam;
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index b1c4b4c..0d7b7f1 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -1064,6 +1064,80 @@ void SAL_CALL ScConsolidationDescriptor::setInsertLinks( sal_Bool bInsertLinks )
 
 //------------------------------------------------------------------------
 
+void ScFilterDescriptorBase::fillQueryParam(
+    ScQueryParam& rParam, ScDocument* pDoc,
+    const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
+{
+    SCSIZE nCount = static_cast<SCSIZE>(aFilterFields.getLength());
+    DBG_ASSERT( nCount <= MAXQUERY, "setFilterFields: zu viele" );
+
+    rParam.Resize( nCount );
+
+    const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
+    SCSIZE i;
+    for (i=0; i<nCount; i++)
+    {
+        ScQueryEntry& rEntry = rParam.GetEntry(i);
+        if (!rEntry.pStr)
+            rEntry.pStr = new String;		// sollte nicht sein (soll immer initialisiert sein)
+
+        rEntry.bDoQuery			= sal_True;
+        rEntry.eConnect			= (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
+        rEntry.nField			= pAry[i].Field;
+        rEntry.bQueryByString	= !pAry[i].IsNumeric;
+        *rEntry.pStr			= String( pAry[i].StringValue );
+        rEntry.nVal				= pAry[i].NumericValue;
+
+        if (!rEntry.bQueryByString && pDoc)
+        {
+            pDoc->GetFormatTable()->GetInputLineString(rEntry.nVal, 0, *rEntry.pStr);
+        }
+
+        switch (pAry[i].Operator)			// FilterOperator
+        {
+        case sheet::FilterOperator2::EQUAL:			        rEntry.eOp = SC_EQUAL;		        break;
+        case sheet::FilterOperator2::LESS:			        rEntry.eOp = SC_LESS;			    break;
+        case sheet::FilterOperator2::GREATER:			    rEntry.eOp = SC_GREATER;		    break;
+        case sheet::FilterOperator2::LESS_EQUAL:		    rEntry.eOp = SC_LESS_EQUAL;	        break;
+        case sheet::FilterOperator2::GREATER_EQUAL:	        rEntry.eOp = SC_GREATER_EQUAL;      break;
+        case sheet::FilterOperator2::NOT_EQUAL:		        rEntry.eOp = SC_NOT_EQUAL;	        break;
+        case sheet::FilterOperator2::TOP_VALUES:	    	rEntry.eOp = SC_TOPVAL;		        break;
+        case sheet::FilterOperator2::BOTTOM_VALUES:	        rEntry.eOp = SC_BOTVAL;		        break;
+        case sheet::FilterOperator2::TOP_PERCENT:		    rEntry.eOp = SC_TOPPERC;		    break;
+        case sheet::FilterOperator2::BOTTOM_PERCENT:	    rEntry.eOp = SC_BOTPERC;		    break;
+        case sheet::FilterOperator2::CONTAINS:		        rEntry.eOp = SC_CONTAINS;		    break;
+        case sheet::FilterOperator2::DOES_NOT_CONTAIN:		rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
+        case sheet::FilterOperator2::BEGINS_WITH:			rEntry.eOp = SC_BEGINS_WITH;		break;
+        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:	rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
+        case sheet::FilterOperator2::ENDS_WITH:			    rEntry.eOp = SC_ENDS_WITH;		    break;
+        case sheet::FilterOperator2::DOES_NOT_END_WITH:		rEntry.eOp = SC_DOES_NOT_END_WITH;	break;
+        case sheet::FilterOperator2::EMPTY:
+            {
+                rEntry.eOp = SC_EQUAL;
+                rEntry.nVal = SC_EMPTYFIELDS;
+                rEntry.bQueryByString = false;
+                *rEntry.pStr = EMPTY_STRING;
+            }
+            break;
+        case sheet::FilterOperator2::NOT_EMPTY:
+            {
+                rEntry.eOp = SC_EQUAL;
+                rEntry.nVal = SC_NONEMPTYFIELDS;
+                rEntry.bQueryByString = false;
+                *rEntry.pStr = EMPTY_STRING;
+            }
+            break;
+        default:
+            OSL_FAIL("Falscher Query-enum");
+            rEntry.eOp = SC_EQUAL;
+        }
+    }
+
+    SCSIZE nParamCount = rParam.GetEntryCount();	// Param wird nicht unter 8 resized
+    for (i=nCount; i<nParamCount; i++)
+        rParam.GetEntry(i).bDoQuery = false;		// ueberzaehlige Felder zuruecksetzen
+}
+
 ScFilterDescriptorBase::ScFilterDescriptorBase(ScDocShell* pDocShell) :
     aPropSet( lcl_GetFilterPropertyMap() ),
     pDocSh(pDocShell)
@@ -1316,76 +1390,7 @@ void SAL_CALL ScFilterDescriptorBase::setFilterFields2(
     SolarMutexGuard aGuard;
     ScQueryParam aParam;
     GetData(aParam);
-
-    SCSIZE nCount = static_cast<SCSIZE>(aFilterFields.getLength());
-    DBG_ASSERT( nCount <= MAXQUERY, "setFilterFields: zu viele" );
-
-    aParam.Resize( nCount );
-
-    const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
-    SCSIZE i;
-    for (i=0; i<nCount; i++)
-    {
-        ScQueryEntry& rEntry = aParam.GetEntry(i);
-        if (!rEntry.pStr)
-            rEntry.pStr = new String;		// sollte nicht sein (soll immer initialisiert sein)
-
-        rEntry.bDoQuery			= sal_True;
-        rEntry.eConnect			= (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
-        rEntry.nField			= pAry[i].Field;
-        rEntry.bQueryByString	= !pAry[i].IsNumeric;
-        *rEntry.pStr			= String( pAry[i].StringValue );
-        rEntry.nVal				= pAry[i].NumericValue;
-
-        if (!rEntry.bQueryByString && pDocSh)
-        {
-            pDocSh->GetDocument()->GetFormatTable()->GetInputLineString(rEntry.nVal, 0, *rEntry.pStr);
-        }
-
-        switch (pAry[i].Operator)			// FilterOperator
-        {
-        case sheet::FilterOperator2::EQUAL:			        rEntry.eOp = SC_EQUAL;		        break;
-        case sheet::FilterOperator2::LESS:			        rEntry.eOp = SC_LESS;			    break;
-        case sheet::FilterOperator2::GREATER:			    rEntry.eOp = SC_GREATER;		    break;
-        case sheet::FilterOperator2::LESS_EQUAL:		    rEntry.eOp = SC_LESS_EQUAL;	        break;
-        case sheet::FilterOperator2::GREATER_EQUAL:	        rEntry.eOp = SC_GREATER_EQUAL;      break;
-        case sheet::FilterOperator2::NOT_EQUAL:		        rEntry.eOp = SC_NOT_EQUAL;	        break;
-        case sheet::FilterOperator2::TOP_VALUES:	    	rEntry.eOp = SC_TOPVAL;		        break;
-        case sheet::FilterOperator2::BOTTOM_VALUES:	        rEntry.eOp = SC_BOTVAL;		        break;
-        case sheet::FilterOperator2::TOP_PERCENT:		    rEntry.eOp = SC_TOPPERC;		    break;
-        case sheet::FilterOperator2::BOTTOM_PERCENT:	    rEntry.eOp = SC_BOTPERC;		    break;
-        case sheet::FilterOperator2::CONTAINS:		        rEntry.eOp = SC_CONTAINS;		    break;
-        case sheet::FilterOperator2::DOES_NOT_CONTAIN:		rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
-        case sheet::FilterOperator2::BEGINS_WITH:			rEntry.eOp = SC_BEGINS_WITH;		break;
-        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:	rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
-        case sheet::FilterOperator2::ENDS_WITH:			    rEntry.eOp = SC_ENDS_WITH;		    break;
-        case sheet::FilterOperator2::DOES_NOT_END_WITH:		rEntry.eOp = SC_DOES_NOT_END_WITH;	break;
-        case sheet::FilterOperator2::EMPTY:
-            {
-                rEntry.eOp = SC_EQUAL;
-                rEntry.nVal = SC_EMPTYFIELDS;
-                rEntry.bQueryByString = false;
-                *rEntry.pStr = EMPTY_STRING;
-            }
-            break;
-        case sheet::FilterOperator2::NOT_EMPTY:
-            {
-                rEntry.eOp = SC_EQUAL;
-                rEntry.nVal = SC_NONEMPTYFIELDS;
-                rEntry.bQueryByString = false;
-                *rEntry.pStr = EMPTY_STRING;
-            }
-            break;
-        default:
-            OSL_FAIL("Falscher Query-enum");
-            rEntry.eOp = SC_EQUAL;
-        }
-    }
-
-    SCSIZE nParamCount = aParam.GetEntryCount();	// Param wird nicht unter 8 resized
-    for (i=nCount; i<nParamCount; i++)
-        aParam.GetEntry(i).bDoQuery = false;		// ueberzaehlige Felder zuruecksetzen
-
+    fillQueryParam(aParam, pDocSh->GetDocument(), aFilterFields);
     PutData(aParam);
 }
 
commit 809b6489c0c536a6dffd7adf216d90a268701029
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 14:30:52 2011 -0400

    Field index must be relative to the first field.
    
    Also, let's not write the subtotal element when there is not subtotal
    entries to export.

diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index edd6791..d2ee414 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -718,7 +718,7 @@ private:
 
     void writeCondition(const ScQueryEntry& rEntry, SCCOLROW nFieldStart, bool bCaseSens, bool bRegExp)
     {
-        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nFieldStart - rEntry.nField));
+        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(rEntry.nField - nFieldStart));
         if (bCaseSens)
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
         if (rEntry.bQueryByString)
@@ -784,9 +784,11 @@ private:
                 bOr = true;
         }
 
+        // Note that export field index values are relative to the first field.
         ScRange aRange;
         rData.GetArea(aRange);
-        SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Row() : aRange.aStart.Col();
+        SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+
         if (bOr && !bAnd)
         {
             SvXMLElementExport aElemOr(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
@@ -869,6 +871,16 @@ private:
         ScSubTotalParam aParam;
         rData.GetSubTotalParam(aParam);
 
+        size_t nCount = 0;
+        for (; nCount < MAXSUBTOTAL; ++nCount)
+        {
+            if (!aParam.bGroupActive[nCount])
+                break;
+        }
+
+        if (!nCount)
+            return;
+
         if (!aParam.bIncludePattern)
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
 
@@ -905,8 +917,7 @@ private:
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nFieldCol));
             SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True);
 
-            SCCOL nCount = aParam.nSubTotals[i];
-            for (SCCOL j = 0; j < nCount; ++j)
+            for (SCCOL j = 0, n = aParam.nSubTotals[i]; j < n; ++j)
             {
                 sal_Int32 nCol = static_cast<sal_Int32>(aParam.pSubTotals[i][j]);
                 ScSubTotalFunc eFunc = aParam.pFunctions[i][j];
commit aa0ed0123bc8b9d54934512bd0275f3511adf06a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 14:12:33 2011 -0400

    Field index should be relative to the first column index.

diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 95b1848..edd6791 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -663,7 +663,6 @@ private:
 
     OUString getOperatorXML(const ScQueryEntry& rEntry, bool bRegExp) const
     {
-
         switch (rEntry.eOp)
         {
             case SC_BEGINS_WITH:
@@ -717,9 +716,9 @@ private:
         return OUString(RTL_CONSTASCII_USTRINGPARAM("="));
     }
 
-    void writeCondition(const ScQueryEntry& rEntry, bool bCaseSens, bool bRegExp)
+    void writeCondition(const ScQueryEntry& rEntry, SCCOLROW nFieldStart, bool bCaseSens, bool bRegExp)
     {
-        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(rEntry.nField));
+        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nFieldStart - rEntry.nField));
         if (bCaseSens)
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
         if (rEntry.bQueryByString)
@@ -785,21 +784,24 @@ private:
                 bOr = true;
         }
 
+        ScRange aRange;
+        rData.GetArea(aRange);
+        SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Row() : aRange.aStart.Col();
         if (bOr && !bAnd)
         {
             SvXMLElementExport aElemOr(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
             for (size_t i = 0; i < nCount; ++i)
-                writeCondition(aParam.GetEntry(i), aParam.bCaseSens, aParam.bRegExp);
+                writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
         }
         else if (bAnd && !bOr)
         {
             SvXMLElementExport aElemAnd(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, true, true);
             for (size_t i = 0; i < nCount; ++i)
-                writeCondition(aParam.GetEntry(i), aParam.bCaseSens, aParam.bRegExp);
+                writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
         }
         else if (nCount == 1)
         {
-            writeCondition(aParam.GetEntry(0), aParam.bCaseSens, aParam.bRegExp);
+            writeCondition(aParam.GetEntry(0), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
         }
         else
         {
@@ -827,18 +829,18 @@ private:
                     {
                         mrExport.StartElement(aName, true );
                         bOpenAndElement = true;
-                        writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                        writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
                         aPrevEntry = rEntry;
                         if (i == nCount - 1)
                         {
-                            writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                            writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
                             mrExport.EndElement(aName, true);
                             bOpenAndElement = false;
                         }
                     }
                     else
                     {
-                        writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                        writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
                         aPrevEntry = rEntry;
                         if (bOpenAndElement)
                         {
@@ -846,15 +848,15 @@ private:
                             bOpenAndElement = false;
                         }
                         if (i == nCount - 1)
-                            writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                            writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
                     }
                 }
                 else
                 {
-                    writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                    writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
                     aPrevEntry = rEntry;
                     if (i == nCount - 1)
-                        writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                        writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
                 }
             }
             if(bOpenAndElement)
commit 587d711258405afd98629edb7f77cdc43e8dedb7
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 12:26:30 2011 -0400

    Export filter conditions for anonymous db ranges.

diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 8c56c32..95b1848 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -647,13 +647,219 @@ private:
 
         SvXMLElementExport aElemDR(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True);
 
-        writeSheetFilter(rData);
+        writeImport(rData);
+        writeFilter(rData);
+        writeSort(rData);
         writeSubtotals(rData);
     }
 
-    void writeSheetFilter(const ScDBData& rData)
+    void writeImport(const ScDBData& rData)
     {
+    }
+
+    void writeSort(const ScDBData& rData)
+    {
+    }
+
+    OUString getOperatorXML(const ScQueryEntry& rEntry, bool bRegExp) const
+    {
+
+        switch (rEntry.eOp)
+        {
+            case SC_BEGINS_WITH:
+                return GetXMLToken(XML_BEGINS_WITH);
+            case SC_BOTPERC:
+                return GetXMLToken(XML_BOTTOM_PERCENT);
+            case SC_BOTVAL:
+                return GetXMLToken(XML_BOTTOM_VALUES);
+            case SC_CONTAINS:
+                return GetXMLToken(XML_CONTAINS);
+            case SC_DOES_NOT_BEGIN_WITH:
+                return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
+            case SC_DOES_NOT_CONTAIN:
+                return GetXMLToken(XML_DOES_NOT_CONTAIN);
+            case SC_DOES_NOT_END_WITH:
+                return GetXMLToken(XML_DOES_NOT_END_WITH);
+            case SC_ENDS_WITH:
+                return GetXMLToken(XML_ENDS_WITH);
+            case SC_EQUAL:
+                if (!rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING)
+                {
+                    if (rEntry.nVal == SC_EMPTYFIELDS)
+                        return GetXMLToken(XML_EMPTY);
+                    else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+                        return GetXMLToken(XML_NOEMPTY);
+                }
+                if (bRegExp)
+                    return GetXMLToken(XML_MATCH);
+                else
+                    return OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+            case SC_GREATER:
+                return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+            case SC_GREATER_EQUAL:
+                return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+            case SC_LESS:
+                return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+            case SC_LESS_EQUAL:
+                return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+            case SC_NOT_EQUAL:
+                if (bRegExp)
+                    return GetXMLToken(XML_NOMATCH);
+                else
+                    return OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+            case SC_TOPPERC:
+                return GetXMLToken(XML_TOP_PERCENT);
+            case SC_TOPVAL:
+                return GetXMLToken(XML_TOP_VALUES);
+            default:
+                ;
+        }
+        return OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+    }
+
+    void writeCondition(const ScQueryEntry& rEntry, bool bCaseSens, bool bRegExp)
+    {
+        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(rEntry.nField));
+        if (bCaseSens)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+        if (rEntry.bQueryByString)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, *rEntry.pStr);
+        else
+        {
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+            OUStringBuffer aBuf;
+            mrExport.GetMM100UnitConverter().convertDouble(aBuf, rEntry.nVal);
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aBuf.makeStringAndClear());
+        }
+
+        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(rEntry, bRegExp));
+        SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
+    }
+
+    void writeFilter(const ScDBData& rData)
+    {
+        ScQueryParam aParam;
+        rData.GetQueryParam(aParam);
+        size_t nCount = 0;
+        for (size_t n = aParam.GetEntryCount(); nCount < n; ++nCount)
+        {
+            if (!aParam.GetEntry(nCount).bDoQuery)
+                break;
+        }
+
+        if (!nCount)
+            // No filter criteria to save. Bail out.
+            return;
+
+        if (!aParam.bInplace)
+        {
+            OUString aAddrStr;
+            ScRangeStringConverter::GetStringFromAddress(
+                aAddrStr, ScAddress(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab), mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aAddrStr);
+        }
+
+        ScRange aAdvSource;
+        if (rData.GetAdvancedQuerySource(aAdvSource))
+        {
+            OUString aAddrStr;
+            ScRangeStringConverter::GetStringFromRange(
+                aAddrStr, aAdvSource, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, aAddrStr);
+        }
+
+        if (!aParam.bDuplicate)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
 
+        SvXMLElementExport aElemF(mrExport, XML_NAMESPACE_TABLE, XML_FILTER, true, true);
+
+        bool bAnd = false;
+        bool bOr = false;
+
+        for (size_t i = 0; i < nCount; ++i)
+        {
+            const ScQueryEntry& rEntry = aParam.GetEntry(i);
+            if (rEntry.eConnect == SC_AND)
+                bAnd = true;
+            else
+                bOr = true;
+        }
+
+        if (bOr && !bAnd)
+        {
+            SvXMLElementExport aElemOr(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
+            for (size_t i = 0; i < nCount; ++i)
+                writeCondition(aParam.GetEntry(i), aParam.bCaseSens, aParam.bRegExp);
+        }
+        else if (bAnd && !bOr)
+        {
+            SvXMLElementExport aElemAnd(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, true, true);
+            for (size_t i = 0; i < nCount; ++i)
+                writeCondition(aParam.GetEntry(i), aParam.bCaseSens, aParam.bRegExp);
+        }
+        else if (nCount == 1)
+        {
+            writeCondition(aParam.GetEntry(0), aParam.bCaseSens, aParam.bRegExp);
+        }
+        else
+        {
+            SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
+            ScQueryEntry aPrevEntry = aParam.GetEntry(0);
+            ScQueryConnect eConnect = aParam.GetEntry(1).eConnect;
+            bool bOpenAndElement = false;
+            OUString aName = mrExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
+
+            if (eConnect == SC_AND)
+            {
+                mrExport.StartElement(aName, true);
+                bOpenAndElement = true;
+            }
+            else
+                bOpenAndElement = false;
+
+            for (size_t i = 1; i < nCount; ++i)
+            {
+                const ScQueryEntry& rEntry = aParam.GetEntry(i);
+                if (eConnect != rEntry.eConnect)
+                {
+                    eConnect = rEntry.eConnect;
+                    if (rEntry.eConnect == SC_AND)
+                    {
+                        mrExport.StartElement(aName, true );
+                        bOpenAndElement = true;
+                        writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                        aPrevEntry = rEntry;
+                        if (i == nCount - 1)
+                        {
+                            writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                            mrExport.EndElement(aName, true);
+                            bOpenAndElement = false;
+                        }
+                    }
+                    else
+                    {
+                        writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                        aPrevEntry = rEntry;
+                        if (bOpenAndElement)
+                        {
+                            mrExport.EndElement(aName, true);
+                            bOpenAndElement = false;
+                        }
+                        if (i == nCount - 1)
+                            writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                    }
+                }
+                else
+                {
+                    writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                    aPrevEntry = rEntry;
+                    if (i == nCount - 1)
+                        writeCondition(aPrevEntry, aParam.bCaseSens, aParam.bRegExp);
+                }
+            }
+            if(bOpenAndElement)
+                mrExport.EndElement(aName, true);
+        }
     }
 
     void writeSubtotals(const ScDBData& rData)
commit 17372f17a6f8203f5b52ac6c2a19f80e76152b12
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Mar 31 00:24:36 2011 -0400

    First cut on getting ODS import/export of sheet-local anonymous ranges.
    
    The punch lines is that we don't use UNO API to handle sheet-local
    anonymous ranges during ODS import and export.  Eventually we should
    import the named database ranges using the internal API too, but
    for now we keep the current code (that uses the UNO API) for those.

diff --git a/sc/inc/globalnames.hxx b/sc/inc/globalnames.hxx
index 6b5e176..ae30bc1 100644
--- a/sc/inc/globalnames.hxx
+++ b/sc/inc/globalnames.hxx
@@ -29,6 +29,6 @@
 #define __SC_GLOBALNAMES_HXX__
 
 #define STR_DB_LOCAL_NONAME  "__Anonymous_Sheet_DB__"
-#define STR_DB_GLOBAL_NONAME "unnamed"
+#define STR_DB_GLOBAL_NONAME "__Anonymous_DB__"
 
 #endif
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 3131bc2..8c56c32 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -48,6 +48,7 @@
 #include "XMLExportSharedData.hxx"
 #include "rangeutl.hxx"
 #include "subtotalparam.hxx"
+#include "queryparam.hxx"
 
 #include <com/sun/star/sheet/DataImportMode.hpp>
 #include <com/sun/star/table/TableSortField.hpp>
@@ -59,6 +60,8 @@
 #include <tools/debug.hxx>
 #include <comphelper/extract.hxx>
 
+#include <map>
+
 //! not found in unonames.hxx
 #define SC_USERLIST "UserList"
 #define SC_SORTASCENDING "SortAscending"
@@ -67,6 +70,8 @@
 
 using namespace com::sun::star;
 using namespace xmloff::token;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
 
 ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport)
     : rExport(rTempExport),
@@ -569,11 +574,182 @@ void ScXMLExportDatabaseRanges::WriteSubTotalDescriptor(const com::sun::star::un
     }
 }
 
+namespace {
+
+class WriteDatabaseRange : public ::std::unary_function<ScDBData, void>
+{
+public:
+    WriteDatabaseRange(ScXMLExport& rExport, ScDocument* pDoc) :
+        mrExport(rExport), mpDoc(pDoc), mnCounter(0) {}
+
+    void operator() (const ::std::pair<SCTAB, const ScDBData*>& r)
+    {
+        // name
+        OUStringBuffer aBuf;
+        aBuf.appendAscii(STR_DB_LOCAL_NONAME);
+        aBuf.append(static_cast<sal_Int32>(r.first)); // appended number equals sheet index on import.
+
+        write(aBuf.makeStringAndClear(), *r.second);
+    }
+
+    void operator() (const ScDBData& rData)
+    {
+        // name
+        OUStringBuffer aBuf;
+        aBuf.appendAscii(STR_DB_GLOBAL_NONAME);
+        aBuf.append(++mnCounter); // 1-based, for entirely arbitrary reasons.  The numbers are ignored on import.
+
+        write(aBuf.makeStringAndClear(), rData);
+    }
+
+private:
+    void write(const OUString& rName, const ScDBData& rData)
+    {
+        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rName);
+
+        // range
+        ScRange aRange;
+        rData.GetArea(aRange);
+        OUString aRangeStr;
+        ScRangeStringConverter::GetStringFromRange(
+            aRangeStr, aRange, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+        mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aRangeStr);
+
+        // various boolean flags.
+        if (rData.HasImportSelection())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
+        if (rData.HasAutoFilter())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE);
+        if (rData.IsKeepFmt())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE);
+        if (rData.IsDoSize())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE);
+        if (rData.IsStripData())
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE);
+
+        ScQueryParam aQueryParam;
+        rData.GetQueryParam(aQueryParam);
+        if (!aQueryParam.bHasHeader)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE);
+
+        ScSortParam aSortParam;
+        rData.GetSortParam(aSortParam);
+        if (!aSortParam.bByRow)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN);
+
+        sal_Int32 nRefresh = rData.GetRefreshDelay();
+        if (nRefresh)
+        {
+            OUStringBuffer aBuf;
+            SvXMLUnitConverter::convertTime(aBuf, static_cast<double>(nRefresh) / 86400.0);
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, aBuf.makeStringAndClear());
+        }
+
+        SvXMLElementExport aElemDR(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True);
+
+        writeSheetFilter(rData);
+        writeSubtotals(rData);
+    }
+
+    void writeSheetFilter(const ScDBData& rData)
+    {
+
+    }
+
+    void writeSubtotals(const ScDBData& rData)
+    {
+        ScSubTotalParam aParam;
+        rData.GetSubTotalParam(aParam);
+
+        if (!aParam.bIncludePattern)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+
+        if (aParam.bPagebreak)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
+
+        if (aParam.bCaseSens)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+
+        SvXMLElementExport aElemSTRs(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, sal_True, sal_True);
+
+        if (aParam.bDoSort)
+        {
+            if (!aParam.bAscending)
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+
+            if (aParam.bUserDef)
+            {
+                OUStringBuffer aBuf;
+                aBuf.appendAscii(SC_USERLIST);
+                aBuf.append(static_cast<sal_Int32>(aParam.nUserIndex));
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
+            }
+            SvXMLElementExport aElemSGs(mrExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, sal_True, sal_True);
+        }
+
+        for (size_t i = 0; i < MAXSUBTOTAL; ++i)
+        {
+            if (!aParam.bGroupActive[i])
+                // We're done!
+                break;
+
+            sal_Int32 nFieldCol = static_cast<sal_Int32>(aParam.nField[i]);
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nFieldCol));
+            SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True);
+
+            SCCOL nCount = aParam.nSubTotals[i];
+            for (SCCOL j = 0; j < nCount; ++j)
+            {
+                sal_Int32 nCol = static_cast<sal_Int32>(aParam.pSubTotals[i][j]);
+                ScSubTotalFunc eFunc = aParam.pFunctions[i][j];
+
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nCol));
+                OUString aFuncStr;
+                ScXMLConverter::GetStringFromFunction(aFuncStr, eFunc);
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, aFuncStr);
+
+                SvXMLElementExport aElemSTF(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, sal_True, sal_True);
+            }
+        }
+    }
+
+private:
+    ScXMLExport& mrExport;
+    ScDocument* mpDoc;
+    sal_Int32 mnCounter;
+};
+
+}
+
 void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc)
 {
+    typedef ::std::map<SCTAB, const ScDBData*> SheetLocalDBs;
+
     pDoc = rExport.GetDocument();
     if (pDoc)
     {
+        // Get sheet-local anonymous ranges.
+        SCTAB nTabCount = pDoc->GetTableCount();
+        SheetLocalDBs aSheetDBs;
+        for (SCTAB i = 0; i < nTabCount; ++i)
+        {
+            const ScDBData* p = pDoc->GetAnonymousDBData(i);
+            if (p)
+                aSheetDBs.insert(SheetLocalDBs::value_type(i, p));
+        }
+
+        bool bHasRanges = !aSheetDBs.empty();
+
+        // See if we have global ranges.
+        ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+        if (pDBCollection && pDBCollection->GetCount() > 0)
+            bHasRanges = true;
+
+        if (!bHasRanges)
+            // No ranges to export. Bail out.
+            return;
+
+        SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, sal_True, sal_True);
         uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
         if (xPropertySet.is())
         {
@@ -585,37 +761,22 @@ void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::R
                 sal_Int32 nDatabaseRangesCount = aRanges.getLength();
                 if (nDatabaseRangesCount > 0)
                 {
-                    SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, sal_True, sal_True);
                     for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
                     {
                         rtl::OUString sDatabaseRangeName(aRanges[i]);
                         uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
                         if (xDatabaseRange.is())
                         {
-                            rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sDatabaseRangeName);
+                            rtl::OUString sOUUnbenannt (ScGlobal::GetRscString(STR_DB_NONAME));
+                            if (sOUUnbenannt != sDatabaseRangeName)
+                                rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sDatabaseRangeName);
                             table::CellRangeAddress aRangeAddress(xDatabaseRange->getDataArea());
                             rtl::OUString sOUAddress;
                             ScRangeStringConverter::GetStringFromRange( sOUAddress, aRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO );
                             rExport.AddAttribute (XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUAddress);
-                            ScDBCollection* pDBCollection = pDoc->GetDBCollection();
-
-                            ScDBData* pDBData= NULL;
-                            if (sDatabaseRangeName.match(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME))))
-                            {
-                                rtl::OUString aDBNoName = sDatabaseRangeName.replaceAt(0,rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)).getLength(),rtl::OUString());
-                                SCTAB nTab = aDBNoName.toInt32();;
-                                pDBData=pDoc->GetAnonymousDBData(nTab);
-                            }
-                            else
-                            {
-                                sal_uInt16 nIndex;
-                                pDBCollection->SearchName(sDatabaseRangeName, nIndex);
-                                pDBData = (*pDBCollection)[nIndex];
-                            }
-
-                            if (!pDBData)
-                                continue;
-
+                            sal_uInt16 nIndex;
+                            pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+                            ScDBData* pDBData = (*pDBCollection)[nIndex];
                             if (pDBData->HasImportSelection())
                                 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
                             if (pDBData->HasAutoFilter())
@@ -679,6 +840,10 @@ void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::R
                 }
             }
         }
+
+        WriteDatabaseRange func(rExport, pDoc);
+        // Write sheet-local ranges.
+        ::std::for_each(aSheetDBs.begin(), aSheetDBs.end(), func);
     }
 }
 
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index 9e1fd6b..c9dad19 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -63,12 +63,15 @@
 #include <com/sun/star/uno/RuntimeException.hpp>
 #include <com/sun/star/xml/sax/XLocator.hpp>
 
+#include <memory>
+
 #define SC_ENABLEUSERSORTLIST	"EnableUserSortList"
 #define SC_USERSORTLISTINDEX	"UserSortListIndex"
 #define SC_USERLIST				"UserList"
 
 using namespace com::sun::star;
 using namespace xmloff::token;
+using ::rtl::OUString;
 
 //------------------------------------------------------------------
 
@@ -146,7 +149,8 @@ ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
     bFilterIsCaseSensitive(false),
     bFilterSkipDuplicates(false),
     bFilterUseRegularExpressions(false),
-    bFilterConditionSourceRange(false)
+    bFilterConditionSourceRange(false),
+    meRangeType(GlobalNamed)
 {
     nSourceType = sheet::DataImportMode_NONE;
     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
@@ -216,6 +220,9 @@ ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
             break;
         }
     }
+
+    if (sDatabaseRangeName.matchAsciiL(STR_DB_LOCAL_NONAME, strlen(STR_DB_LOCAL_NONAME)))
+        meRangeType = SheetAnonymous;
 }
 
 ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
@@ -278,13 +285,113 @@ SvXMLImportContext *ScXMLDatabaseRangeContext::CreateChildContext( sal_uInt16 nP
     return pContext;
 }
 
+ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
+{
+    ScDocument* pDoc = GetScImport().GetDocument();
+
+    sal_Int32 nOffset = 0;
+    ScRange aRange;
+    if (!ScRangeStringConverter::GetRangeFromString(aRange, sRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset))
+        return NULL;
+
+    ::std::auto_ptr<ScDBData> pData(
+        new ScDBData(rName, aRange.aStart.Tab(), aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row()));
+
+    pData->SetAutoFilter(bAutoFilter);
+    pData->SetKeepFmt(bKeepFormats);
+    pData->SetDoSize(bMoveCells);
+    pData->SetStripData(bStripData);
+
+    // TODO: Properly import other paramters as well.
+
+    if (bContainsSubTotal)
+    {
+        ScSubTotalParam aParam;
+        aParam.bIncludePattern = bSubTotalsBindFormatsToContent;
+        aParam.bUserDef = bSubTotalsEnabledUserList;
+        aParam.nUserIndex = nSubTotalsUserListIndex;
+        aParam.bPagebreak = bSubTotalsInsertPageBreaks;
+        aParam.bCaseSens = bSubTotalsIsCaseSensitive;
+        aParam.bDoSort = bSubTotalsSortGroups;
+        aParam.bAscending = bSubTotalsAscending;
+        aParam.bUserDef = bSubTotalsEnabledUserList;
+        aParam.nUserIndex = nSubTotalsUserListIndex;
+        std::vector <ScSubTotalRule>::iterator itr = aSubTotalRules.begin(), itrEnd = aSubTotalRules.end();
+        for (size_t nPos = 0; itr != itrEnd; ++itr, ++nPos)
+        {
+            if (nPos >= MAXSUBTOTAL)
+                break;
+
+            const uno::Sequence<sheet::SubTotalColumn>& rColumns = itr->aSubTotalColumns;
+            sal_Int32 nColCount = rColumns.getLength();
+            sal_Int16 nGroupColumn = itr->nSubTotalRuleGroupFieldNumber;
+            aParam.bGroupActive[nPos] = true;
+            aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
+
+            SCCOL nCount = static_cast<SCCOL>(nColCount);
+            aParam.nSubTotals[nPos] = nCount;
+            if (nCount != 0)
+            {
+                aParam.pSubTotals[nPos] = new SCCOL[nCount];
+                aParam.pFunctions[nPos] = new ScSubTotalFunc[nCount];
+
+                const sheet::SubTotalColumn* pAry = rColumns.getConstArray();
+                for (SCCOL i = 0; i < nCount; ++i)
+                {
+                    aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
+                    aParam.pFunctions[nPos][i] =
+                        ScDataUnoConversion::GeneralToSubTotal( pAry[i].Function );
+                }
+            }
+            else
+            {
+                aParam.pSubTotals[nPos] = NULL;
+                aParam.pFunctions[nPos] = NULL;
+            }
+        }
+
+        pData->SetSubTotalParam(aParam);
+    }
+
+    return pData.release();
+}
+
 void ScXMLDatabaseRangeContext::EndElement()
 {
+    ScDocument* pDoc = GetScImport().GetDocument();
+    if (!pDoc)
+        return;
+
+    if (meRangeType == SheetAnonymous)
+    {
+        OUString aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
+        ::std::auto_ptr<ScDBData> pData(ConvertToDBData(aName));
+
+        if (pData.get())
+        {
+            // Infer sheet index from the name.
+            OUString aStrNum = sDatabaseRangeName.copy(aName.getLength());
+            SCTAB nTab = static_cast<SCTAB>(aStrNum.toInt32());
+
+            if (bAutoFilter)
+            {
+                // Set autofilter flags so that the buttons get displayed.
+                ScRange aRange;
+                pData->GetArea(aRange);
+                pDoc->ApplyFlagsTab(
+                    aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
+                    aRange.aStart.Tab(), SC_MF_AUTO);
+            }
+
+            pDoc->SetAnonymousDBData(nTab, pData.release());
+        }
+        return;
+    }
+
     if (GetScImport().GetModel().is())
     {
         uno::Reference <beans::XPropertySet> xPropertySet( GetScImport().GetModel(), uno::UNO_QUERY );
-        ScDocument* pDoc = GetScImport().GetDocument();
-        if (pDoc && xPropertySet.is())
+        if (xPropertySet.is())
         {
             uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
             if (xDatabaseRanges.is())
@@ -345,35 +452,10 @@ void ScXMLDatabaseRangeContext::EndElement()
                                 else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE)))
                                     aImportDescriptor[i].Value <<= bNative;
                             }
-                            ScDBData* pDBData = NULL;
                             ScDBCollection* pDBCollection = pDoc->GetDBCollection();
-                            rtl::OUString aLocalNoName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
-                            rtl::OUString aGlobalNoName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_GLOBAL_NONAME));
-                            if (sDatabaseRangeName.match(aLocalNoName)||sDatabaseRangeName==aGlobalNoName)
-                            {
-                                SCTAB nTab = 0;
-                                if (sDatabaseRangeName==aGlobalNoName)//convert old global anonymous db ranges to new sheet local ones
-                                {
-                                    nTab = static_cast<SCTAB> (aCellRangeAddress.Sheet);
-                                }
-                                else
-                                {
-                                    rtl::OUString aDBNoName(sDatabaseRangeName);
-                                    aDBNoName = aDBNoName.replaceAt(0,aLocalNoName.getLength(),rtl::OUString());
-                                    nTab = aDBNoName.toInt32();
-                                }
-                                pDBData = pDoc->GetAnonymousDBData(nTab);
-                            }
-                            else
-                            {
-                                sal_uInt16 nIndex;
-                                pDBCollection->SearchName(sDatabaseRangeName, nIndex);
-                                pDBData = (*pDBCollection)[nIndex];
-                            }
-
-                            if (!pDBData)
-                                return;
-
+                            sal_uInt16 nIndex;
+                            pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+                            ScDBData* pDBData = (*pDBCollection)[nIndex];
                             pDBData->SetImportSelection(bIsSelection);
                             pDBData->SetAutoFilter(bAutoFilter);
                             if (bAutoFilter)
diff --git a/sc/source/filter/xml/xmldrani.hxx b/sc/source/filter/xml/xmldrani.hxx
index 1ba2eb9..80b6524 100644
--- a/sc/source/filter/xml/xmldrani.hxx
+++ b/sc/source/filter/xml/xmldrani.hxx
@@ -39,6 +39,7 @@
 #include <com/sun/star/table/CellRangeAddress.hpp>
 #include <com/sun/star/table/TableOrientation.hpp>
 
+class ScDBData;
 class ScXMLImport;
 

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list