[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