[ooo-build-commit] .: 2 commits - sc/inc sc/source

Fridrich Strba fridrich at kemper.freedesktop.org
Thu Sep 16 01:16:48 PDT 2010


 sc/inc/table.hxx                 |   10 +
 sc/source/core/data/column.cxx   |   19 ++
 sc/source/core/data/column3.cxx  |   14 +-
 sc/source/core/data/table6.cxx   |  269 +++++++++++++++++++++++++++++++++++++++
 sc/source/ui/docshell/docsh8.cxx |   60 ++++++++
 sc/source/ui/view/tabvwsha.cxx   |    7 -
 6 files changed, 374 insertions(+), 5 deletions(-)

New commits:
commit 8c05a4f470c292245e298e4b216036a558babb16
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 10:13:57 2010 +0200

    calc-filter-dbf-precision.diff: import/export precision of value cells fix
    
    n#479025, i#101045

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index e93fd9f..a44a7d1 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1968,8 +1968,18 @@ xub_StrLen ScColumn::GetMaxNumberStringLen(
                 if ( nLen )
                 {
                     if ( nFormat )
-                    {   // more decimals than standard?
-                        sal_uInt16 nPrec = pNumFmt->GetFormatPrecision( nFormat );
+                    {
+                        const SvNumberformat* pEntry = pNumFmt->GetEntry( nFormat );
+                        sal_uInt16 nPrec;
+                        if (pEntry)
+                        {
+                            BOOL bThousand, bNegRed;
+                            USHORT nLeading;
+                            pEntry->GetFormatSpecialInfo(bThousand, bNegRed, nPrec, nLeading);
+                        }
+                        else
+                            nPrec = pNumFmt->GetFormatPrecision( nFormat );
+
                         if ( nPrec != SvNumberFormatter::UNLIMITED_PRECISION && nPrec > nPrecision )
                             nPrecision = nPrec;
                     }
diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx
index 589b0c6..75a0756 100644
--- a/sc/source/ui/docshell/docsh8.cxx
+++ b/sc/source/ui/docshell/docsh8.cxx
@@ -78,8 +78,16 @@
 #include "dbdocutl.hxx"
 #include "dociter.hxx"
 #include "globstr.hrc"
+#include "svl/zformat.hxx"
+#include "svl/intitem.hxx"
+#include "patattr.hxx"
+#include "scitems.hxx"
+#include "docpool.hxx"
+
+#include <vector>
 
 using namespace com::sun::star;
+using ::std::vector;
 
 // -----------------------------------------------------------------------
 
@@ -246,6 +254,53 @@ BOOL ScDocShell::IsDocument( const INetURLObject& rURL )
 
 // -----------------------------------------------------------------------
 
+static void lcl_setScalesToColumns(ScDocument& rDoc, const vector<long>& rScales)
+{
+    SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
+    if (!pFormatter)
+        return;
+
+    SCCOL nColCount = static_cast<SCCOL>(rScales.size());
+    for (SCCOL i = 0; i < nColCount; ++i)
+    {
+        if (rScales[i] < 0)
+            continue;
+
+        sal_uInt32 nOldFormat;
+        rDoc.GetNumberFormat(static_cast<SCCOL>(i), 0, 0, nOldFormat);
+        const SvNumberformat* pOldEntry = pFormatter->GetEntry(nOldFormat);
+        if (!pOldEntry)
+            continue;
+
+        LanguageType eLang = pOldEntry->GetLanguage();
+        BOOL bThousand, bNegRed;
+        USHORT nPrecision, nLeading;
+        pOldEntry->GetFormatSpecialInfo(bThousand, bNegRed, nPrecision, nLeading);
+
+        nPrecision = static_cast<USHORT>(rScales[i]);
+        String aNewPicture;
+        pFormatter->GenerateFormat(aNewPicture, nOldFormat, eLang,
+                                   bThousand, bNegRed, nPrecision, nLeading);
+
+        sal_uInt32 nNewFormat = pFormatter->GetEntryKey(aNewPicture, eLang);
+        if (nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+        {
+            xub_StrLen nErrPos = 0;
+            short nNewType = 0;
+            bool bOk = pFormatter->PutEntry(
+                aNewPicture, nErrPos, nNewType, nNewFormat, eLang);
+
+            if (!bOk)
+                continue;
+        }
+
+        ScPatternAttr aNewAttrs( rDoc.GetPool() );
+        SfxItemSet& rSet = aNewAttrs.GetItemSet();
+        rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat) );
+        rDoc.ApplyPatternAreaTab(static_cast<SCCOL>(i), 0, static_cast<SCCOL>(i), MAXROW, 0, aNewAttrs);
+    }
+}
+
 ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
                                 BOOL bSimpleColWidth[MAXCOLCOUNT] )
 {
@@ -327,6 +382,7 @@ ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
         //	read column names
         //!	add type descriptions
 
+        vector<long> aScales(nColCount, -1);
         for (i=0; i<nColCount; i++)
         {
             String aHeader = xMeta->getColumnLabel( i+1 );
@@ -356,6 +412,7 @@ ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
                                         nPrec, nScale ) );
                         aHeader += ',';
                         aHeader += String::CreateFromInt32( nScale );
+                        aScales[i] = nScale;
                     }
                     break;
             }
