[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 791 commits - apple_remote/source basctl/source basegfx/source basic/source bean/test boost/boost.3093.warnings.patch boost/boost.libcdr.warnings.patch.1 boost/UnpackedTarball_boost.mk bridges/inc bridges/test canvas/source chart2/CppunitTest_chart2_export.mk chart2/CppunitTest_chart2_exporttest.mk chart2/CppunitTest_chart2_import.mk chart2/CppunitTest_chart2_importtest.mk chart2/Module_chart2.mk chart2/qa chart2/source clucene/UnpackedTarball_clucene.mk codemaker/source comphelper/Library_comphelper.mk comphelper/source config_host/config_vclplug.h.in config_host.mk.in configmgr/source configure.ac connectivity/source cppcanvas/source cppuhelper/qa cppuhelper/source cui/source cui/uiconfig cui/UIConfig_cui.mk dbaccess/JunitTest_dbaccess_complex.mk dbaccess/JunitTest_dbaccess_unoapi.mk dbaccess/Library_dba.mk dbaccess/source desktop/Executable_oosplash.mk desktop/Library_sofficeapp.mk desktop/Package_branding_custom.mk desktop/Package_branding.mk desktop/Package_pagein_install.mk desktop/Package_scripts_install.mk desktop/source desktop/unx dictionaries distro-configs/LibreOfficeAndroid.conf distro-configs/LibreOfficeAndroidX86.conf distro-configs/LibreOfficeLinux.conf distro-configs/LibreOfficeOpenBSD.conf distro-configs/OxygenOfficeLinux.conf download.lst drawinglayer/source dtrans/source editeng/source embeddedobj/test eventattacher/source extensions/qa extensions/source external/wine extras/CustomTarget_autocorr.mk extras/Gallery_arrows.mk extras/Gallery_computers.mk extras/Gallery_diagrams.mk extras/Gallery_education.mk extras/Gallery_environment.mk extras/Gallery_finance.mk extras/Gallery_people.mk extras/Gallery_sound.mk extras/Gallery_symbols.mk extras/Gallery_transportation.mk extras/Gallery_txtshapes.mk extras/Module_extras.mk extras/Package_autocorr.mk extras/Package_gallmytheme.mk extras/Package_gallsound.mk extras/Package_gallsounds.mk extras/Package_gallsystem.mk extras/READ ME extras/source filter/source forms/source formula/source fpicker/source framework/inc framework/Library_fwk.mk framework/source framework/util harfbuzz/ExternalProject_harfbuzz.mk harfbuzz/harfbuzz-0.9.16-winxp.patch.1 harfbuzz/UnpackedTarball_harfbuzz.mk helpcontent2 i18nlangtag/source i18npool/source icon-themes/galaxy icon-themes/hicontrast icon-themes/tango icu/ExternalProject_icu.mk icu/icu4c-build.patch idlc/Executable_idlc.mk idlc/inc idlc/source include/basegfx include/comphelper include/drawinglayer include/editeng include/filter include/framework include/i18nlangtag include/jvmfwk include/linguistic include/osl include/rtl include/sal include/sfx2 include/shell include/svl include/svtools include/svx include/toolkit include/tools include/unoidl include/unotools include/vcl include/xmloff include/xmlreader instsetoo_native/CustomTarget_install.mk instsetoo_native/Package_config.mk instsetoo_native/Package_rdb.mk instsetoo_native/Package_setup.mk jurt/workbench jvm fwk/distributions jvmfwk/plugins l10ntools/inc l10ntools/source lcms2/ExternalPackage_lcms2.mk libcdr/ExternalPackage_libcdr.mk libcdr/ExternalProject_libcdr.mk libcdr/libcdr-0.0.13.patch libcdr/UnpackedTarball_libcdr.mk libcmis/libcmis-0.3.0.patch liblangtag/liblangtag-0.5.1-unistd.patch liblangtag/UnpackedTarball_langtag.mk libmariadb/mariadb-trunk-40.patch libmspub/ExternalPackage_libmspub.mk libmspub/ExternalProject_libmspub.mk libmwaw/ExternalPackage_libmwaw.mk libmwaw/libmwaw-0.1.7-autotools.patch libmwaw/libmwaw-0.1.8-cctype.patch libmwaw/libmwaw-0.1.9.patch.1 libmwaw/UnpackedTarball_libmwaw.mk Library_urelibs.mk libvisio/ExternalPackage_libvisio.mk libvisio/ExternalProject_libvisio.mk libwpd/ExternalPackage_libwpd.mk libxmlsec/xmlsec1-noverify.patch lingucomponent/source linguistic/inc linguistic/source linguistic/workben lotuswordpro/source Makefile.in moz/ExternalPackage_runtime.mk mysqlc/source nlpsolver/ThirdParty nss/ExternalProject_nss.mk nss/nss-3.13.5-zlib-we rror.patch odk/examples odk/source offapi/com offapi/type_reference offapi/UnoApi_offapi.mk officecfg/Configuration_officecfg.mk officecfg/files.mk officecfg/registry oovbaapi/ooo oox/source openssl/ExternalProject_openssl.mk padmin/Package_padmin.mk padmin/source padmin/uiconfig postprocess/CustomTarget_registry.mk python3/ExternalPackage_python3.mk python3/GeneratedPackage_python3.mk python3/Zip_PythonFramework.mk pyuno/CustomTarget_python_bin.mk pyuno/Package_python_bin.mk pyuno/Package_python_scripts_install.mk pyuno/source qadevOOo/runner qadevOOo/tests README.cross redland/ExternalProject_redland.mk redland/Library_raptor.mk registry/source reportdesign/source RepositoryExternal.mk Repository.mk RepositoryModule_build.mk rhino/OfficeScriptInfo.java ridljar/com rsc/source sal/Library_sal.mk sal/osl sal/qa sax/source sc/AllLangResTarget_sc.mk sc/inc sc/Library_sc.mk scp2/inc scp2/InstallModule_gnome.mk scp2/InstallModule_graphicfilter.mk scp2/InstallModule_ooo.mk scp2/Mo dule_scp2.mk scp2/source sc/qa scripting/Package_scriptproviderforpython.mk scripting/source sc/sdi sc/source sc/uiconfig sc/UIConfig_scalc.mk sc/util sd/CppunitTest_sd_import_tests.mk sd/CppunitTest_sd_regression_test.mk sdext/source sd/inc sd/Library_sd.mk sd/Module_sd.mk sd/qa sd/res sd/sdi sd/source sd/uiconfig sd/util setup_native/source sfx2/AllLangResTarget_sfx2.mk sfx2/doc sfx2/Library_sfx.mk sfx2/README sfx2/sdi sfx2/source sfx2/workben shell/Package_scripts_gnome.mk shell/Package_scripts_kde.mk shell/Package_scripts.mk shell/Package_senddoc.mk slideshow/source solenv/bin solenv/gbuild solenv/inc solenv/Package_gdb_install.mk soltools/Executable_cpp.mk soltools/Executable_makedepend.mk soltools/mkdepend soltools/Module_soltools.mk soltools/Package_inc.mk soltools/winunistd sot/source starmath/inc starmath/Library_sm.mk starmath/sdi starmath/source starmath/uiconfig stoc/source svl/AllLangResTarget_svl.mk svl/CppunitTest_svl_lngmisc.mk svl/Library_svl.mk svl/qa svl/R EADME svl/source svtools/inc svtools/source svx/AllLangResTarget_svx.mk svx/inc svx/Library_svxcore.mk svx/Library_svx.mk svx/sdi svx/source svx/util sw/AllLangResTarget_sw.mk sw/CppunitTest_sw_macros_test.mk swext/mediawiki sw/inc sw/Library_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/util sysui/CustomTarget_deb.mk sysui/CustomTarget_rpm.mk sysui/CustomTarget_share.mk sysui/CustomTarget_slackware.mk sysui/CustomTarget_solaris.mk sysui/desktop sysui/Package_desktop.mk sysui/Package_share.mk sysui/productlist.mk TEMPLATE.SOURCECODE.HEADER test/source tomcat/build.xml toolkit/source toolkit/test tools/source translations udkapi/com udkapi/type_reference udkapi/UnoApi_udkapi.mk unodevtools/source unoidl/README unoidl/source unotools/source vcl/aqua vcl/coretext vcl/generic vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_tde.mk vcl/qa vcl/source vcl/uiconfig vcl/unx vcl/win wizards/com wizards/source writerfilter/source xmloff/source xmlreader/source xmlsecurity/sour ce xmlsecurity/test_docs
Kohei Yoshida
kohei.yoshida at gmail.com
Mon May 20 17:27:18 PDT 2013
Rebased ref, commits from common ancestor:
commit f61aa0df67c440f9d201a0b10eccac9729ed7aca
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 19:21:21 2013 -0400
Rehash the 0.8.1 package due to a last minute oops.
Change-Id: Idea947e8b6674d436cc1a1d92f29279d2c03fc58
diff --git a/download.lst b/download.lst
index fea1f3e..f02392e 100644
--- a/download.lst
+++ b/download.lst
@@ -63,7 +63,7 @@ export LIBXML_TARBALL := 7740a8ec23878a2f50120e1faa2730f2-libxml2-2.7.6.tar.gz
export LIBXSLT_TARBALL := e61d0364a30146aaa3001296f853b2b9-libxslt-1.1.26.tar.gz
export LPSOLVE_TARBALL := 26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz
export MARIADB_TARBALL := 05f84c95b610c21c5fd510d10debcabf-mariadb-native-client-1.0.0.tar.bz2
-export MDDS_TARBALL := 5c7060bfa4ebb77b86026c268e9681fa-mdds_0.8.1.tar.bz2
+export MDDS_TARBALL := 08c85a6d6d793daee14e10e22eefdc4b-mdds_0.8.1.tar.bz2
export MYSQLCPPCONN_TARBALL := 0981bda6548a8c8233ffce2b6e4b2a23-mysql-connector-c++-1.1.0.tar.gz
export MYTHES_TARBALL := 46e92b68e31e858512b680b3b61dc4c1-mythes-1.2.3.tar.gz
export NEON_TARBALL := ff369e69ef0f0143beb5626164e87ae2-neon-0.29.5.tar.gz
commit fc3f0a25661e371f1f561ee21b8ba4c67a1a2173
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 18:23:10 2013 -0400
We don't need this patch anymore.
Change-Id: Id6b787096d15c40903661fa3d309e8131b655752
diff --git a/mdds/0001-Remove-disambiguation-of-a-integer-type.patch b/mdds/0001-Remove-disambiguation-of-a-integer-type.patch
deleted file mode 100644
index e23d057..0000000
--- a/mdds/0001-Remove-disambiguation-of-a-integer-type.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 46cf3188790b821b359e13b14e2211898ab2139b Mon Sep 17 00:00:00 2001
-From: Kohei Yoshida <kohei.yoshida at gmail.com>
-Date: Thu, 9 May 2013 14:48:41 -0400
-Subject: [PATCH] Remove disambiguation of a integer type.
-
----
- include/mdds/multi_type_vector_def.inl | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/include/mdds/multi_type_vector_def.inl b/include/mdds/multi_type_vector_def.inl
-index 2299a7b..f443e08 100644
---- a/include/mdds/multi_type_vector_def.inl
-+++ misc/build/mdds_0.8.0/include/mdds/multi_type_vector_def.inl
-@@ -1479,7 +1479,7 @@ multi_type_vector<_CellBlockFunc>::transfer_single_block(
-
- // Insert two new blocks below current.
- size_type blk2_size = blk_dest->m_size - dest_pos_in_block - len;
-- dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index+1, 2, NULL);
-+ dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index+1, 2u, NULL);
- dest.m_blocks[dest_block_index+1] = new block(len);
- dest.m_blocks[dest_block_index+2] = new block(blk2_size);
- blk_dest->m_size = dest_pos_in_block;
---
-1.8.0
-
diff --git a/mdds/UnpackedTarball_mdds.mk b/mdds/UnpackedTarball_mdds.mk
index 11a6a23..b33bc1b 100644
--- a/mdds/UnpackedTarball_mdds.mk
+++ b/mdds/UnpackedTarball_mdds.mk
@@ -17,7 +17,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,mdds,\
mdds/mdds_0.6.0.patch \
mdds/0001-Workaround-for-gcc-bug.patch \
mdds/mdds_0.7.0_unreachable_warning.patch.1 \
- mdds/0001-Remove-disambiguation-of-a-integer-type.patch \
))
# vim: set noet sw=4 ts=4:
commit 9785579ed0ec8e2e3e826c7e4cbbcaf51f8cb0d4
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 18:19:48 2013 -0400
Update mdds to 0.8.1.
Change-Id: If6c1a8a88e9996527d3fcf350a00a72a3866ef4f
diff --git a/configure.ac b/configure.ac
index eb83414..10782ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8046,7 +8046,7 @@ AC_SUBST(SYSTEM_BOOST)
dnl ===================================================================
dnl Check for system mdds
dnl ===================================================================
-libo_CHECK_SYSTEM_MODULE([mdds], [MDDS], [mdds >= 0.8.0])
+libo_CHECK_SYSTEM_MODULE([mdds], [MDDS], [mdds >= 0.8.1])
dnl ===================================================================
dnl Determine which hash container mdds shall use
diff --git a/download.lst b/download.lst
index 4e0fa28..fea1f3e 100644
--- a/download.lst
+++ b/download.lst
@@ -63,7 +63,7 @@ export LIBXML_TARBALL := 7740a8ec23878a2f50120e1faa2730f2-libxml2-2.7.6.tar.gz
export LIBXSLT_TARBALL := e61d0364a30146aaa3001296f853b2b9-libxslt-1.1.26.tar.gz
export LPSOLVE_TARBALL := 26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz
export MARIADB_TARBALL := 05f84c95b610c21c5fd510d10debcabf-mariadb-native-client-1.0.0.tar.bz2
-export MDDS_TARBALL := b0bba8c768f3d92608a07149039510e5-mdds_0.8.0.tar.bz2
+export MDDS_TARBALL := 5c7060bfa4ebb77b86026c268e9681fa-mdds_0.8.1.tar.bz2
export MYSQLCPPCONN_TARBALL := 0981bda6548a8c8233ffce2b6e4b2a23-mysql-connector-c++-1.1.0.tar.gz
export MYTHES_TARBALL := 46e92b68e31e858512b680b3b61dc4c1-mythes-1.2.3.tar.gz
export NEON_TARBALL := ff369e69ef0f0143beb5626164e87ae2-neon-0.29.5.tar.gz
commit 876504529cf450482b8450ef97fbf1d0a1d1ed67
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 17:24:50 2013 -0400
Test performance of pasting of formula cells as well.
Undo and redo of this are still a bit slow. Not fast enough to be
reliably tested.
Change-Id: I0e0b4c16e55bae60f8d7b1db71347a93eb977de8
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 62d6546..59201d4 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -702,6 +702,100 @@ void Test::testPerf()
CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
}
+ clearRange(m_pDoc, ScRange(0,0,0,1,MAXROW,0)); // Clear columns A:B.
+ CPPUNIT_ASSERT_MESSAGE("Column A shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,0));
+ CPPUNIT_ASSERT_MESSAGE("Column B shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,1));
+
+ {
+ // Measure the performance of repeat-pasting 2 adjacent cells to a
+ // large cell range, undoing it, and redoing it. The bottom one of
+ // the two source cells is empty. In this scenario, the non-empty
+ // cell is a formula cell referencing a cell to the right, which
+ // inserts a broadcaster to cell it references. So it has a higher
+ // overhead than the previous scenario.
+
+ ScRange aSrcRange(0,0,0,0,1,0); // A1:A2
+
+ ScAddress aPos(0,0,0);
+ m_pDoc->SetString(aPos, "=B1");
+ ScMarkData aMark;
+ aMark.SetMarkArea(aSrcRange);
+
+ // Copy to clipboard.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ ScClipParam aParam(aSrcRange, false);
+ m_pDoc->CopyToClip(aParam, &aClipDoc, &aMark);
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), aClipDoc.GetString(aPos));
+
+ ScDocument* pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pUndoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(aSrcRange, IDF_CONTENTS, false, pUndoDoc, &aMark);
+
+ // Paste it to A3:A50001, and measure its duration.
+ ScRange aPasteRange(0,2,0,0,50000,0);
+ aMark.SetMarkArea(aPasteRange);
+
+ {
+ MeasureTimeSwitch aTime(diff);
+ m_pDoc->CopyFromClip(aPasteRange, aMark, IDF_CONTENTS, pUndoDoc, &aClipDoc);
+ }
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Pasting took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ ScDocument* pRedoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pRedoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(aPasteRange, IDF_CONTENTS, false, pRedoDoc, &aMark);
+
+ // Create an undo object for this.
+ ScRefUndoData* pRefUndoData = new ScRefUndoData(m_pDoc);
+ ScUndoPaste aUndo(&(*m_xDocShRef), aPasteRange, aMark, pUndoDoc, pRedoDoc, IDF_CONTENTS, pRefUndoData);
+
+ // Make sure it did what it's supposed to do.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_FORMULA, m_pDoc->GetCellType(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_FORMULA, m_pDoc->GetCellType(aPasteRange.aEnd));
+ ScAddress aTmp = aPasteRange.aStart;
+ aTmp.IncRow();
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aTmp));
+
+#if 0 // TODO: Undo and redo of this scenario is currently not fast enough to be tested reliably.
+ {
+ MeasureTimeSwitch aTime(diff);
+ aUndo.Undo();
+ }
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Undoing took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really undone.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_FORMULA, m_pDoc->GetCellType(aPos));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aEnd));
+
+ // Now redo.
+ {
+ MeasureTimeSwitch aTime(diff);
+ aUndo.Redo();
+ }
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Redoing took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really redone.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_FORMULA, m_pDoc->GetCellType(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_FORMULA, m_pDoc->GetCellType(aPasteRange.aEnd));
+#endif
+ }
+
m_pDoc->DeleteTab(0);
}
commit 1cd034088c8e0d44ba51b3b3b247a05ad309e0ed
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 17:01:12 2013 -0400
Another performance scenario. Pasting of cells interspersed with empty ones.
Change-Id: Ia03af65dc1daf13e1228cacc20ce931839305ab8
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 3506a29..62d6546 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -535,6 +535,9 @@ void Test::testPerf()
CPPUNIT_ASSERT_MESSAGE("Column B shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,1));
{
+ // Measure the performance of repeat-pasting a single cell to a large
+ // cell range, undoing it, and redoing it.
+
ScAddress aPos(0,0,0);
m_pDoc->SetString(aPos, "test");
ScMarkData aMark;
@@ -610,6 +613,95 @@ void Test::testPerf()
CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
}
+ clearRange(m_pDoc, ScRange(0,0,0,1,MAXROW,0)); // Clear columns A:B.
+ CPPUNIT_ASSERT_MESSAGE("Column A shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,0));
+ CPPUNIT_ASSERT_MESSAGE("Column B shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,1));
+
+ {
+ // Measure the performance of repeat-pasting 2 adjacent cells to a
+ // large cell range, undoing it, and redoing it. The bottom one of
+ // the two source cells is empty.
+
+ ScRange aSrcRange(0,0,0,0,1,0); // A1:A2
+
+ ScAddress aPos(0,0,0);
+ m_pDoc->SetValue(aPos, 12);
+ ScMarkData aMark;
+ aMark.SetMarkArea(aSrcRange);
+
+ // Copy to clipboard.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ ScClipParam aParam(aSrcRange, false);
+ m_pDoc->CopyToClip(aParam, &aClipDoc, &aMark);
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), aClipDoc.GetString(aPos));
+
+ ScDocument* pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pUndoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(aSrcRange, IDF_CONTENTS, false, pUndoDoc, &aMark);
+
+ // Paste it to A3:A100001, and measure its duration.
+ ScRange aPasteRange(0,2,0,0,100000,0);
+ aMark.SetMarkArea(aPasteRange);
+
+ {
+ MeasureTimeSwitch aTime(diff);
+ m_pDoc->CopyFromClip(aPasteRange, aMark, IDF_CONTENTS, pUndoDoc, &aClipDoc);
+ }
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Pasting A1:A2 to A3:A100001 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ ScDocument* pRedoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pRedoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(aPasteRange, IDF_CONTENTS, false, pRedoDoc, &aMark);
+
+ // Create an undo object for this.
+ ScRefUndoData* pRefUndoData = new ScRefUndoData(m_pDoc);
+ ScUndoPaste aUndo(&(*m_xDocShRef), aPasteRange, aMark, pUndoDoc, pRedoDoc, IDF_CONTENTS, pRefUndoData);
+
+ // Make sure it did what it's supposed to do.
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
+ ScAddress aTmp = aPasteRange.aStart;
+ aTmp.IncRow();
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aTmp));
+
+ {
+ MeasureTimeSwitch aTime(diff);
+ aUndo.Undo();
+ }
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Undoing took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really undone.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_VALUE, m_pDoc->GetCellType(aPos));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aEnd));
+
+ // Now redo.
+ {
+ MeasureTimeSwitch aTime(diff);
+ aUndo.Redo();
+ }
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Redoing took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really redone.
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
+ }
+
m_pDoc->DeleteTab(0);
}
commit 42855ef3a1c78f8dbd10ab8cad6d3cdbc7e8fc9e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 16:35:20 2013 -0400
A bit cleaner way to measure time segment.
Change-Id: I999baaa3acba5513a148542fa28f7ae43dd7ee4f
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index cbd2752..3506a29 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -442,6 +442,25 @@ public:
}
};
+class MeasureTimeSwitch
+{
+ double& mrDiff;
+ TimeValue maTimeBefore;
+public:
+ MeasureTimeSwitch(double& rDiff) : mrDiff(rDiff)
+ {
+ mrDiff = 9999.0;
+ osl_getSystemTime(&maTimeBefore);
+ }
+
+ ~MeasureTimeSwitch()
+ {
+ TimeValue aTimeAfter;
+ osl_getSystemTime(&aTimeAfter);
+ mrDiff = getTimeDiff(aTimeAfter, maTimeBefore);
+ }
+};
+
Test::Test()
: m_pDoc(0)
{
@@ -471,15 +490,15 @@ void Test::testPerf()
{
CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, "foo"));
- TimeValue aTimeBefore, aTimeAfter;
+ double diff = 9999.0;
// Clearing an already empty sheet should finish in a fraction of a
// second. Flag failure if it takes more than one second. Clearing 100
// columns should be large enough to flag if something goes wrong.
- osl_getSystemTime(&aTimeBefore);
- clearRange(m_pDoc, ScRange(0,0,0,99,MAXROW,0));
- osl_getSystemTime(&aTimeAfter);
- double diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ {
+ MeasureTimeSwitch aTime(diff);
+ clearRange(m_pDoc, ScRange(0,0,0,99,MAXROW,0));
+ }
if (diff >= 1.0)
{
std::ostringstream os;
@@ -499,10 +518,10 @@ void Test::testPerf()
// Now, Delete B2:B100000. This should complete in a fraction of a second
// (0.06 sec on my machine).
- osl_getSystemTime(&aTimeBefore);
- clearRange(m_pDoc, ScRange(1,1,0,1,99999,0));
- osl_getSystemTime(&aTimeAfter);
- diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ {
+ MeasureTimeSwitch aTime(diff);
+ clearRange(m_pDoc, ScRange(1,1,0,1,99999,0));
+ }
if (diff >= 1.0)
{
std::ostringstream os;
@@ -535,10 +554,10 @@ void Test::testPerf()
ScRange aPasteRange(0,1,0,0,99999,0);
aMark.SetMarkArea(aPasteRange);
- osl_getSystemTime(&aTimeBefore);
- m_pDoc->CopyFromClip(aPasteRange, aMark, IDF_CONTENTS, pUndoDoc, &aClipDoc);
- osl_getSystemTime(&aTimeAfter);
- diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ {
+ MeasureTimeSwitch aTime(diff);
+ m_pDoc->CopyFromClip(aPasteRange, aMark, IDF_CONTENTS, pUndoDoc, &aClipDoc);
+ }
if (diff >= 1.0)
{
std::ostringstream os;
@@ -558,10 +577,10 @@ void Test::testPerf()
CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
- osl_getSystemTime(&aTimeBefore);
- aUndo.Undo();
- osl_getSystemTime(&aTimeAfter);
- diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ {
+ MeasureTimeSwitch aTime(diff);
+ aUndo.Undo();
+ }
if (diff >= 1.0)
{
std::ostringstream os;
@@ -575,10 +594,10 @@ void Test::testPerf()
CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aEnd));
// Now redo.
- osl_getSystemTime(&aTimeBefore);
- aUndo.Redo();
- osl_getSystemTime(&aTimeAfter);
- diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ {
+ MeasureTimeSwitch aTime(diff);
+ aUndo.Redo();
+ }
if (diff >= 1.0)
{
std::ostringstream os;
commit 42901096de15311d828696aabfc3f0b45655e237
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 16:19:04 2013 -0400
Make these stack variables & fix one memory leak with the undo object.
Change-Id: I1dd2bf0fc843394502119928c921913131c86f7e
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 5ebf6b6..cbd2752 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -5684,8 +5684,8 @@ void Test::testCopyPaste()
ScClipParam aClipParam(aRange, false);
ScMarkData aMark;
aMark.SetMarkArea(aRange);
- ScDocument* pClipDoc = new ScDocument(SCDOCMODE_CLIP);
- m_pDoc->CopyToClip(aClipParam, pClipDoc, &aMark);
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ m_pDoc->CopyToClip(aClipParam, &aClipDoc, &aMark);
sal_uInt16 nFlags = IDF_ALL;
aRange = ScRange(0,1,1,2,1,1);//target: Sheet2.A2:C2
@@ -5694,9 +5694,9 @@ void Test::testCopyPaste()
ScMarkData aMarkData2;
aMarkData2.SetMarkArea(aRange);
ScRefUndoData* pRefUndoData= new ScRefUndoData(m_pDoc);
- SfxUndoAction* pUndo = new ScUndoPaste(
+ ScUndoPaste aUndo(
&m_xDocShRef, ScRange(0, 1, 1, 2, 1, 1), aMarkData2, pUndoDoc, NULL, IDF_ALL, pRefUndoData, false);
- m_pDoc->CopyFromClip(aRange, aMarkData2, nFlags, NULL, pClipDoc);
+ m_pDoc->CopyFromClip(aRange, aMarkData2, nFlags, NULL, &aClipDoc);
//check values after copying
OUString aString;
@@ -5718,13 +5718,13 @@ void Test::testCopyPaste()
//check undo and redo
- pUndo->Undo();
+ aUndo.Undo();
m_pDoc->GetValue(1,1,1, aValue);
ASSERT_DOUBLES_EQUAL_MESSAGE("after undo formula should return nothing", aValue, 0);
aString = m_pDoc->GetString(2, 1, 1);
CPPUNIT_ASSERT_MESSAGE("after undo string should be removed", aString.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("")));
- pUndo->Redo();
+ aUndo.Redo();
m_pDoc->GetValue(1,1,1, aValue);
ASSERT_DOUBLES_EQUAL_MESSAGE("formula should return 2 after redo", aValue, 2);
aString = m_pDoc->GetString(2, 1, 1);
@@ -5732,9 +5732,6 @@ void Test::testCopyPaste()
m_pDoc->GetFormula(1,1,1, aString);
CPPUNIT_ASSERT_MESSAGE("Formula should be correct again", aString == aFormulaString);
- //clear all variables
- delete pClipDoc;
- delete pUndoDoc;
m_pDoc->DeleteTab(1);
m_pDoc->DeleteTab(0);
}
commit 266e71c7b89234b9e8722c24dfc9ee7d4ccbd74f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 16:13:32 2013 -0400
Add performance test for repeat-pasting cell to a large cell range.
Change-Id: I98dcdb1e0a72f2c3ad6f33c7b6b7d4a4bcf89096
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d1492eb..dfc46b0 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -472,6 +472,7 @@ public:
SvtBroadcaster* GetBroadcaster( SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCROW nRow ) const;
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
+ bool HasBroadcaster() const;
private:
void UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index ff525a6..f5d3414 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1972,6 +1972,11 @@ public:
const SvtBroadcaster* GetBroadcaster( const ScAddress& rPos ) const;
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const ScAddress& rTopPos, SCROW nLength );
+ /**
+ * See if specified column has any broadcaster at all.
+ */
+ bool HasBroadcaster( SCTAB nTab, SCCOL nCol ) const;
+
private: // CLOOK-Impl-methods
/**
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 6038311..b62fa1e 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -851,6 +851,7 @@ public:
SvtBroadcaster* GetBroadcaster( SCCOL nCol, SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCCOL nCol, SCROW nRow ) const;
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 );
+ bool HasBroadcaster( SCCOL nCol ) const;
/** Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 07fa33f..5ebf6b6 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -511,6 +511,86 @@ void Test::testPerf()
}
}
+ clearRange(m_pDoc, ScRange(0,0,0,1,MAXROW,0)); // Clear columns A:B.
+ CPPUNIT_ASSERT_MESSAGE("Column A shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,0));
+ CPPUNIT_ASSERT_MESSAGE("Column B shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,1));
+
+ {
+ ScAddress aPos(0,0,0);
+ m_pDoc->SetString(aPos, "test");
+ ScMarkData aMark;
+ aMark.SelectOneTable(0);
+
+ // Copy cell A1 to clipboard.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ ScClipParam aParam(aPos, false);
+ m_pDoc->CopyToClip(aParam, &aClipDoc, &aMark);
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), aClipDoc.GetString(aPos));
+
+ ScDocument* pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pUndoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(ScRange(aPos), IDF_CONTENTS, false, pUndoDoc, &aMark);
+
+ // Paste it to A2:A100000, and measure its duration.
+ ScRange aPasteRange(0,1,0,0,99999,0);
+ aMark.SetMarkArea(aPasteRange);
+
+ osl_getSystemTime(&aTimeBefore);
+ m_pDoc->CopyFromClip(aPasteRange, aMark, IDF_CONTENTS, pUndoDoc, &aClipDoc);
+ osl_getSystemTime(&aTimeAfter);
+ diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Pasting a single cell to A2:A100000 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ ScDocument* pRedoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pRedoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(aPasteRange, IDF_CONTENTS, false, pRedoDoc, &aMark);
+
+ // Create an undo object for this.
+ ScRefUndoData* pRefUndoData = new ScRefUndoData(m_pDoc);
+ ScUndoPaste aUndo(&(*m_xDocShRef), aPasteRange, aMark, pUndoDoc, pRedoDoc, IDF_CONTENTS, pRefUndoData);
+
+ // Make sure it did what it's supposed to do.
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
+
+ osl_getSystemTime(&aTimeBefore);
+ aUndo.Undo();
+ osl_getSystemTime(&aTimeAfter);
+ diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Undoing a pasting of a cell to A2:A100000 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really undone.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, m_pDoc->GetCellType(aPos));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aEnd));
+
+ // Now redo.
+ osl_getSystemTime(&aTimeBefore);
+ aUndo.Redo();
+ osl_getSystemTime(&aTimeAfter);
+ diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Redoing a pasting of a cell to A2:A100000 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really redone.
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
+ }
+
m_pDoc->DeleteTab(0);
}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 375752c..fbd0c0a 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1611,6 +1611,18 @@ void ScColumn::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRo
maBroadcasters.set_empty(rBlockPos.miBroadcasterPos, nRow1, nRow2);
}
+bool ScColumn::HasBroadcaster() const
+{
+ sc::BroadcasterStoreType::const_iterator it = maBroadcasters.begin(), itEnd = maBroadcasters.end();
+ for (; it != itEnd; ++it)
+ {
+ if (it->type == sc::element_type_broadcaster)
+ // Having a broadcaster block automatically means there is at least one broadcaster.
+ return true;
+ }
+ return false;
+}
+
sal_uInt16 ScColumn::GetTextWidth(SCROW nRow) const
{
return maCellTextAttrs.get<sc::CellTextAttr>(nRow).mnTextWidth;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 901476e..34ae049 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2257,6 +2257,15 @@ void ScDocument::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const S
pTab->DeleteBroadcasters(rBlockPos, rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
}
+bool ScDocument::HasBroadcaster( SCTAB nTab, SCCOL nCol ) const
+{
+ const ScTable* pTab = FetchTable(nTab);
+ if (!pTab)
+ return false;
+
+ return pTab->HasBroadcaster(nCol);
+}
+
bool ScDocument::TableExists( SCTAB nTab ) const
{
return ValidTab(nTab) && static_cast<size_t>(nTab) < maTabs.size() && maTabs[nTab];
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 9c380c8..c0e2c3f 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2186,6 +2186,14 @@ void ScTable::DeleteBroadcasters(
aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
}
+bool ScTable::HasBroadcaster( SCCOL nCol ) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return aCol[nCol].HasBroadcaster();
+}
+
const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
{
if (!ValidColRow(nCol, nRow))
commit 02304b8fc917a8af4230ddf3e26a45000550768a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 13:17:28 2013 -0400
Ditto when purging broadcasters.
Change-Id: I632d617cad76485f7e1f57daa7db4d4cfa775e8b
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 6db56d4..d1492eb 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -471,7 +471,7 @@ public:
SvtBroadcaster* GetBroadcaster( SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCROW nRow ) const;
- void DeleteBroadcasters( SCROW nRow1, SCROW nRow2 );
+ void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
private:
void UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx
index 35d94bf..ab24828 100644
--- a/sc/inc/columnspanset.hxx
+++ b/sc/inc/columnspanset.hxx
@@ -47,7 +47,6 @@ public:
void set(SCTAB nTab, SCCOL nCol, SCROW nRow1, SCROW nRow2, bool bVal);
void executeFromTop(Action& ac) const;
- void executeFromBottom(Action& ac) const;
};
}
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 544c9b5..ff525a6 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1970,7 +1970,7 @@ public:
SvtBroadcaster* GetBroadcaster( const ScAddress& rPos );
const SvtBroadcaster* GetBroadcaster( const ScAddress& rPos ) const;
- void DeleteBroadcasters( const ScAddress& rTopPos, SCROW nLength );
+ void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const ScAddress& rTopPos, SCROW nLength );
private: // CLOOK-Impl-methods
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 48fca53..6038311 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -850,7 +850,7 @@ public:
SvtBroadcaster* GetBroadcaster( SCCOL nCol, SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCCOL nCol, SCROW nRow ) const;
- void DeleteBroadcasters( SCCOL nCol, SCROW nRow1, SCROW nRow2 );
+ void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 );
/** Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index fa603f5..375752c 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1605,9 +1605,10 @@ const SvtBroadcaster* ScColumn::GetBroadcaster(SCROW nRow) const
return maBroadcasters.get<SvtBroadcaster*>(nRow);
}
-void ScColumn::DeleteBroadcasters( SCROW nRow1, SCROW nRow2 )
+void ScColumn::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 )
{
- maBroadcasters.set_empty(nRow1, nRow2);
+ rBlockPos.miBroadcasterPos =
+ maBroadcasters.set_empty(rBlockPos.miBroadcasterPos, nRow1, nRow2);
}
sal_uInt16 ScColumn::GetTextWidth(SCROW nRow) const
diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx
index ea4f706..9b63dc7 100644
--- a/sc/source/core/data/columnspanset.cxx
+++ b/sc/source/core/data/columnspanset.cxx
@@ -85,43 +85,14 @@ void ColumnSpanSet::executeFromTop(Action& ac) const
ColumnSpansType::const_iterator it = rCol.begin(), itEnd = rCol.end();
SCROW nRow1, nRow2;
nRow1 = it->first;
+ bool bVal = it->second;
for (++it; it != itEnd; ++it)
{
nRow2 = it->first-1;
- bool bVal = it->second;
ac.execute(ScAddress(nCol, nRow1, nTab), nRow2-nRow1+1, bVal);
nRow1 = nRow2+1; // for the next iteration.
- }
- }
- }
-}
-
-void ColumnSpanSet::executeFromBottom(Action& ac) const
-{
- for (size_t nTab = 0; nTab < maDoc.size(); ++nTab)
- {
- if (!maDoc[nTab])
- continue;
-
- const TableType& rTab = *maDoc[nTab];
- for (size_t nCol = 0; nCol < rTab.size(); ++nCol)
- {
- if (!rTab[nCol])
- continue;
-
- ac.startColumn(nTab, nCol);
- ColumnSpansType& rCol = *rTab[nCol];
- ColumnSpansType::const_reverse_iterator it = rCol.rbegin(), itEnd = rCol.rend();
- SCROW nRow1, nRow2;
- nRow2 = it->first-1;
- for (++it; it != itEnd; ++it)
- {
- nRow1 = it->first;
- bool bVal = it->second;
- ac.execute(ScAddress(nCol, nRow1, nTab), nRow2-nRow1+1, bVal);
-
- nRow2 = nRow1-1; // for the next iteration.
+ bVal = it->second;
}
}
}
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f74a946..901476e 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2241,20 +2241,20 @@ SvtBroadcaster* ScDocument::GetBroadcaster( const ScAddress& rPos )
const SvtBroadcaster* ScDocument::GetBroadcaster( const ScAddress& rPos ) const
{
- ScTable* pTab = FetchTable(rPos.Tab());
+ const ScTable* pTab = FetchTable(rPos.Tab());
if (!pTab)
return NULL;
return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
}
-void ScDocument::DeleteBroadcasters( const ScAddress& rTopPos, SCROW nLength )
+void ScDocument::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const ScAddress& rTopPos, SCROW nLength )
{
ScTable* pTab = FetchTable(rTopPos.Tab());
if (!pTab || nLength <= 0)
return;
- pTab->DeleteBroadcasters(rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
+ pTab->DeleteBroadcasters(rBlockPos, rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
}
bool ScDocument::TableExists( SCTAB nTab ) const
diff --git a/sc/source/core/data/listenercontext.cxx b/sc/source/core/data/listenercontext.cxx
index f53f1bc..1f4c995 100644
--- a/sc/source/core/data/listenercontext.cxx
+++ b/sc/source/core/data/listenercontext.cxx
@@ -17,12 +17,22 @@ namespace {
class PurgeAction : public ColumnSpanSet::Action
{
ScDocument& mrDoc;
+ sc::ColumnBlockPosition maBlockPos;
+
public:
PurgeAction(ScDocument& rDoc) : mrDoc(rDoc) {}
+
+ virtual void startColumn(SCTAB nTab, SCCOL nCol)
+ {
+ mrDoc.InitColumnBlockPosition(maBlockPos, nTab, nCol);
+ }
+
virtual void execute(const ScAddress& rPos, SCROW nLength, bool bVal)
{
if (bVal)
- mrDoc.DeleteBroadcasters(rPos, nLength);
+ {
+ mrDoc.DeleteBroadcasters(maBlockPos, rPos, nLength);
+ }
};
};
@@ -60,7 +70,7 @@ void EndListeningContext::addEmptyBroadcasterPosition(SCTAB nTab, SCCOL nCol, SC
void EndListeningContext::purgeEmptyBroadcasters()
{
PurgeAction aAction(mrDoc);
- maSet.executeFromBottom(aAction);
+ maSet.executeFromTop(aAction);
}
}
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index d1654a6..9c380c8 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2177,12 +2177,13 @@ SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow )
return aCol[nCol].GetBroadcaster(nRow);
}
-void ScTable::DeleteBroadcasters( SCCOL nCol, SCROW nRow1, SCROW nRow2 )
+void ScTable::DeleteBroadcasters(
+ sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
{
if (!ValidCol(nCol))
return;
- aCol[nCol].DeleteBroadcasters(nRow1, nRow2);
+ aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
}
const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
commit 96d56b9cc6a3e00faf231e92bffbfff7e73a7ee5
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 12:35:05 2013 -0400
A bit of cleanup.
Change-Id: I9f200377c1f5bf44eb4ba60c272b02ae3d632a19
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 0535388..f74a946 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2232,26 +2232,29 @@ ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
SvtBroadcaster* ScDocument::GetBroadcaster( const ScAddress& rPos )
{
- if (!TableExists(rPos.Tab()))
+ ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
return NULL;
- return maTabs[rPos.Tab()]->GetBroadcaster(rPos.Col(), rPos.Row());
+ return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
}
const SvtBroadcaster* ScDocument::GetBroadcaster( const ScAddress& rPos ) const
{
- if (!TableExists(rPos.Tab()))
+ ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
return NULL;
- return maTabs[rPos.Tab()]->GetBroadcaster(rPos.Col(), rPos.Row());
+ return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
}
void ScDocument::DeleteBroadcasters( const ScAddress& rTopPos, SCROW nLength )
{
- if (!TableExists(rTopPos.Tab()) || nLength <= 0)
+ ScTable* pTab = FetchTable(rTopPos.Tab());
+ if (!pTab || nLength <= 0)
return;
- maTabs[rTopPos.Tab()]->DeleteBroadcasters(rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
+ pTab->DeleteBroadcasters(rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
}
bool ScDocument::TableExists( SCTAB nTab ) const
commit a3d2a042916edf54db544db34f89c1f841e69bf5
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 12:25:19 2013 -0400
Do the same trick when getting broadcasters during mass formula cell deletion.
Change-Id: Iee1b3ff637d10c6bd2d2342db518a2fc986327b7
diff --git a/sc/inc/listenercontext.hxx b/sc/inc/listenercontext.hxx
index 2503e72..f4fbb0f 100644
--- a/sc/inc/listenercontext.hxx
+++ b/sc/inc/listenercontext.hxx
@@ -35,10 +35,13 @@ class EndListeningContext : boost::noncopyable
{
ScDocument& mrDoc;
ColumnSpanSet maSet;
+ ColumnBlockPositionSet maPosSet;
public:
EndListeningContext(ScDocument& rDoc);
ScDocument& getDoc();
+ ColumnBlockPosition* getBlockPosition(SCTAB nTab, SCCOL nCol);
+
void addEmptyBroadcasterPosition(SCTAB nTab, SCCOL nCol, SCROW nRow);
void purgeEmptyBroadcasters();
};
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 828dbe1..fa603f5 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2107,10 +2107,19 @@ void ScColumn::StartListening( sc::StartListeningContext& rCxt, SCROW nRow, SvtL
void ScColumn::EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener )
{
- SvtBroadcaster* pBC = GetBroadcaster(nRow);
- if (!pBC)
+ sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
+ if (!p)
+ return;
+
+ sc::BroadcasterStoreType::iterator& it = p->miBroadcasterPos;
+ std::pair<sc::BroadcasterStoreType::iterator,size_t> aPos = maBroadcasters.position(it, nRow);
+ it = aPos.first; // store the block position for next iteration.
+ if (it->type != sc::element_type_broadcaster)
return;
+ SvtBroadcaster* pBC = sc::custom_broadcaster_block::at(*it->data, aPos.second);
+ OSL_ASSERT(pBC);
+
rListener.EndListening(*pBC);
if (!pBC->HasListeners())
// There is no more listeners for this cell. Add it to the purge list for later purging.
diff --git a/sc/source/core/data/listenercontext.cxx b/sc/source/core/data/listenercontext.cxx
index 7ab3799..f53f1bc 100644
--- a/sc/source/core/data/listenercontext.cxx
+++ b/sc/source/core/data/listenercontext.cxx
@@ -40,13 +40,18 @@ ColumnBlockPosition* StartListeningContext::getBlockPosition(SCTAB nTab, SCCOL n
return maSet.getBlockPosition(nTab, nCol);
}
-EndListeningContext::EndListeningContext(ScDocument& rDoc) : mrDoc(rDoc) {}
+EndListeningContext::EndListeningContext(ScDocument& rDoc) : mrDoc(rDoc), maPosSet(rDoc) {}
ScDocument& EndListeningContext::getDoc()
{
return mrDoc;
}
+ColumnBlockPosition* EndListeningContext::getBlockPosition(SCTAB nTab, SCCOL nCol)
+{
+ return maPosSet.getBlockPosition(nTab, nCol);
+}
+
void EndListeningContext::addEmptyBroadcasterPosition(SCTAB nTab, SCCOL nCol, SCROW nRow)
{
maSet.set(nTab, nCol, nRow, true);
commit d5b4cb00bedd08ad72885defbc35c971b573ecd8
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon May 20 11:12:49 2013 -0400
Keep track of column block positions when mass-pasting formula cells.
This speeds up the following scenario:
1) type =B1 in A1. Leave A2 empty.
2) Select A1:A2 and Ctrl-C to copy.
3) Select A3:A50000 (or longer if you so wish), and ctrl-V to paste.
This causes the broadcaster storage array in column B to be heavily
partitioned due to the empty cells interspersed between formula cells
in column A. Without tracking the column position this would cause a
O(n^2) complexity algorithm.
Change-Id: Ic2f23c2c2bea3353c517faa73fe5412c7528bd95
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 46ffbd9..6db56d4 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -37,6 +37,7 @@ namespace editeng { class SvxBorderLine; }
namespace sc {
struct FormulaGroupContext;
+ class StartListeningContext;
class EndListeningContext;
class CopyFromClipContext;
class CopyToClipContext;
@@ -226,7 +227,7 @@ public:
void CopyFromClip(
sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn );
- void StartListeningInArea( SCROW nRow1, SCROW nRow2 );
+ void StartListeningInArea( sc::StartListeningContext& rCxt, SCROW nRow1, SCROW nRow2 );
void BroadcastInArea( SCROW nRow1, SCROW nRow2 );
void RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow );
@@ -433,6 +434,7 @@ public:
void StartListening( SvtListener& rLst, SCROW nRow );
void EndListening( SvtListener& rLst, SCROW nRow );
+ void StartListening( sc::StartListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
void EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
void MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow );
void StartAllListeners();
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index f01e811..544c9b5 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -49,6 +49,7 @@
namespace editeng { class SvxBorderLine; }
namespace sc {
struct FormulaGroupContext;
+ class StartListeningContext;
class EndListeningContext;
class CopyFromClipContext;
struct ColumnBlockPosition;
@@ -1765,6 +1766,7 @@ public:
void EndListeningCell( const ScAddress& rAddress,
SvtListener* pListener );
+ void StartListeningCell( sc::StartListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener );
void EndListeningCell( sc::EndListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener );
void EndListeningFormulaCells( std::vector<ScFormulaCell*>& rCells );
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index e081353..4760062 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -30,6 +30,7 @@
namespace sc {
+class StartListeningContext;
class EndListeningContext;
}
@@ -313,6 +314,7 @@ public:
// nOnlyNames may be one or more of SC_LISTENING_NAMES_*
void StartListeningTo( ScDocument* pDoc );
+ void StartListeningTo( sc::StartListeningContext& rCxt );
void EndListeningTo(
ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
void EndListeningTo( sc::EndListeningContext& rCxt );
diff --git a/sc/inc/listenercontext.hxx b/sc/inc/listenercontext.hxx
index 36f26d8..2503e72 100644
--- a/sc/inc/listenercontext.hxx
+++ b/sc/inc/listenercontext.hxx
@@ -12,6 +12,7 @@
#include "address.hxx"
#include "columnspanset.hxx"
+#include "mtvelements.hxx"
#include <boost/noncopyable.hpp>
@@ -19,6 +20,17 @@ class ScDocument;
namespace sc {
+class StartListeningContext : boost::noncopyable
+{
+ ScDocument& mrDoc;
+ ColumnBlockPositionSet maSet;
+public:
+ StartListeningContext(ScDocument& rDoc);
+ ScDocument& getDoc();
+
+ ColumnBlockPosition* getBlockPosition(SCTAB nTab, SCCOL nCol);
+};
+
class EndListeningContext : boost::noncopyable
{
ScDocument& mrDoc;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index f04a9bb..48fca53 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -49,6 +49,7 @@ namespace com { namespace sun { namespace star {
namespace sc {
struct FormulaGroupContext;
+ class StartListeningContext;
class EndListeningContext;
class CopyFromClipContext;
class CopyToClipContext;
@@ -393,8 +394,9 @@ public:
sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCsCOL nDx, SCsROW nDy, ScTable* pTable );
- void StartListeningInArea( SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2 );
+ void StartListeningInArea(
+ sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+
void BroadcastInArea( SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2 );
@@ -948,6 +950,7 @@ private:
void StartListening( const ScAddress& rAddress, SvtListener* pListener );
void EndListening( const ScAddress& rAddress, SvtListener* pListener );
+ void StartListening( sc::StartListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
void EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
void StartAllListeners();
void StartNeededListeners(); // only for cells where NeedsListening()==TRUE
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 3b28d61..828dbe1 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2013,17 +2013,18 @@ void ScColumn::FindUsed( SCROW nStartRow, SCROW nEndRow, bool* pUsed ) const
}
}
-void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
+namespace {
+
+void startListening(
+ sc::BroadcasterStoreType& rStore, sc::BroadcasterStoreType::iterator& itBlockPos, size_t nElemPos,
+ SCROW nRow, SvtListener& rLst)
{
- std::pair<sc::BroadcasterStoreType::iterator,size_t> aPos = maBroadcasters.position(nRow);
- sc::BroadcasterStoreType::iterator it = aPos.first; // block position.
- size_t nElemPos = aPos.second; // element position within the block.
- switch (it->type)
+ switch (itBlockPos->type)
{
case sc::element_type_broadcaster:
{
// Broadcaster already exists here.
- SvtBroadcaster* pBC = sc::custom_broadcaster_block::at(*it->data, nElemPos);
+ SvtBroadcaster* pBC = sc::custom_broadcaster_block::at(*itBlockPos->data, nElemPos);
rLst.StartListening(*pBC);
}
break;
@@ -2032,7 +2033,7 @@ void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
// No broadcaster exists at this position yet.
SvtBroadcaster* pBC = new SvtBroadcaster;
rLst.StartListening(*pBC);
- maBroadcasters.set(it, nRow, pBC);
+ itBlockPos = rStore.set(itBlockPos, nRow, pBC); // Store the block position for next iteration.
}
break;
default:
@@ -2046,6 +2047,14 @@ void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
}
}
+}
+
+void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
+{
+ std::pair<sc::BroadcasterStoreType::iterator,size_t> aPos = maBroadcasters.position(nRow);
+ startListening(maBroadcasters, aPos.first, aPos.second, nRow, rLst);
+}
+
void ScColumn::MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow )
{
// Move listeners from the source position to the destination position.
@@ -2081,6 +2090,21 @@ void ScColumn::EndListening( SvtListener& rLst, SCROW nRow )
maBroadcasters.set_empty(nRow, nRow);
}
+void ScColumn::StartListening( sc::StartListeningContext& rCxt, SCROW nRow, SvtListener& rLst )
+{
+ if (!ValidRow(nRow))
+ return;
+
+ sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
+ if (!p)
+ return;
+
+ sc::BroadcasterStoreType::iterator& it = p->miBroadcasterPos;
+ std::pair<sc::BroadcasterStoreType::iterator,size_t> aPos = maBroadcasters.position(it, nRow);
+ it = aPos.first; // store the block position for next iteration.
+ startListening(maBroadcasters, it, aPos.second, nRow, rLst);
+}
+
void ScColumn::EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener )
{
SvtBroadcaster* pBC = GetBroadcaster(nRow);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 70d007d..60eb8e3 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1166,7 +1166,7 @@ void ScColumn::BroadcastInArea( SCROW nRow1, SCROW nRow2 )
}
-void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 )
+void ScColumn::StartListeningInArea( sc::StartListeningContext& rCxt, SCROW nRow1, SCROW nRow2 )
{
if (maItems.empty())
return;
@@ -1178,7 +1178,7 @@ void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 )
{
ScBaseCell* pCell = maItems[nIndex].pCell;
if ( pCell->GetCellType() == CELLTYPE_FORMULA )
- ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
+ ((ScFormulaCell*)pCell)->StartListeningTo(rCxt);
if ( nRow != maItems[nIndex].nRow )
Search( nRow, nIndex ); // Inserted via Listening
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index b240633..1c3f665 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -201,13 +201,24 @@ void ScDocument::EndListeningCell( const ScAddress& rAddress,
maTabs[nTab]->EndListening( rAddress, pListener );
}
+void ScDocument::StartListeningCell(
+ sc::StartListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener )
+{
+ ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ pTab->StartListening(rCxt, rPos.Col(), rPos.Row(), rListener);
+}
+
void ScDocument::EndListeningCell(
sc::EndListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener )
{
- if (!TableExists(rPos.Tab()))
+ ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
return;
- maTabs[rPos.Tab()]->EndListening(rCxt, rPos.Col(), rPos.Row(), rListener);
+ pTab->EndListening(rCxt, rPos.Col(), rPos.Row(), rListener);
}
void ScDocument::EndListeningFormulaCells( std::vector<ScFormulaCell*>& rCells )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f41a715..0535388 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -91,6 +91,7 @@
#include "formulaiter.hxx"
#include "formulacell.hxx"
#include "clipcontext.hxx"
+#include "listenercontext.hxx"
#include <map>
#include <limits>
@@ -2314,11 +2315,12 @@ void ScDocument::StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
{
if (nInsFlag & IDF_CONTENTS)
{
+ sc::StartListeningContext aCxt(*this);
SCTAB nMax = static_cast<SCTAB>(maTabs.size());
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd && *itr < nMax; ++itr)
if (maTabs[*itr])
- maTabs[*itr]->StartListeningInArea( nCol1, nRow1, nCol2, nRow2 );
+ maTabs[*itr]->StartListeningInArea(aCxt, nCol1, nRow1, nCol2, nRow2);
}
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 30810df..98df69a 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3162,6 +3162,34 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
return true;
}
+namespace {
+
+void startListeningArea(
+ ScFormulaCell* pCell, ScDocument& rDoc, const ScAddress& rPos, const ScToken& rToken)
+{
+ const ScSingleRefData& rRef1 = rToken.GetSingleRef();
+ const ScSingleRefData& rRef2 = rToken.GetSingleRef2();
+ ScAddress aCell1 = rRef1.toAbs(rPos);
+ ScAddress aCell2 = rRef2.toAbs(rPos);
+ if (aCell1.IsValid() && aCell2.IsValid())
+ {
+ if (rToken.GetOpCode() == ocColRowNameAuto)
+ { // automagically
+ if ( rRef1.IsColRel() )
+ { // ColName
+ aCell2.SetRow(MAXROW);
+ }
+ else
+ { // RowName
+ aCell2.SetCol(MAXCOL);
+ }
+ }
+ rDoc.StartListeningArea(ScRange(aCell1, aCell2), pCell);
+ }
+}
+
+}
+
void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
{
if (pDoc->IsClipOrUndo() || pDoc->GetNoListening() || IsInChangeTrack())
@@ -3181,40 +3209,58 @@ void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
ScToken* t;
while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
{
- StackVar eType = t->GetType();
- ScSingleRefData& rRef1 = t->GetSingleRef();
- ScSingleRefData& rRef2 = (eType == svDoubleRef ?
- t->GetDoubleRef().Ref2 : rRef1);
- switch( eType )
+ switch (t->GetType())
{
case svSingleRef:
{
- ScAddress aCell = rRef1.toAbs(aPos);
+ ScAddress aCell = t->GetSingleRef().toAbs(aPos);
if (aCell.IsValid())
pDoc->StartListeningCell(aCell, this);
}
break;
case svDoubleRef:
+ startListeningArea(this, *pDoc, aPos, *t);
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ SetNeedsListening( false);
+}
+
+void ScFormulaCell::StartListeningTo( sc::StartListeningContext& rCxt )
+{
+ ScDocument& rDoc = rCxt.getDoc();
+
+ if (rDoc.IsClipOrUndo() || rDoc.GetNoListening() || IsInChangeTrack())
+ return;
+
+ rDoc.SetDetectiveDirty(true); // It has changed something
+
+ ScTokenArray* pArr = GetCode();
+ if( pArr->IsRecalcModeAlways() )
+ {
+ rDoc.StartListeningArea(BCA_LISTEN_ALWAYS, this);
+ SetNeedsListening( false);
+ return;
+ }
+
+ pArr->Reset();
+ ScToken* t;
+ while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+ {
+ switch (t->GetType())
+ {
+ case svSingleRef:
{
- ScAddress aCell1 = rRef1.toAbs(aPos);
- ScAddress aCell2 = rRef2.toAbs(aPos);
- if (aCell1.IsValid() && aCell2.IsValid())
- {
- if (t->GetOpCode() == ocColRowNameAuto)
- { // automagically
- if ( rRef1.IsColRel() )
- { // ColName
- aCell2.SetRow(MAXROW);
- }
- else
- { // RowName
- aCell2.SetCol(MAXCOL);
- }
- }
- pDoc->StartListeningArea(ScRange(aCell1, aCell2), this);
- }
+ ScAddress aCell = t->GetSingleRef().toAbs(aPos);
+ if (aCell.IsValid())
+ rDoc.StartListeningCell(rCxt, aCell, *this);
}
break;
+ case svDoubleRef:
+ startListeningArea(this, rDoc, aPos, *t);
+ break;
default:
; // nothing
}
diff --git a/sc/source/core/data/listenercontext.cxx b/sc/source/core/data/listenercontext.cxx
index a288494..7ab3799 100644
--- a/sc/source/core/data/listenercontext.cxx
+++ b/sc/source/core/data/listenercontext.cxx
@@ -28,6 +28,18 @@ public:
}
+StartListeningContext::StartListeningContext(ScDocument& rDoc) : mrDoc(rDoc), maSet(rDoc) {}
+
+ScDocument& StartListeningContext::getDoc()
+{
+ return mrDoc;
+}
+
+ColumnBlockPosition* StartListeningContext::getBlockPosition(SCTAB nTab, SCCOL nCol)
+{
+ return maSet.getBlockPosition(nTab, nCol);
+}
+
EndListeningContext::EndListeningContext(ScDocument& rDoc) : mrDoc(rDoc) {}
ScDocument& EndListeningContext::getDoc()
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 51801af..0f5d458 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1010,14 +1010,14 @@ void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
}
-void ScTable::StartListeningInArea( SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2 )
+void ScTable::StartListeningInArea(
+ sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
{
if (nCol2 > MAXCOL) nCol2 = MAXCOL;
if (nRow2 > MAXROW) nRow2 = MAXROW;
if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
for (SCCOL i = nCol1; i <= nCol2; i++)
- aCol[i].StartListeningInArea( nRow1, nRow2 );
+ aCol[i].StartListeningInArea(rCxt, nRow1, nRow2);
}
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 9468352..ed15086 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -1097,6 +1097,14 @@ void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener )
aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() );
}
+void ScTable::StartListening( sc::StartListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener )
+{
+ if (!ValidCol(nCol))
+ return;
+
+ aCol[nCol].StartListening(rCxt, nRow, rListener);
+}
+
void ScTable::EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener )
{
if (!ValidCol(nCol))
commit fc470416281b92e6b481885b64d59bc01ea4c3a6
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 23:33:30 2013 -0400
A bit of cleanup before refactoring.
Change-Id: I3627a83669b6a69c299aef96b8b2ead1352eabe2
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index b243ea2..30810df 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3188,53 +3188,32 @@ void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
switch( eType )
{
case svSingleRef:
- rRef1.CalcAbsIfRel(aPos);
- if ( rRef1.Valid() )
- {
- pDoc->StartListeningCell(
- ScAddress( rRef1.nCol,
- rRef1.nRow,
- rRef1.nTab ), this );
- }
+ {
+ ScAddress aCell = rRef1.toAbs(aPos);
+ if (aCell.IsValid())
+ pDoc->StartListeningCell(aCell, this);
+ }
break;
case svDoubleRef:
- t->CalcAbsIfRel(aPos);
- if ( rRef1.Valid() && rRef2.Valid() )
+ {
+ ScAddress aCell1 = rRef1.toAbs(aPos);
+ ScAddress aCell2 = rRef2.toAbs(aPos);
+ if (aCell1.IsValid() && aCell2.IsValid())
{
- if ( t->GetOpCode() == ocColRowNameAuto )
+ if (t->GetOpCode() == ocColRowNameAuto)
{ // automagically
if ( rRef1.IsColRel() )
{ // ColName
- pDoc->StartListeningArea( ScRange (
- rRef1.nCol,
- rRef1.nRow,
- rRef1.nTab,
- rRef2.nCol,
- MAXROW,
- rRef2.nTab ), this );
+ aCell2.SetRow(MAXROW);
}
else
{ // RowName
- pDoc->StartListeningArea( ScRange (
- rRef1.nCol,
- rRef1.nRow,
- rRef1.nTab,
- MAXCOL,
- rRef2.nRow,
- rRef2.nTab ), this );
+ aCell2.SetCol(MAXCOL);
}
}
- else
- {
- pDoc->StartListeningArea( ScRange (
- rRef1.nCol,
- rRef1.nRow,
- rRef1.nTab,
- rRef2.nCol,
- rRef2.nRow,
- rRef2.nTab ), this );
- }
+ pDoc->StartListeningArea(ScRange(aCell1, aCell2), this);
}
+ }
break;
default:
; // nothing
commit c2e28f50354d4e95b2202aebe1764d81fdbfd27e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 22:45:43 2013 -0400
Prefer early bail-out.
Change-Id: I112a4be56910c07007b28715336fcd82d56bb313
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index f573011..70d007d 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1103,38 +1103,40 @@ ScAttrIterator* ScColumn::CreateAttrIterator( SCROW nStartRow, SCROW nEndRow ) c
void ScColumn::StartAllListeners()
{
- if ( !maItems.empty() )
- for (SCSIZE i = 0; i < maItems.size(); i++)
+ if (maItems.empty())
+ return;
+
+ for (SCSIZE i = 0; i < maItems.size(); i++)
+ {
+ ScBaseCell* pCell = maItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
{
- ScBaseCell* pCell = maItems[i].pCell;
- if ( pCell->GetCellType() == CELLTYPE_FORMULA )
- {
- SCROW nRow = maItems[i].nRow;
- ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
- if ( nRow != maItems[i].nRow )
- Search( nRow, i ); // Insert Listener?
- }
+ SCROW nRow = maItems[i].nRow;
+ ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
+ if ( nRow != maItems[i].nRow )
+ Search( nRow, i ); // Insert Listener?
}
+ }
}
void ScColumn::StartNeededListeners()
{
- if ( !maItems.empty() )
+ if (maItems.empty())
+ return;
+
+ for (SCSIZE i = 0; i < maItems.size(); i++)
{
- for (SCSIZE i = 0; i < maItems.size(); i++)
+ ScBaseCell* pCell = maItems[i].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
{
- ScBaseCell* pCell = maItems[i].pCell;
- if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if (pFCell->NeedsListening())
{
- ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
- if (pFCell->NeedsListening())
- {
- SCROW nRow = maItems[i].nRow;
- pFCell->StartListeningTo( pDocument );
- if ( nRow != maItems[i].nRow )
- Search( nRow, i ); // Insert Listener?
- }
+ SCROW nRow = maItems[i].nRow;
+ pFCell->StartListeningTo( pDocument );
+ if ( nRow != maItems[i].nRow )
+ Search( nRow, i ); // Insert Listener?
}
}
}
@@ -1166,20 +1168,21 @@ void ScColumn::BroadcastInArea( SCROW nRow1, SCROW nRow2 )
void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 )
{
- if ( !maItems.empty() )
+ if (maItems.empty())
+ return;
+
+ SCROW nRow;
+ SCSIZE nIndex;
+ Search( nRow1, nIndex );
+ while ( nIndex < maItems.size() && (nRow = maItems[nIndex].nRow) <= nRow2 )
{
- SCROW nRow;
- SCSIZE nIndex;
- Search( nRow1, nIndex );
- while ( nIndex < maItems.size() && (nRow = maItems[nIndex].nRow) <= nRow2 )
- {
- ScBaseCell* pCell = maItems[nIndex].pCell;
- if ( pCell->GetCellType() == CELLTYPE_FORMULA )
- ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
- if ( nRow != maItems[nIndex].nRow )
- Search( nRow, nIndex ); // Inserted via Listening
- nIndex++;
- }
+ ScBaseCell* pCell = maItems[nIndex].pCell;
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ ((ScFormulaCell*)pCell)->StartListeningTo( pDocument );
+ if ( nRow != maItems[nIndex].nRow )
+ Search( nRow, nIndex ); // Inserted via Listening
+
+ ++nIndex;
}
}
commit 0e25fe33f0114dc8723a7a9af4cdd11f07a55ec5
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 22:16:45 2013 -0400
Compiler warning.
Change-Id: I6f358f89348a23b3c70f8b7db8a1f01d659393ba
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 9339e8b..f573011 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -906,8 +906,7 @@ void ScColumn::MixData(
SCSIZE nIndex;
Search( nRow1, nIndex );
-// SCSIZE nSrcIndex = 0;
- SCSIZE nSrcIndex, nDestIndex;
+ SCSIZE nSrcIndex = 0, nDestIndex = 0;
rSrcCol.Search( nRow1, nSrcIndex ); // See if data is at the beginning
SCROW nNextThis = MAXROW+1;
commit f7d037c2288cacaedf221404b5c9d4b7f2a0b7cb
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 21:23:22 2013 -0400
Optimize ScColumn::MixData() to remove several bottlenecks.
The use case that would previously make Calc freeze.
1) type in "test" in A1.
2) Select A1:A2 and Ctrl-C to copy to the clipboard.
3) select the whole column B.
4) paste special, select "Add" operation and click OK to paste.
With this change, the above scenario no longer freezes Calc.
Change-Id: I98b1f1e6c25b853aa884e7598c04b1457fab4636
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index c71ffea..46ffbd9 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -497,6 +497,12 @@ private:
void SetCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScBaseCell* pNewCell );
void SetCell( SCROW nRow, ScBaseCell* pNewCell );
void PostSetCell( SCROW nRow, ScBaseCell* pNewCell );
+
+ /**
+ * Clear and re-populate the cell text attribute array from the non-empty
+ * cells stored in the cell array.
+ */
+ void ResetCellTextAttrs();
};
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index d4fe479..3b28d61 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1569,6 +1569,32 @@ void ScColumn::PostSetCell( SCROW nRow, ScBaseCell* pNewCell )
}
}
+namespace {
+
+class SetEmptyAttr : std::unary_function<ColEntry, void>
+{
+ sc::CellTextAttrStoreType& mrAttrStore;
+ sc::CellTextAttrStoreType::iterator miPos;
+public:
+ SetEmptyAttr(sc::CellTextAttrStoreType& rAttrStore) :
+ mrAttrStore(rAttrStore), miPos(rAttrStore.begin()) {}
+
+ void operator() (const ColEntry& rEntry)
+ {
+ miPos = mrAttrStore.set(miPos, rEntry.nRow, sc::CellTextAttr());
+ }
+};
+
+}
+
+void ScColumn::ResetCellTextAttrs()
+{
+ maCellTextAttrs.clear();
+ maCellTextAttrs.resize(MAXROWCOUNT);
+
+ std::for_each(maItems.begin(), maItems.end(), SetEmptyAttr(maCellTextAttrs));
+}
+
SvtBroadcaster* ScColumn::GetBroadcaster(SCROW nRow)
{
return maBroadcasters.get<SvtBroadcaster*>(nRow);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b530184..9339e8b 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -842,11 +842,12 @@ void ScColumn::MixMarked(
}
}
+namespace {
// Result in rVal1
-static sal_Bool lcl_DoFunction( double& rVal1, double nVal2, sal_uInt16 nFunction )
+bool lcl_DoFunction( double& rVal1, double nVal2, sal_uInt16 nFunction )
{
- sal_Bool bOk = false;
+ bool bOk = false;
switch (nFunction)
{
case PASTE_ADD:
@@ -866,8 +867,7 @@ static sal_Bool lcl_DoFunction( double& rVal1, double nVal2, sal_uInt16 nFunctio
return bOk;
}
-
-static void lcl_AddCode( ScTokenArray& rArr, ScFormulaCell* pCell )
+void lcl_AddCode( ScTokenArray& rArr, ScFormulaCell* pCell )
{
rArr.AddOpCode(ocOpen);
@@ -885,6 +885,15 @@ static void lcl_AddCode( ScTokenArray& rArr, ScFormulaCell* pCell )
rArr.AddOpCode(ocClose);
}
+struct FindRemovedCell : std::unary_function<ColEntry, bool>
+{
+ bool operator() (const ColEntry& rEntry) const
+ {
+ return rEntry.pCell == NULL;
+ }
+};
+
+}
void ScColumn::MixData(
sc::MixDocContext& rCxt, SCROW nRow1, SCROW nRow2, sal_uInt16 nFunction,
@@ -892,11 +901,13 @@ void ScColumn::MixData(
{
SCSIZE nSrcCount = rSrcCol.maItems.size();
+ sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
+
SCSIZE nIndex;
Search( nRow1, nIndex );
// SCSIZE nSrcIndex = 0;
- SCSIZE nSrcIndex;
+ SCSIZE nSrcIndex, nDestIndex;
rSrcCol.Search( nRow1, nSrcIndex ); // See if data is at the beginning
SCROW nNextThis = MAXROW+1;
@@ -906,6 +917,7 @@ void ScColumn::MixData(
if ( nSrcIndex < nSrcCount )
nNextSrc = rSrcCol.maItems[nSrcIndex].nRow;
+ bool bDeferredDelete = false;
while ( nNextThis <= nRow2 || nNextSrc <= nRow2 )
{
SCROW nRow = std::min( nNextThis, nNextSrc );
@@ -913,13 +925,16 @@ void ScColumn::MixData(
ScBaseCell* pSrc = NULL;
ScBaseCell* pDest = NULL;
ScBaseCell* pNew = NULL;
- sal_Bool bDelete = false;
+ bool bDelete = false;
if ( nSrcIndex < nSrcCount && nNextSrc == nRow )
pSrc = rSrcCol.maItems[nSrcIndex].pCell;
if ( nIndex < maItems.size() && nNextThis == nRow )
+ {
pDest = maItems[nIndex].pCell;
+ nDestIndex = nIndex;
+ }
OSL_ENSURE( pSrc || pDest, "What happened?" );
@@ -1024,10 +1039,18 @@ void ScColumn::MixData(
if ( pNew || bDelete ) // New result?
{
- sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
if (pDest && !pNew) // Old cell present?
{
- Delete(nRow); // -> Delete
+ // Delete the destination cell because the cell was originally
+ // empty. Don't erase its slot in the cell array yet.
+ OSL_ASSERT(pDest == maItems[nDestIndex].pCell);
+ maItems[nDestIndex].pCell = NULL;
+
+ if (pDest->GetCellType() == CELLTYPE_FORMULA)
+ static_cast<ScFormulaCell*>(pDest)->EndListeningTo(pDocument);
+ pDest->Delete();
+
+ bDeferredDelete = true;
}
if (pNew)
{
@@ -1057,6 +1080,19 @@ void ScColumn::MixData(
MAXROW+1;
}
}
+
+ if (bDeferredDelete)
+ {
+ // Erase all the slots in the cell array where the deleted cells
+ // previously occupied.
+ std::vector<ColEntry>::iterator it =
+ std::remove_if(maItems.begin(), maItems.end(), FindRemovedCell());
+
+ maItems.erase(it, maItems.end());
+
+ // Reset the cell text attriute array to keep it in sync again.
+ ResetCellTextAttrs();
+ }
}
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index ced0936..ec5b1c4 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -118,14 +118,7 @@ void ScDocumentImport::finalize()
for (; pCol != pColEnd; ++pCol)
{
ScColumn& rCol = *pCol;
- if (rCol.maItems.empty())
- // Column has no cells. Skip it.
- continue;
-
- sc::CellTextAttrStoreType::iterator itCTAPos = rCol.maCellTextAttrs.begin();
- std::vector<ColEntry>::iterator itCell = rCol.maItems.begin(), itCellEnd = rCol.maItems.end();
- for (; itCell != itCellEnd; ++itCell)
- itCTAPos = rCol.maCellTextAttrs.set<sc::CellTextAttr>(itCTAPos, itCell->nRow, sc::CellTextAttr());
+ rCol.ResetCellTextAttrs();
}
}
}
commit edddbde921bf977dc1e7104956d204622b0449dd
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 16:48:25 2013 -0400
A bit of a cleanup.
Change-Id: Iaa7003cabee4630e4fbb8fb1cd114d04b4e9e33c
diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx
index 599da6e..84b1fcc 100644
--- a/sc/inc/clipcontext.hxx
+++ b/sc/inc/clipcontext.hxx
@@ -22,13 +22,7 @@ namespace sc {
class ClipContextBase
{
- typedef boost::unordered_map<SCCOL, ColumnBlockPosition> ColumnsType;
- typedef std::vector<ColumnsType> TablesType;
-
- ScDocument& mrDoc;
- TablesType maTables;
- SCTAB mnTabStart;
- SCTAB mnTabEnd;
+ sc::ColumnBlockPositionSet maSet;
ClipContextBase(); // disabled
@@ -36,16 +30,13 @@ public:
ClipContextBase(ScDocument& rDoc);
virtual ~ClipContextBase();
- void setTabRange(SCTAB nStart, SCTAB nEnd);
-
- SCTAB getTabStart() const;
- SCTAB getTabEnd() const;
-
ColumnBlockPosition* getBlockPosition(SCTAB nTab, SCCOL nCol);
};
class CopyFromClipContext : public ClipContextBase
{
+ SCTAB mnTabStart;
+ SCTAB mnTabEnd;
ScDocument* mpRefUndoDoc;
ScDocument* mpClipDoc;
sal_uInt16 mnInsertFlag;
@@ -61,6 +52,11 @@ public:
virtual ~CopyFromClipContext();
+ void setTabRange(SCTAB nStart, SCTAB nEnd);
+
+ SCTAB getTabStart() const;
+ SCTAB getTabEnd() const;
+
ScDocument* getUndoDoc();
ScDocument* getClipDoc();
sal_uInt16 getInsertFlag() const;
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 2c7abdf..2b51076 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -13,62 +13,20 @@
namespace sc {
ClipContextBase::ClipContextBase(ScDocument& rDoc) :
- mrDoc(rDoc), mnTabStart(-1), mnTabEnd(-1) {}
+ maSet(rDoc) {}
ClipContextBase::~ClipContextBase() {}
-void ClipContextBase::setTabRange(SCTAB nStart, SCTAB nEnd)
-{
- mnTabStart = nStart;
- mnTabEnd = nEnd;
-}
-
-SCTAB ClipContextBase::getTabStart() const
-{
- return mnTabStart;
-}
-
-SCTAB ClipContextBase::getTabEnd() const
-{
- return mnTabEnd;
-}
-
ColumnBlockPosition* ClipContextBase::getBlockPosition(SCTAB nTab, SCCOL nCol)
{
- if (mnTabStart < 0 || mnTabEnd < 0 || mnTabStart > mnTabEnd)
- return NULL;
-
- size_t nTabIndex = nTab - mnTabStart;
- if (nTabIndex >= maTables.size())
- maTables.resize(nTabIndex+1);
-
- ColumnsType& rCols = maTables[nTabIndex];
-
- ColumnsType::iterator it = rCols.find(nCol);
- if (it != rCols.end())
- // Block position for this column has already been fetched.
- return &it->second;
-
- std::pair<ColumnsType::iterator,bool> r =
- rCols.insert(
- ColumnsType::value_type(nCol, ColumnBlockPosition()));
-
- if (!r.second)
- // insertion failed.
- return NULL;
-
- it = r.first;
-
- if (!mrDoc.InitColumnBlockPosition(it->second, nTab, nCol))
- return NULL;
-
- return &it->second;
+ return maSet.getBlockPosition(nTab, nCol);
}
CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc,
ScDocument* pRefUndoDoc, ScDocument* pClipDoc, sal_uInt16 nInsertFlag,
bool bAsLink, bool bSkipAttrForEmptyCells) :
ClipContextBase(rDoc),
+ mnTabStart(-1), mnTabEnd(-1),
mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc), mnInsertFlag(nInsertFlag),
mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells) {}
@@ -76,6 +34,22 @@ CopyFromClipContext::~CopyFromClipContext()
{
}
+void CopyFromClipContext::setTabRange(SCTAB nStart, SCTAB nEnd)
+{
+ mnTabStart = nStart;
+ mnTabEnd = nEnd;
+}
+
+SCTAB CopyFromClipContext::getTabStart() const
+{
+ return mnTabStart;
+}
+
+SCTAB CopyFromClipContext::getTabEnd() const
+{
+ return mnTabEnd;
+}
+
ScDocument* CopyFromClipContext::getUndoDoc()
{
return mpRefUndoDoc;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 94cd257..10d36b6 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1514,7 +1514,6 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
{
// This is the scenario table, the data is copied into it
sc::CopyToDocContext aCxt(*pDocument);
- aCxt.setTabRange(nTab, nTab);
ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
SCROW nStart = -1, nEnd = -1;
const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
@@ -1546,7 +1545,6 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
{
// This is the scenario table, the data is copied to the other
sc::CopyToDocContext aCxt(*rDestCol.pDocument);
- aCxt.setTabRange(rDestCol.nTab, rDestCol.nTab);
ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
SCROW nStart = -1, nEnd = -1;
const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 0229c52..dcdae98 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -857,7 +857,6 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
if (bValid)
{
sc::CopyToDocContext aCxt(*this);
- aCxt.setTabRange(nNewPos, nNewPos);
SetNoListening( true ); // noch nicht bei CopyToTable/Insert
maTabs[nOldPos]->CopyToTable(aCxt, 0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
maTabs[nNewPos], pOnlyMarked );
@@ -965,7 +964,6 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
sc::CopyToDocContext aCxt(*this);
- aCxt.setTabRange(nDestPos, nDestPos);
nDestPos = std::min(nDestPos, (SCTAB)(GetTableCount() - 1));
{ // scope for bulk broadcast
ScBulkBroadcast aBulkBroadcast( pBASM);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 5fbc1ac0..f41a715 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1843,7 +1843,6 @@ void ScDocument::CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
if (ValidTab(nTab1) && ValidTab(nTab2))
{
sc::CopyToDocContext aCxt(*pDestDoc);
- aCxt.setTabRange(nTab1, nTab2);
bool bOldAutoCalc = pDestDoc->GetAutoCalc();
pDestDoc->SetAutoCalc( false ); // avoid multiple calculations
SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pDestDoc->maTabs.size()));
@@ -1875,7 +1874,6 @@ void ScDocument::UndoToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, false, pDestDoc, pMarks );
sc::CopyToDocContext aCxt(*pDestDoc);
- aCxt.setTabRange(nTab1, nTab2);
OSL_ASSERT( nTab2 < static_cast<SCTAB>(maTabs.size()) && nTab2 < static_cast<SCTAB>(pDestDoc->maTabs.size()));
for (SCTAB i = nTab1; i <= nTab2; i++)
{
@@ -1903,7 +1901,6 @@ void ScDocument::CopyToDocument(const ScRange& rRange,
bool bOldAutoCalc = pDestDoc->GetAutoCalc();
pDestDoc->SetAutoCalc( false ); // avoid multiple calculations
sc::CopyToDocContext aCxt(*pDestDoc);
- aCxt.setTabRange(aNewRange.aStart.Tab(), aNewRange.aEnd.Tab());
SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pDestDoc->maTabs.size()));
for (SCTAB i = aNewRange.aStart.Tab(); i <= aNewRange.aEnd.Tab() && i < nMinSizeBothTabs; i++)
{
@@ -1931,7 +1928,6 @@ void ScDocument::UndoToDocument(const ScRange& rRange,
bool bOldAutoCalc = pDestDoc->GetAutoCalc();
pDestDoc->SetAutoCalc( false ); // avoid multiple calculations
sc::CopyToDocContext aCxt(*pDestDoc);
- aCxt.setTabRange(nTab1, nTab2);
if (nTab1 > 0)
CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, false, pDestDoc, pMarks );
@@ -2009,7 +2005,6 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam,
pClipDoc->ResetClip(this, pMarks);
sc::CopyToClipContext aCxt(*pClipDoc, bKeepScenarioFlags, bCloneNoteCaptions);
- aCxt.setTabRange(i, nEndTab-1);
CopyRangeNamesToClip(pClipDoc, aClipRange, pMarks, bAllTabs);
for ( ; i < nEndTab; ++i)
@@ -2107,7 +2102,6 @@ void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1,
pClipDoc->ResetClip( this, nTab );
sc::CopyToClipContext aCxt(*pClipDoc, false, true);
- aCxt.setTabRange(nTab, nTab);
if (nTab < static_cast<SCTAB>(maTabs.size()) && nTab < static_cast<SCTAB>(pClipDoc->maTabs.size()))
if (maTabs[nTab] && pClipDoc->maTabs[nTab])
maTabs[nTab]->CopyToClip(aCxt, nCol1, nRow1, nCol2, nRow2, pClipDoc->maTabs[nTab]);
@@ -2866,7 +2860,6 @@ void ScDocument::MixDocument( const ScRange& rRange, sal_uInt16 nFunction, bool
SCTAB nTab1 = rRange.aStart.Tab();
SCTAB nTab2 = rRange.aEnd.Tab();
sc::MixDocContext aCxt(*this);
- aCxt.setTabRange(nTab1, nTab2);
SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pSrcDoc->maTabs.size()));
for (SCTAB i = nTab1; i <= nTab2 && i < nMinSizeBothTabs; i++)
{
@@ -2905,9 +2898,7 @@ void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
SetAutoCalc( false ); // avoid multiple calculations
sc::CopyToDocContext aCxt(*this);
- aCxt.setTabRange(rMark.GetFirstSelected(), rMark.GetLastSelected());
sc::MixDocContext aMixDocCxt(*this);
- aMixDocCxt.setTabRange(rMark.GetFirstSelected(), rMark.GetLastSelected());
SCTAB nCount = static_cast<SCTAB>(maTabs.size());
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
@@ -2927,7 +2918,6 @@ void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
// context used for copying content to the temporary mix document.
sc::CopyToDocContext aMixCxt(*pMixDoc);
- aMixCxt.setTabRange(i, i);
maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
IDF_CONTENTS, false, pMixDoc->maTabs[i] );
}
@@ -2973,9 +2963,7 @@ void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
SCROW nEndRow = aArea.aEnd.Row();
sc::CopyToDocContext aCxt(*this);
- aCxt.setTabRange(rMark.GetFirstSelected(), rMark.GetLastSelected());
sc::MixDocContext aMixDocCxt(*this);
- aMixDocCxt.setTabRange(rMark.GetFirstSelected(), rMark.GetLastSelected());
SCTAB nCount = static_cast<SCTAB>(maTabs.size());
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd && *itr < nCount; ++itr)
@@ -2993,7 +2981,6 @@ void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
pMixDoc->AddUndoTab( i, i );
sc::CopyToDocContext aMixCxt(*pMixDoc);
- aMixCxt.setTabRange(i, i);
maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
IDF_CONTENTS, true, pMixDoc->maTabs[i], &rMark );
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 4af76be..51801af 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -407,7 +407,6 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
nWhichArray[2] = 0;
sc::CopyToDocContext aCxt(*pDocument);
- aCxt.setTabRange(nTab, nTab);
for (SCSIZE i=0; i<nSize; i++)
{
aCol[nStartCol-1].CopyToColumn(aCxt, nStartRow, nEndRow, IDF_ATTRIB,
commit 252a30609357a5b2691b7796cc8f3f4f1319f655
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 16:39:15 2013 -0400
Keep track of column block positions in ScDocumentImport too.
This currently only affects document import via orcus, but it'll be
good to put this in place.
Change-Id: I8cc6d54aba6fab1f2774127f92c2a764f7b690fb
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index eeafbba..afd954b 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -15,10 +15,13 @@
#include "rtl/ustring.hxx"
+#include <boost/noncopyable.hpp>
+
class ScDocument;
class ScAddress;
class ScTokenArray;
class ScBaseCell;
+struct ScDocumentImportImpl;
/**
* Accessor class to ScDocument. Its purpose is to allow import filter to
@@ -27,15 +30,15 @@ class ScBaseCell;
* position calculation, or anything else that requires expensive
* computation which are unnecessary and undesirable during import.
*/
-class SC_DLLPUBLIC ScDocumentImport
+class SC_DLLPUBLIC ScDocumentImport : boost::noncopyable
{
- ScDocument& mrDoc;
+ ScDocumentImportImpl* mpImpl;
ScDocumentImport(); // disabled
public:
ScDocumentImport(ScDocument& rDoc);
- ScDocumentImport(const ScDocumentImport& r);
+ ~ScDocumentImport();
ScDocument& getDoc();
const ScDocument& getDoc() const;
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index b21f7c7..1628381 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -10,6 +10,7 @@
#ifndef SC_MTVELEMENTS_HXX
#define SC_MTVELEMENTS_HXX
+#include "address.hxx"
#include "svl/broadcast.hxx"
#define DEBUG_COLUMN_STORAGE 0
@@ -25,6 +26,10 @@
#include <mdds/multi_type_vector.hpp>
#include <mdds/multi_type_vector_custom_func1.hpp>
+#include <boost/unordered_map.hpp>
+
+class ScDocument;
+
namespace sc {
struct CellTextAttr
@@ -74,6 +79,20 @@ struct ColumnBlockPosition
CellTextAttrStoreType::iterator miCellTextAttrPos;
};
+class ColumnBlockPositionSet
+{
+ typedef boost::unordered_map<SCCOL, ColumnBlockPosition> ColumnsType;
+ typedef boost::unordered_map<SCTAB, ColumnsType> TablesType;
+
+ ScDocument& mrDoc;
+ TablesType maTables;
+
+public:
+ ColumnBlockPositionSet(ScDocument& rDoc);
+
+ ColumnBlockPosition* getBlockPosition(SCTAB nTab, SCCOL nCol);
+};
+
}
#endif
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index c92688f..ced0936 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -15,24 +15,36 @@
#include "formulacell.hxx"
#include "docoptio.hxx"
#include "globalnames.hxx"
+#include "mtvelements.hxx"
-ScDocumentImport::ScDocumentImport(ScDocument& rDoc) : mrDoc(rDoc) {}
-ScDocumentImport::ScDocumentImport(const ScDocumentImport& r) : mrDoc(r.mrDoc) {}
+struct ScDocumentImportImpl
+{
+ ScDocument& mrDoc;
+ sc::ColumnBlockPositionSet maBlockPosSet;
+
+ ScDocumentImportImpl(ScDocument& rDoc) : mrDoc(rDoc), maBlockPosSet(rDoc) {}
+};
+
+ScDocumentImport::ScDocumentImport(ScDocument& rDoc) : mpImpl(new ScDocumentImportImpl(rDoc)) {}
+ScDocumentImport::~ScDocumentImport()
+{
+ delete mpImpl;
+}
ScDocument& ScDocumentImport::getDoc()
{
- return mrDoc;
+ return mpImpl->mrDoc;
}
const ScDocument& ScDocumentImport::getDoc() const
{
- return mrDoc;
+ return mpImpl->mrDoc;
}
SCTAB ScDocumentImport::getSheetIndex(const OUString& rName) const
{
SCTAB nTab = -1;
- if (!mrDoc.GetTable(rName, nTab))
+ if (!mpImpl->mrDoc.GetTable(rName, nTab))
return -1;
return nTab;
@@ -40,33 +52,34 @@ SCTAB ScDocumentImport::getSheetIndex(const OUString& rName) const
SCTAB ScDocumentImport::getSheetCount() const
{
- return mrDoc.maTabs.size();
+ return mpImpl->mrDoc.maTabs.size();
}
bool ScDocumentImport::appendSheet(const OUString& rName)
{
- SCTAB nTabCount = mrDoc.maTabs.size();
+ SCTAB nTabCount = mpImpl->mrDoc.maTabs.size();
if (!ValidTab(nTabCount))
return false;
- mrDoc.maTabs.push_back(new ScTable(&mrDoc, nTabCount, rName));
+ mpImpl->mrDoc.maTabs.push_back(new ScTable(&mpImpl->mrDoc, nTabCount, rName));
return true;
}
void ScDocumentImport::setOriginDate(sal_uInt16 nYear, sal_uInt16 nMonth, sal_uInt16 nDay)
{
- if (!mrDoc.pDocOptions)
- mrDoc.pDocOptions = new ScDocOptions;
+ if (!mpImpl->mrDoc.pDocOptions)
+ mpImpl->mrDoc.pDocOptions = new ScDocOptions;
- mrDoc.pDocOptions->SetDate(nDay, nMonth, nYear);
+ mpImpl->mrDoc.pDocOptions->SetDate(nDay, nMonth, nYear);
}
void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr)
{
- if (!mrDoc.TableExists(rPos.Tab()))
+ if (!mpImpl->mrDoc.TableExists(rPos.Tab()))
return;
- mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()].SetString(rPos.Row(), rPos.Tab(), rStr, mrDoc.GetAddressConvention());
+ mpImpl->mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()].SetString(
+ rPos.Row(), rPos.Tab(), rStr, mpImpl->mrDoc.GetAddressConvention());
}
void ScDocumentImport::setNumericCell(const ScAddress& rPos, double fVal)
@@ -82,18 +95,18 @@ void ScDocumentImport::setStringCell(const ScAddress& rPos, const OUString& rStr
void ScDocumentImport::setFormulaCell(
const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar)
{
- insertCell(rPos, new ScFormulaCell(&mrDoc, rPos, rFormula, eGrammar));
+ insertCell(rPos, new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
}
void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray)
{
- insertCell(rPos, new ScFormulaCell(&mrDoc, rPos, &rArray));
+ insertCell(rPos, new ScFormulaCell(&mpImpl->mrDoc, rPos, &rArray));
}
void ScDocumentImport::finalize()
{
// Populate the text width and script type arrays in all columns.
- ScDocument::TableContainer::iterator itTab = mrDoc.maTabs.begin(), itTabEnd = mrDoc.maTabs.end();
+ ScDocument::TableContainer::iterator itTab = mpImpl->mrDoc.maTabs.begin(), itTabEnd = mpImpl->mrDoc.maTabs.end();
for (; itTab != itTabEnd; ++itTab)
{
if (!*itTab)
@@ -119,14 +132,18 @@ void ScDocumentImport::finalize()
void ScDocumentImport::insertCell(const ScAddress& rPos, ScBaseCell* pCell)
{
- if (!mrDoc.TableExists(rPos.Tab()))
+ if (!mpImpl->mrDoc.TableExists(rPos.Tab()))
{
pCell->Delete();
return;
}
- ScColumn& rCol = mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()];
- rCol.SetCell(rPos.Row(), pCell);
+ ScColumn& rCol = mpImpl->mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()];
+ sc::ColumnBlockPosition* p = mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ if (p)
+ rCol.SetCell(*p, rPos.Row(), pCell);
+ else
+ rCol.SetCell(rPos.Row(), pCell);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx
index 45c06dd..efe07cf 100644
--- a/sc/source/core/data/mtvelements.cxx
+++ b/sc/source/core/data/mtvelements.cxx
@@ -9,6 +9,7 @@
#include "mtvelements.hxx"
#include "globalnames.hxx"
+#include "document.hxx"
namespace sc {
@@ -24,6 +25,45 @@ CellTextAttr::CellTextAttr(sal_uInt16 nTextWidth, sal_uInt8 nScriptType) :
mnTextWidth(nTextWidth),
mnScriptType(nScriptType) {}
+ColumnBlockPositionSet::ColumnBlockPositionSet(ScDocument& rDoc) : mrDoc(rDoc) {}
+
+ColumnBlockPosition* ColumnBlockPositionSet::getBlockPosition(SCTAB nTab, SCCOL nCol)
+{
+ TablesType::iterator itTab = maTables.find(nTab);
+ if (itTab == maTables.end())
+ {
+ std::pair<TablesType::iterator,bool> r =
+ maTables.insert(TablesType::value_type(nTab, ColumnsType()));
+ if (!r.second)
+ // insertion failed.
+ return NULL;
+
+ itTab = r.first;
+ }
+
+ ColumnsType& rCols = itTab->second;
+
+ ColumnsType::iterator it = rCols.find(nCol);
+ if (it != rCols.end())
+ // Block position for this column has already been fetched.
+ return &it->second;
+
+ std::pair<ColumnsType::iterator,bool> r =
+ rCols.insert(
+ ColumnsType::value_type(nCol, ColumnBlockPosition()));
+
+ if (!r.second)
+ // insertion failed.
+ return NULL;
+
+ it = r.first;
+
+ if (!mrDoc.InitColumnBlockPosition(it->second, nTab, nCol))
+ return NULL;
+
+ return &it->second;
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 430d81e1fd44f51a91b81da91504a004ab7373d8
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 17 15:08:23 2013 -0400
Same with MixDocument(). But this one has additional bottleneck...
With the removal of existing cells. So, this change is not enough to
make this operation fly.
Change-Id: Ic468375f6d0c28e2cc7d5391fb0565d53ee7fb4e
diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx
index 4d9224f..599da6e 100644
--- a/sc/inc/clipcontext.hxx
+++ b/sc/inc/clipcontext.hxx
@@ -90,6 +90,13 @@ public:
virtual ~CopyToDocContext();
};
+class MixDocContext : public ClipContextBase
+{
+public:
+ MixDocContext(ScDocument& rDoc);
+ virtual ~MixDocContext();
+};
+
}
#endif
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 0e7ed53..c71ffea 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -41,6 +41,7 @@ namespace sc {
class CopyFromClipContext;
class CopyToClipContext;
class CopyToDocContext;
+ class MixDocContext;
struct ColumnBlockPosition;
}
@@ -231,10 +232,12 @@ public:
void RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow );
// Selection (?) of this document
- void MixMarked( const ScMarkData& rMark, sal_uInt16 nFunction,
- bool bSkipEmpty, ScColumn& rSrcCol );
- void MixData( SCROW nRow1, SCROW nRow2, sal_uInt16 nFunction, bool bSkipEmpty,
- ScColumn& rSrcCol );
+ void MixMarked(
+ sc::MixDocContext& rCxt, const ScMarkData& rMark, sal_uInt16 nFunction,
+ bool bSkipEmpty, const ScColumn& rSrcCol );
+ void MixData(
+ sc::MixDocContext& rCxt, SCROW nRow1, SCROW nRow2, sal_uInt16 nFunction, bool bSkipEmpty,
+ const ScColumn& rSrcCol );
ScFormulaCell* CreateRefCell( ScDocument* pDestDoc, const ScAddress& rDestPos,
SCSIZE nIndex, sal_uInt16 nFlags ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 5f63d85..f01e811 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1988,6 +1988,8 @@ private: // CLOOK-Impl-methods
};
bool TableExists( SCTAB nTab ) const;
+ ScTable* FetchTable( SCTAB nTab );
+ const ScTable* FetchTable( SCTAB nTab ) const;
void MergeNumberFormatter(ScDocument* pSrcDoc);
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 7d0836f..f04a9bb 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -53,6 +53,7 @@ namespace sc {
class CopyFromClipContext;
class CopyToClipContext;
class CopyToDocContext;
+ class MixDocContext;
struct ColumnBlockPosition;
}
@@ -412,10 +413,13 @@ public:
ScTable* pTransClip, sal_uInt16 nFlags, bool bAsLink );
// mark of this document
- void MixMarked( const ScMarkData& rMark, sal_uInt16 nFunction,
- bool bSkipEmpty, ScTable* pSrcTab );
- void MixData( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- sal_uInt16 nFunction, bool bSkipEmpty, ScTable* pSrcTab );
+ void MixMarked(
+ sc::MixDocContext& rCxt, const ScMarkData& rMark, sal_uInt16 nFunction,
+ bool bSkipEmpty, const ScTable* pSrcTab );
+
+ void MixData(
+ sc::MixDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ sal_uInt16 nFunction, bool bSkipEmpty, const ScTable* pSrcTab );
void CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab );
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 8777aa3..2c7abdf 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -120,6 +120,9 @@ bool CopyToClipContext::isCloneNotes() const
CopyToDocContext::CopyToDocContext(ScDocument& rDoc) : ClipContextBase(rDoc) {}
CopyToDocContext::~CopyToDocContext() {}
+MixDocContext::MixDocContext(ScDocument& rDoc) : ClipContextBase(rDoc) {}
+MixDocContext::~MixDocContext() {}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index a29f791..b530184 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -828,8 +828,9 @@ ScBaseCell* ScColumn::CloneCell(
}
-void ScColumn::MixMarked( const ScMarkData& rMark, sal_uInt16 nFunction,
- bool bSkipEmpty, ScColumn& rSrcCol )
+void ScColumn::MixMarked(
+ sc::MixDocContext& rCxt, const ScMarkData& rMark, sal_uInt16 nFunction,
+ bool bSkipEmpty, const ScColumn& rSrcCol )
{
SCROW nRow1, nRow2;
@@ -837,7 +838,7 @@ void ScColumn::MixMarked( const ScMarkData& rMark, sal_uInt16 nFunction,
{
ScMarkArrayIter aIter( rMark.GetArray()+nCol );
while (aIter.Next( nRow1, nRow2 ))
- MixData( nRow1, nRow2, nFunction, bSkipEmpty, rSrcCol );
+ MixData(rCxt, nRow1, nRow2, nFunction, bSkipEmpty, rSrcCol);
}
}
@@ -885,9 +886,9 @@ static void lcl_AddCode( ScTokenArray& rArr, ScFormulaCell* pCell )
}
-void ScColumn::MixData( SCROW nRow1, SCROW nRow2,
- sal_uInt16 nFunction, bool bSkipEmpty,
- ScColumn& rSrcCol )
+void ScColumn::MixData(
+ sc::MixDocContext& rCxt, SCROW nRow1, SCROW nRow2, sal_uInt16 nFunction,
+ bool bSkipEmpty, const ScColumn& rSrcCol )
{
SCSIZE nSrcCount = rSrcCol.maItems.size();
@@ -1023,12 +1024,18 @@ void ScColumn::MixData( SCROW nRow1, SCROW nRow2,
if ( pNew || bDelete ) // New result?
{
+ sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
if (pDest && !pNew) // Old cell present?
{
Delete(nRow); // -> Delete
}
if (pNew)
- Insert(nRow, pNew); // Insert new one
+ {
+ if (p)
+ Insert(*p, nRow, pNew);
+ else
+ Insert(nRow, pNew); // Insert new one
+ }
Search( nRow, nIndex ); // Everything could have moved
if (pNew)
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 6ca6fc0..5fbc1ac0 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2264,6 +2264,22 @@ bool ScDocument::TableExists( SCTAB nTab ) const
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list