@@ -363,6 +420,8 @@ ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
             aDocument.SetString( static_cast<SCCOL>(i), 0, 0, aHeader );
         }
 
+        lcl_setScalesToColumns(aDocument, aScales);
+
         SCROW nRow = 1;		// 0 is column titles
         BOOL bEnd = FALSE;
         while ( !bEnd && xRowSet->next() )
@@ -486,7 +545,6 @@ void lcl_GetColumnTypes( ScDocShell& rDocShell,
                         break;
                     case 'N' :
                         nDbType = sdbc::DataType::DECIMAL;
-                        bTypeDefined = TRUE;
                         break;
                 }
                 if ( bTypeDefined && !nFieldLen && nToken > 2 )
commit 0835648ea0ceaa1f35ee601fd4b958f1847940b2
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 10:08:52 2010 +0200

    calc-find-replace-empty-cells-sc.diff: Support find and replace empty cells
    
    i#49380, n#415352

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 96a9391..746545d 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -820,6 +820,16 @@ private:
     BOOL		SearchAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark);
     BOOL		ReplaceAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
                                 ScDocument* pUndoDoc);
+    bool        SearchAndReplaceEmptyCells(
+                    const SvxSearchItem& rSearchItem,
+                    SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
+                    String& rUndoStr, ScDocument* pUndoDoc);
+    bool        SearchRangeForEmptyCell(const ScRange& rRange,
+                    const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+                    String& rUndoStr, ScDocument* pUndoDoc);
+    bool        SearchRangeForAllEmptyCells(const ScRange& rRange,
+                    const SvxSearchItem& rSearchItem, ScMarkData& rMark,
+                    String& rUndoStr, ScDocument* pUndoDoc);
 
                                 // benutzen globalen SortParam:
     BOOL		IsSorted(SCCOLROW nStart, SCCOLROW nEnd);
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 2f49e98..622ef83 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1354,7 +1354,24 @@ void ScColumn::CopyToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarke
                     CloneCell( i, nFlags, *rColumn.pDocument, aDestPos );
 
                 if (pNew)
-                    rColumn.Insert(pItems[i].nRow, pNew);
+                {
+                    // Special case to allow removing of cell instances.  A
+                    // string cell with empty content is used to indicate an
+                    // empty cell.
+                    if (pNew->GetCellType() == CELLTYPE_STRING)
+                    {
+                        String aStr;
+                        static_cast<ScStringCell*>(pNew)->GetString(aStr);
+                        if (aStr.Len() == 0)
+                            // A string cell with empty string.  Delete the cell itself.
+                            rColumn.Delete(pItems[i].nRow);
+                        else
+                            // non-empty string cell
+                            rColumn.Insert(pItems[i].nRow, pNew);
+                    }
+                    else
+                        rColumn.Insert(pItems[i].nRow, pNew);
+                }
             }
         }
     }
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index 381cd9c..7cd3057 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -49,6 +49,8 @@
 //--------------------------------------------------------------------------
 
 
+using ::com::sun::star::util::SearchOptions;
+
 BOOL lcl_GetTextWithBreaks( const ScEditCell& rCell, ScDocument* pDoc, String& rVal )
 {
     //	TRUE = more than 1 paragraph
@@ -657,6 +659,12 @@ BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem,
             com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
             aSearchOptions.Locale = *ScGlobal::GetLocale();
 
+            if (!aSearchOptions.searchString.getLength())
+            {
+                // Search for empty cells.
+                return SearchAndReplaceEmptyCells(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
+            }
+
             //	#107259# reflect UseAsianOptions flag in SearchOptions
             //	(use only ignore case and width if asian options are disabled).
             //	This is also done in SvxSearchDialog CommandHdl, but not in API object.
@@ -683,8 +691,269 @@ BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem,
     return bFound;
 }
 
+bool ScTable::SearchAndReplaceEmptyCells(
+    const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
+    String& rUndoStr, ScDocument* pUndoDoc)
+{
+    SCCOL nColStart, nColEnd;
+    SCROW nRowStart, nRowEnd;
+    GetFirstDataPos(nColStart, nRowStart);
+    GetLastDataPos(nColEnd, nRowEnd);
+
+    ScRangeList aRanges;
+    aRanges.Append(ScRange(nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab));
+
+    if (rSearchItem.GetSelection())
+    {
+        // current selection only.
+        if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+            // There is no selection.  Bail out.
+            return false;
+
+        ScRangeList aMarkedRanges, aNewRanges;
+        rMark.FillRangeListWithMarks(&aMarkedRanges, true);
+        for (ScRangePtr p = aMarkedRanges.First(); p; p = aMarkedRanges.Next())
+        {
+            if (p->aStart.Col() > nColEnd || p->aStart.Row() > nRowEnd)
+                // This range is outside the data area.  Skip it.
+                continue;
+
+            // Shrink the range into data area only.
+            if (p->aStart.Col() < nColStart)
+                p->aStart.SetCol(rCol);
+            if (p->aStart.Row() < nRowStart)
+                p->aStart.SetRow(rRow);
+
+            if (p->aEnd.Col() > nColEnd)
+                p->aEnd.SetCol(nColEnd);
+            if (p->aEnd.Row() > nRowEnd)
+                p->aEnd.SetRow(nRowEnd);
+
+            aNewRanges.Append(*p);
+        }
+        aRanges = aNewRanges;
+    }
+
+    sal_uInt16 nCommand = rSearchItem.GetCommand();
+    if (nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE)
+    {
+        if (rSearchItem.GetBackward())
+        {
+            for (ScRangePtr p = aRanges.Last(); p; p = aRanges.Prev())
+            {
+                if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr, pUndoDoc))
+                    return true;
+            }
+        }
+        else
+        {
+            for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
+            {
+                if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr, pUndoDoc))
+                    return true;
+            }
+        }
+    }
+    else if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
+    {
+        bool bFound = false;
+        ScMarkData aNewMark(rMark);
+        aNewMark.ResetMark();
+        for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
+            bFound |= SearchRangeForAllEmptyCells(*p, rSearchItem, aNewMark, rUndoStr, pUndoDoc);
+        rMark = aNewMark;
+        return bFound;
+    }
+    return false;
+}
+
+bool ScTable::SearchRangeForEmptyCell(
+    const ScRange& rRange, const SvxSearchItem& rSearchItem,
+    SCCOL& rCol, SCROW& rRow, String& rUndoStr, ScDocument* /*pUndoDoc*/)
+{
+    sal_uInt16 nCmd = rSearchItem.GetCommand();
+    if (rSearchItem.GetBackward())
+    {
+        // backward search
+        if (rSearchItem.GetRowDirection())
+        {
+            // row direction.
+            SCROW nBeginRow = rRange.aEnd.Row() > rRow ? rRow : rRange.aEnd.Row();
+            for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
+            {
+                SCCOL nBeginCol = rRange.aEnd.Col();
+                if (nRow == rRow && nBeginCol >= rCol)
+                    // always start from one cell before the cursor.
+                    nBeginCol = rCol - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+
+                for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
+                {
+                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+                    if (!pCell)
+                    {
+                        // empty cell found.
+                        rCol = nCol;
+                        rRow = nRow;
+                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+                            rSearchItem.GetReplaceString().Len())
+                        {
+                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+                            rUndoStr = String();
+                        }
+                        return true;
+                    }
+                }
+            }
+        }
+        else
+        {
+            // column direction.
+            SCCOL nBeginCol = rRange.aEnd.Col() > rCol ? rCol : rRange.aEnd.Col();
+            for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
+            {
+                SCROW nBeginRow = rRange.aEnd.Row();
+                if (nCol == rCol && nBeginRow >= rRow)
+                    // always start from one cell before the cursor.
+                    nBeginRow = rRow - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+                for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
+                {
+                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+                    if (!pCell)
+                    {
+                        // empty cell found.
+                        rCol = nCol;
+                        rRow = nRow;
+                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+                            rSearchItem.GetReplaceString().Len())
+                        {
+                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+                            rUndoStr = String();
+                        }
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        // forward search
+        if (rSearchItem.GetRowDirection())
+        {
+            // row direction.
+            SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
+            for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
+            {
+                SCCOL nBeginCol = rRange.aStart.Col();
+                if (nRow == rRow && nBeginCol <= rCol)
+                    // always start from one cell past the cursor.
+                    nBeginCol = rCol + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+                for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
+                {
+                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+                    if (!pCell)
+                    {
+                        // empty cell found.
+                        rCol = nCol;
+                        rRow = nRow;
+                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+                            rSearchItem.GetReplaceString().Len())
+                        {
+                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+                            rUndoStr = String();
+                        }
+                        return true;
+                    }
+                }
+            }
+        }
+        else
+        {
+            // column direction.
+            SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
+            for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
+            {
+                SCROW nBeginRow = rRange.aStart.Row();
+                if (nCol == rCol && nBeginRow <= rRow)
+                    // always start from one cell past the cursor.
+                    nBeginRow = rRow + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+                for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
+                {
+                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+                    if (!pCell)
+                    {
+                        // empty cell found.
+                        rCol = nCol;
+                        rRow = nRow;
+                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+                            rSearchItem.GetReplaceString().Len())
+                        {
+                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+                            rUndoStr = String();
+                        }
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
 
+bool ScTable::SearchRangeForAllEmptyCells(
+    const ScRange& rRange, const SvxSearchItem& rSearchItem, ScMarkData& rMark,
+    String& rUndoStr, ScDocument* pUndoDoc)
+{
+    bool bFound = false;
+    bool bReplace = (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) &&
+                    (rSearchItem.GetReplaceString().Len() > 0);
 
+    for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
+    {
+        if (aCol[nCol].IsEmptyData())
+        {
+            // The entire column is empty.  Add the whole column and move on.
+            rMark.SetMultiMarkArea(
+                ScRange(nCol, rRange.aStart.Row(), nTab, nCol, rRange.aEnd.Row(), nTab));
+            bFound = true;
 
+            if (bReplace)
+            {
+                const String& rNewStr = rSearchItem.GetReplaceString();
+                for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+                {
+                    aCol[nCol].Insert(nRow, new ScStringCell(rNewStr));
+                    if (pUndoDoc)
+                        // TODO: I'm using a string cell with empty content to
+                        // trigger deletion of cell instance on undo.  Maybe I
+                        // should create a new cell type for this?
+                        pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
+                }
+                rUndoStr = String();
+            }
+            continue;
+        }
 
+        for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+        {
+            ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+            if (!pCell)
+            {
+                // empty cell found
+                rMark.SetMultiMarkArea(ScRange(nCol, nRow, nTab));
+                bFound = true;
 
+                if (bReplace)
+                {
+                    aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+                    if (pUndoDoc)
+                        // TODO: I'm using a string cell with empty content to
+                        // trigger deletion of cell instance on undo.  Maybe I
+                        // should create a new cell type for this?
+                        pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
+                }
+            }
+        }
+    }
+    return bFound;
+}
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 436fe7e..9d12665 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -230,8 +230,13 @@ void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet )
                 break;
 
             case SID_SEARCH_ITEM:
-                rSet.Put( ScGlobal::GetSearchItem() );
+            {
+                SvxSearchItem aItem(ScGlobal::GetSearchItem()); // make a copy.
+                // Search on current selection if a range is marked.
+                aItem.SetSelection(rMark.IsMarked());
+                rSet.Put(aItem);
                 break;
+            }
 
             case SID_SEARCH_OPTIONS:
                 {


More information about the ooo-build-commit mailing list