[ooo-build-commit] Branch 'ooo/master' - 3 commits - chart2/source sc/inc sc/source

Jan Holesovsky kendy at kemper.freedesktop.org
Fri Jul 3 17:12:48 PDT 2009


 chart2/source/controller/main/ChartController.cxx |    5 
 chart2/source/controller/main/ChartWindow.cxx     |   28 
 chart2/source/controller/main/ChartWindow.hxx     |    6 
 sc/inc/cell.hxx                                   |    2 
 sc/inc/compiler.hxx                               |    1 
 sc/inc/document.hxx                               |   13 
 sc/inc/docuno.hxx                                 |    2 
 sc/inc/drwlayer.hxx                               |    6 
 sc/inc/postit.hxx                                 |  177 ++++--
 sc/inc/reftokenhelper.hxx                         |    3 
 sc/inc/table.hxx                                  |   15 
 sc/source/core/data/attarray.cxx                  |    5 
 sc/source/core/data/cell.cxx                      |    4 
 sc/source/core/data/column.cxx                    |   15 
 sc/source/core/data/column3.cxx                   |    3 
 sc/source/core/data/documen2.cxx                  |    3 
 sc/source/core/data/documen5.cxx                  |    8 
 sc/source/core/data/document.cxx                  |   42 +
 sc/source/core/data/drwlayer.cxx                  |   22 
 sc/source/core/data/makefile.mk                   |    1 
 sc/source/core/data/postit.cxx                    |  645 +++++++++++++++-------
 sc/source/core/data/table1.cxx                    |    7 
 sc/source/core/data/table2.cxx                    |   38 +
 sc/source/core/data/table6.cxx                    |    2 
 sc/source/core/tool/compiler.cxx                  |    5 
 sc/source/core/tool/detfunc.cxx                   |    2 
 sc/source/core/tool/editutil.cxx                  |    4 
 sc/source/core/tool/reftokenhelper.cxx            |    4 
 sc/source/filter/excel/colrowst.cxx               |    6 
 sc/source/filter/excel/xechart.cxx                |    5 
 sc/source/filter/excel/xeescher.cxx               |   11 
 sc/source/filter/excel/xiescher.cxx               |   32 -
 sc/source/filter/html/htmlpars.cxx                |  335 ++++++-----
 sc/source/filter/inc/htmlpars.hxx                 |  359 ++++++------
 sc/source/filter/lotus/op.cxx                     |    2 
 sc/source/filter/starcalc/scflt.cxx               |    2 
 sc/source/filter/xml/xmlannoi.cxx                 |   94 +--
 sc/source/filter/xml/xmlannoi.hxx                 |   53 +
 sc/source/filter/xml/xmlcelli.cxx                 |  164 +++--
 sc/source/filter/xml/xmlcelli.hxx                 |   22 
 sc/source/filter/xml/xmlexprt.cxx                 |    1 
 sc/source/filter/xml/xmlimprt.cxx                 |   37 +
 sc/source/filter/xml/xmlimprt.hxx                 |    1 
 sc/source/filter/xml/xmlstyli.cxx                 |    8 
 sc/source/filter/xml/xmlsubti.cxx                 |   32 +
 sc/source/ui/app/inputhdl.cxx                     |   45 +
 sc/source/ui/app/inputwin.cxx                     |    2 
 sc/source/ui/docshell/docfunc.cxx                 |   27 
 sc/source/ui/docshell/docsh4.cxx                  |   14 
 sc/source/ui/docshell/docsh5.cxx                  |   44 +
 sc/source/ui/drawfunc/fuins2.cxx                  |    4 
 sc/source/ui/drawfunc/futext3.cxx                 |    2 
 sc/source/ui/inc/docfunc.hxx                      |    1 
 sc/source/ui/inc/docsh.hxx                        |    3 
 sc/source/ui/undo/undoblk3.cxx                    |   12 
 sc/source/ui/undo/undocell.cxx                    |   11 
 sc/source/ui/unoobj/chart2uno.cxx                 |   16 
 sc/source/ui/unoobj/docuno.cxx                    |   35 -
 sc/source/ui/unoobj/editsrc.cxx                   |    3 
 sc/source/ui/unoobj/notesuno.cxx                  |    6 
 sc/source/ui/vba/vbacontrol.cxx                   |    9 
 sc/source/ui/view/cellsh1.cxx                     |    1 
 sc/source/ui/view/cellsh2.cxx                     |    4 
 sc/source/ui/view/gridwin.cxx                     |    1 
 sc/source/ui/view/preview.cxx                     |    4 
 sc/source/ui/view/printfun.cxx                    |    1 
 sc/source/ui/view/tabview3.cxx                    |    4 
 sc/source/ui/view/tabvwsh4.cxx                    |    4 
 sc/source/ui/view/tabvwsh5.cxx                    |    5 
 sc/source/ui/view/viewfun6.cxx                    |    6 
 sc/source/ui/view/viewfunc.cxx                    |    1 
 71 files changed, 1610 insertions(+), 887 deletions(-)

New commits:
commit 7891c97150152346a2070e1c9c7a32b28eec4423
Author: Release Engineers <releng at openoffice.org>
Date:   Fri Jul 3 14:21:50 2009 +0000

    CWS-TOOLING: integrate CWS dba32c
    2009-06-29 20:53:25 +0200 fs  r273484 : #i103138# Rectangle conversion
    2009-06-29 20:51:50 +0200 fs  r273483 : #i103138# yet more refactoring, now also setting the proper zoom level at the proper point in time
    2009-06-29 13:40:26 +0200 fs  r273470 : added svn:ignore to ignore output paths
    2009-06-29 10:08:54 +0200 fs  r273455 : #i103138#
    refactored the code for positioning/zooming the control
    Basically, we now allow adjustControlGeometry_throw (formerly known as positionControl_throw and setControlZoom) to
    take an additional ViewTransformation parameter, describing the transformation to obtain the actual
    control position/size. Consequently, positionControl itself also allows for a ViewTransformation parameter.
    This has become necessary since during painting, the device which we created our control for might not necessarily
    have a proper MapMode set. In this case, if we would use this map mode for calculating the control's position/size,
    this would lead to wrong results.
    Note that this problem was introduced by the fix for #i101398#: During the fix, we postponed the control creation
    to a later time (when it is really needed). At this later time, the MapMode at the device is broken, at the earlier
    time where we formerly crearted the control (createPrimitive2DSequence), it is not yet broken.
    Whether or not the MapMode is defined as "broken" might depend on one's point of view, however ...
    I consider it broken, since:
    - we need the map mode to obtain the proper zoom level, which is to be forwarded to the control
    - there are scenarios where the MapMode is *not* set to MAP_PIXEL (in those scenarios, everything works
      fine), and there are scenarios where it *is* set to MAP_PIXEL (in those the bug 103138 appears).
    It somehow feels wrong that one cannot rely on the device's map mode this way, but on the other hand
    one has no possibility to obtain the current zoom by other means.
    Note that one issue (still to be submitted) is left: In the page pane of a Draw/Impress document, controls
    have a wrong text size. This is because in this pane, the above-mentioned "broken" map mode is used,
    which means the controls have a zoom of "1:1" set, which is wrong here.
    2009-06-25 13:41:35 +0200 msc  r273380 : #100000# the tabs changed die to new properties
    2009-06-24 12:42:40 +0200 msc  r273330 : #102082# remove issue warning
    2009-06-22 10:43:14 +0200 fs  r273201 : createPrimitive2DSequence: care for being disposed
    2009-06-18 12:35:13 +0200 oj  r273109 : #i102305# make nooptfiles for gcc
    2009-06-17 12:14:37 +0200 oj  r273056 : #i102305# fix for linux
    2009-06-17 07:20:22 +0200 oj  r273046 : #i102305# move ValueTransfer into the for loop to avoid a crash under Linux
    2009-06-17 07:17:28 +0200 oj  r273045 : #i102305# use varchar
    2009-06-15 14:11:27 +0200 fs  r272983 : added since tag
    2009-06-15 12:11:39 +0200 oj  r272973 : #i102305# SAL_DLLPUBLIC_EXPORT inserted
    2009-06-15 11:08:53 +0200 fs  r272969 : #i10000#
    2009-06-15 09:25:13 +0200 fs  r272963 : merging fix for P1 issue #i102701#
    2009-06-11 11:31:24 +0200 fs  r272858 : #i10000# copied the fix which before the rebase was done in ../dialog/macropg.src
    2009-06-11 09:38:14 +0200 fs  r272846 : CWS-TOOLING: rebase CWS dba32c to trunk at 272827 (milestone: DEV300:m50)
    2009-06-02 09:53:10 +0200 fs  r272483 : #i10000#
    2009-05-29 15:55:03 +0200 fs  r272465 : #i100818#
    2009-05-29 12:58:43 +0200 fs  r272452 : don't apply comphelper::getString on possibly VOID any
    2009-05-29 10:38:35 +0200 oj  r272437 : #i101519# handle where condition
    2009-05-29 09:53:39 +0200 fs  r272434 : #i100818# call into releaseStubs /without/ locked GlobalMutex
    2009-05-28 07:53:44 +0200 oj  r272375 : #i101369# parse tree changed
    2009-05-27 14:53:36 +0200 fs  r272347 : #i10000#
    2009-05-27 09:29:15 +0200 oj  r272327 : #i101626# check for double before hard cast
    2009-05-27 09:13:58 +0200 oj  r272326 : #i101626# handle void correctly
    2009-05-27 08:04:39 +0200 oj  r272321 : #i102256# wrong method signature used
    2009-05-27 07:55:52 +0200 oj  r272320 : #i101519# look up parameter typ if used in function
    2009-05-27 06:49:07 +0200 oj  r272319 : #i101519# set parameter from rowset as well
    2009-05-26 13:30:56 +0200 oj  r272297 : #i101987# impl XBatchExecution
    2009-05-26 12:44:34 +0200 oj  r272293 : #i101700# check if group is not set
    2009-05-26 12:16:53 +0200 oj  r272290 : #i101369# resolved some reduce7reduce problems with boolean_term and search_condition
    2009-05-26 12:12:42 +0200 oj  r272289 : #i101369# fix for or on one line criteria
    2009-05-25 16:02:25 +0200 fs  r272257 : #i999704# +PROPERTY_MOUSE_WHEEL_BEHAVIOR
    2009-05-25 16:01:55 +0200 fs  r272256 : merging the changes from CWS dba32b herein
    2009-05-25 15:49:57 +0200 fs  r272254 : #i999704#
    2009-05-25 15:32:57 +0200 fs  r272252 : #i99704# grid columns also to respect the MouseWheelBehavior property
    2009-05-25 15:23:43 +0200 fs  r272251 : don't pass empty Anys to ::comphelper::getString
    2009-05-25 14:48:43 +0200 fs  r272248 : merged changes from CWS dba32b herein
    2009-05-25 14:44:40 +0200 fs  r272247 : #i99704# support new MouseWheelBehavior property
    2009-05-25 14:43:18 +0200 fs  r272246 : #i99704# WheelWithoutFocus (peer property) superseded by MouseWheelBehavior (model property)
    2009-05-25 14:41:03 +0200 fs  r272245 : #i99704# no need to set the mouse wheel behavior at the peer, this is now a model property, having the right default
    2009-05-25 14:39:31 +0200 fs  r272243 : removed dead import
    2009-05-25 14:35:36 +0200 fs  r272242 : the new EnableVisible doesn't make sense for grid columns
    2009-05-25 14:34:33 +0200 fs  r272241 : #i99704# +MouseWheelBehavior - allow to enable/disable the mouse wheel for the control, or make it focus-dependent
    2009-05-25 14:26:11 +0200 fs  r272240 : #i99704# change MouseSettings wheel flag (NoWheelActionWithoutFocus) to a three-state option, allowing to completely ignore the mouse wheel
    2009-05-23 21:35:59 +0200 fs  r272213 : localize 'sub component opened/closed' event
    2009-05-22 21:42:47 +0200 fs  r272211 : #i102003#
    2009-05-22 21:42:20 +0200 fs  r272210 : grammar
    2009-05-22 21:36:10 +0200 fs  r272209 : #i102140# load only once, not twice, and show error messages during loading (and during any form action, that is) asynchronously
    2009-05-22 21:35:11 +0200 fs  r272208 : #i102140# +clear
    2009-05-22 14:50:30 +0200 fs  r272194 : #i102139# for newly created DB docs, set the MacroExecutionMode to USE_CONFIG
    2009-05-22 12:03:42 +0200 fs  r272180 : #i88878#
    provided by noel.power at novell.com
    implement a visibility property (EnableVisible) for toolkit controls, and usage in forms and UNO dialogs
    2009-05-15 15:37:31 +0200 fs  r271942 : #i100671# corrected some @since tags, so autodoc has better chances of correctly reading them
    2009-05-15 15:33:11 +0200 fs  r271940 : don't call comphelper::getFOO for VOID values
    2009-05-15 15:08:31 +0200 fs  r271937 : includes
    2009-05-15 13:39:22 +0200 fs  r271934 : #i101398# createPrimitive2DSequence: when we already have a control, use the old code. In particular, call positionControlForPaint
    2009-05-15 12:33:48 +0200 fs  r271933 : make the geometry a part of the ControlPrimitive2D's identity
    2009-05-15 10:15:44 +0200 fs  r271928 : #i10000#
    2009-05-14 20:55:38 +0200 fs  r271921 : #i101398# don't reuse the name PRIMITIVE_ID_CONTROLPRIMITIVE2D, make the name of our own ControlPrimitive2D unique
    2009-05-14 20:55:31 +0200 fs  r271920 : #i101398# don't reuse the name PRIMITIVE_ID_CONTROLPRIMITIVE2D, make the name of our own ControlPrimitive2D unique
    2009-05-14 20:23:23 +0200 fs  r271919 : #i101622#
    2009-05-14 16:04:38 +0200 fs  r271898 : don't use comphelper::getInt32 on voids
    2009-05-14 16:04:12 +0200 fs  r271897 : merge fix for issue whose number just slipped my memory ... (originally fixed in CWS dba32b)
    2009-05-14 15:36:55 +0200 fs  r271895 : merging changes from DEV300:m48
    2009-05-07 14:43:19 +0200 fs  r271670 : #i101477#
    2009-05-07 14:37:30 +0200 fs  r271668 : #i101477#
    2009-05-07 09:27:30 +0200 oj  r271628 : #i101343# remove pch
    2009-05-06 09:36:02 +0200 fs  r271568 : getFoo: diagnostics
    2009-05-04 09:23:06 +0200 oj  r271438 : CWS-TOOLING: rebase CWS dba32c to trunk at 271427 (milestone: DEV300:m47)
    2009-04-29 23:18:13 +0200 fs  r271394 : #i101398# use a dedicated 2DPrimitive for UNO Controls, which is able to provide the B2DRange *without* actually creating the control
    2009-04-29 13:52:25 +0200 fs  r271366 : #i101308#

diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
index 1138a1b..af1a902 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -391,6 +391,9 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS
     rEscherEx.OpenContainer( ESCHER_SpContainer );
     rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
     EscherPropertyContainer aPropOpt;
+    bool bVisible = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "EnableVisible" ) );
+    aPropOpt.AddOpt( ESCHER_Prop_fPrint, bVisible ? 0x00080000 : 0x00080002 ); // visible flag
+
     aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01000100 ); // bool field
     aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 );                        // Text ID
     aPropOpt.AddOpt( ESCHER_Prop_WrapText, 0x00000001 );
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index 19d831e..98e8719 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -1698,7 +1698,7 @@ void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) co
     aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
 
     // control visible and printable?
-//    aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );     // waiting for #i88878#
+    aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
     aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
 
     // sheet links
diff --git a/sc/source/ui/vba/vbacontrol.cxx b/sc/source/ui/vba/vbacontrol.cxx
index 666c553..dd4b637 100644
--- a/sc/source/ui/vba/vbacontrol.cxx
+++ b/sc/source/ui/vba/vbacontrol.cxx
@@ -185,14 +185,15 @@ void SAL_CALL ScVbaControl::setEnabled( sal_Bool bVisible ) throw (uno::RuntimeE
 
 sal_Bool SAL_CALL ScVbaControl::getVisible() throw (uno::RuntimeException)
 {
-    uno::Reference< awt::XWindow2 > xWindow2( getWindowPeer(), uno::UNO_QUERY_THROW );
-    return xWindow2->isVisible();
+    sal_Bool bVisible = sal_False;
+    m_xProps->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableVisible" ) ) ) >>= bVisible;
+    return bVisible;
 }
 
 void SAL_CALL ScVbaControl::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException)
 {
-    uno::Reference< awt::XWindow2 > xWindow2( getWindowPeer(), uno::UNO_QUERY_THROW );
-    xWindow2->setVisible( bVisible );
+    m_xProps->setPropertyValue
+            (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableVisible" ) ), uno::makeAny( bVisible ) );
 }
 double SAL_CALL ScVbaControl::getHeight() throw (uno::RuntimeException)
 {
commit 2b954fb11782e3e0f5a02ca496fdd4713a6f997d
Author: Release Engineers <releng at openoffice.org>
Date:   Fri Jul 3 12:42:53 2009 +0000

    CWS-TOOLING: integrate CWS dr70
    2009-06-09 13:52:02 +0200 dr  r272770 : #i101930# SXC import broken
    2009-06-05 11:50:16 +0200 dr  r272675 : #i10000# compiler warning
    2009-06-05 11:24:39 +0200 dr  r272674 : #i10000# compiler warning
    2009-06-05 10:35:22 +0200 dr  r272668 : #i10000# compiler warning
    2009-06-04 16:53:32 +0200 dr  r272646 : CWS-TOOLING: rebase CWS dr70 to trunk at 272291 (milestone: DEV300:m49)
    2009-06-04 14:50:45 +0200 dr  r272633 : #i10000# compiler warning
    2009-06-03 18:50:57 +0200 dr  r272603 : #i101930# fix ODS export of uninit'ed notes, do not craete note captions in UpdatePendingRowHeights
    2009-05-28 11:11:17 +0200 dr  r272384 : #i101930# note captions must be created before changing row/column size
    2009-05-27 15:48:44 +0200 iha  r272356 : #i101925# metafile creation is requested superfluously during inplace editing
    2009-05-27 15:46:44 +0200 iha  r272355 : #i101925# metafile creation is requested superfluously during inplace editing
    2009-05-27 15:06:58 +0200 iha  r272349 : #i101928# superfluous paint calls while entering and editing charts
    2009-05-27 15:01:08 +0200 iha  r272348 : #i101928# superfluous paint calls while entering and editing charts
    2009-05-26 14:43:39 +0200 dr  r272303 : #i101930# import performance: invisible cell notes cache caption data
    2009-05-22 18:44:19 +0200 dr  r272205 : #i101930# preparations for uninitialized notes (performance), adapted ODF import filter
    2009-05-14 19:50:43 +0200 dr  r271918 : #i101930# 'recycle' the shapes already created while loading cell notes
    2009-05-06 16:07:45 +0200 dr  r271598 : #i100827# improve performance of HTML query filter, patch by mmeeks, slightly modified
    2009-05-06 11:02:38 +0200 dr  r271577 : #i100827# improve performance of HTML query filter, patch by mmeeks
    2009-05-06 10:50:13 +0200 dr  r271575 : #i86650# improve performance of HTML query filter
    2009-05-05 10:09:44 +0200 nn  r271502 : #i101428# better handling of non-existing view data
    2009-04-29 16:42:57 +0200 nn  r271384 : #i101428# after loading, update row heights per sheet on demand

diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx
index 8d14850..9437abc 100644
--- a/chart2/source/controller/main/ChartController.cxx
+++ b/chart2/source/controller/main/ChartController.cxx
@@ -468,7 +468,7 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent
     {
         //the view has become dirty, we should repaint it if we have a window
         if( m_pChartWindow )
-            m_pChartWindow->Invalidate();
+            m_pChartWindow->ForceInvalidate();
     }
     else if( rEvent.NewMode.equals(C2U("invalid")) )
     {
@@ -478,8 +478,11 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent
         if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
             this->EndTextEdit();
         if( m_pDrawViewWrapper )
+        {
             m_pDrawViewWrapper->UnmarkAll();
             //m_pDrawViewWrapper->hideMarkHandles(); todo??
+            m_pDrawViewWrapper->HideSdrPage();
+        }
     }
     else
     {
diff --git a/chart2/source/controller/main/ChartWindow.cxx b/chart2/source/controller/main/ChartWindow.cxx
index af952b4..2ea9f14 100644
--- a/chart2/source/controller/main/ChartWindow.cxx
+++ b/chart2/source/controller/main/ChartWindow.cxx
@@ -60,6 +60,7 @@ namespace chart
 ChartWindow::ChartWindow( WindowController* pWindowController, Window* pParent, WinBits nStyle )
         : Window(pParent, nStyle)
         , m_pWindowController( pWindowController )
+        , m_bInPaint(false)
 {
     this->SetSmartHelpId( SmartId( HID_SCH_WIN_DOCUMENT ) );
     this->SetMapMode( MapMode(MAP_100TH_MM) );
@@ -67,7 +68,7 @@ ChartWindow::ChartWindow( WindowController* pWindowController, Window* pParent,
     // chart does not depend on exact pixel painting => enable antialiased drawing
     SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW | GetAntialiasing() );
     EnableRTL( FALSE );
-    if( pParent )
+    if( pParent )
         pParent->EnableRTL( FALSE );// #i96215# necessary for a correct position of the context menu in rtl mode
 }
 
@@ -92,10 +93,12 @@ void ChartWindow::PrePaint()
 
 void ChartWindow::Paint( const Rectangle& rRect )
 {
+    m_bInPaint = true;
     if( m_pWindowController )
         m_pWindowController->execute_Paint( rRect );
     else
         Window::Paint( rRect );
+    m_bInPaint = false;
 }
 
 void ChartWindow::MouseButtonDown(const MouseEvent& rMEvt)
@@ -243,6 +246,29 @@ void ChartWindow::adjustHighContrastMode()
     SetDrawMode( bUseContrast ? nContrastMode : DRAWMODE_DEFAULT );
 }
 
+void ChartWindow::ForceInvalidate()
+{
+    ::Window::Invalidate();
+}
+void ChartWindow::Invalidate( USHORT nFlags )
+{
+    if( m_bInPaint ) // #i101928# superfluous paint calls while entering and editing charts"
+        return;
+    ::Window::Invalidate( nFlags );
+}
+void ChartWindow::Invalidate( const Rectangle& rRect, USHORT nFlags )
+{
+    if( m_bInPaint ) // #i101928# superfluous paint calls while entering and editing charts"
+        return;
+    ::Window::Invalidate( rRect, nFlags );
+}
+void ChartWindow::Invalidate( const Region& rRegion, USHORT nFlags )
+{
+    if( m_bInPaint ) // #i101928# superfluous paint calls while entering and editing charts"
+        return;
+    ::Window::Invalidate( rRegion, nFlags );
+}
+
 //.............................................................................
 } //namespace chart
 //.............................................................................
diff --git a/chart2/source/controller/main/ChartWindow.hxx b/chart2/source/controller/main/ChartWindow.hxx
index 4e63356..371b3bb 100644
--- a/chart2/source/controller/main/ChartWindow.hxx
+++ b/chart2/source/controller/main/ChartWindow.hxx
@@ -70,10 +70,16 @@ public:
     virtual void DataChanged( const DataChangedEvent& rDCEvt );
     virtual void RequestHelp( const HelpEvent& rHEvt );
 
+    void ForceInvalidate();
+    virtual void Invalidate( USHORT nFlags = 0 );
+    virtual void Invalidate( const Rectangle& rRect, USHORT nFlags = 0 );
+    virtual void Invalidate( const Region& rRegion, USHORT nFlags = 0 );
+
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
 
 private:
     WindowController*    m_pWindowController;
+    bool m_bInPaint;
 
     void adjustHighContrastMode();
 };
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 1bdbc1a..6c5ddcf 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -102,7 +102,7 @@ public:
 
     /** Returns a clone of this cell, clones cell note and caption object too
         (unless SC_CLONECELL_NOCAPTION flag is set). Broadcaster will not be cloned. */
-    ScBaseCell*     CloneWithNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
+    ScBaseCell*     CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
 
     /** Due to the fact that ScBaseCell does not have a vtable, this function
         deletes the cell by calling the appropriate d'tor of the derived class. */
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 451c590..d7bbc47 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -580,6 +580,8 @@ public:
     SC_DLLPUBLIC void			TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos);
     SC_DLLPUBLIC void			SetVisible( SCTAB nTab, BOOL bVisible );
     SC_DLLPUBLIC BOOL			IsVisible( SCTAB nTab ) const;
+    BOOL            IsPendingRowHeights( SCTAB nTab ) const;
+    void            SetPendingRowHeights( SCTAB nTab, BOOL bSet );
     SC_DLLPUBLIC void			SetLayoutRTL( SCTAB nTab, BOOL bRTL );
     SC_DLLPUBLIC BOOL			IsLayoutRTL( SCTAB nTab ) const;
     BOOL			IsNegativePage( SCTAB nTab ) const;
@@ -774,6 +776,12 @@ public:
     SC_DLLPUBLIC ScPostIt* GetOrCreateNote( const ScAddress& rPos );
     /** Deletes the note at the passed cell address. */
     void            DeleteNote( const ScAddress& rPos );
+    /** Creates the captions of all uninitialized cell notes in the specified sheet.
+        @param bForced  True = always create all captions, false = skip when Undo is disabled. */
+    void            InitializeNoteCaptions( SCTAB nTab, bool bForced = false );
+    /** Creates the captions of all uninitialized cell notes in all sheets.
+        @param bForced  True = always create all captions, false = skip when Undo is disabled. */
+    void            InitializeAllNoteCaptions( bool bForced = false );
 
     BOOL            ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow,
                                 SCCOL& rEndCol, SCROW& rEndRow, const ScMarkData& rMark,
@@ -1240,7 +1248,8 @@ public:
                                         BOOL bShrink );
     void            UpdateAllRowHeights( OutputDevice* pDev,
                                         double nPPTX, double nPPTY,
-                                        const Fraction& rZoomX, const Fraction& rZoomY );
+                                        const Fraction& rZoomX, const Fraction& rZoomY,
+                                        const ScMarkData* pTabMark = NULL );
     long			GetNeededSize( SCCOL nCol, SCROW nRow, SCTAB nTab,
                                     OutputDevice* pDev,
                                     double nPPTX, double nPPTY,
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index f851103..bc51c74 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -125,7 +125,7 @@ public:
     ScDocument*				GetDocument() const;
     SfxObjectShell*         GetEmbeddedObject() const;
 
-    void                    UpdateAllRowHeights();
+    void                    UpdateAllRowHeights( const ScMarkData* pTabMark = NULL );
 
     ScDrawLayer*	                        MakeDrawLayer();
     void                    BeforeXMLLoading();
diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index a08fd60..faa6b8b 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -115,11 +115,7 @@ private:
     void			MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
                                 SCsCOL nDx,SCsROW nDy );
 
-    void			RecalcPos( SdrObject* pObj,
-                        const ScDrawObjData& rData,
-                        const ScAddress& rOldStart,
-                        const ScAddress& rOldEnd,
-                        bool bNegativePage );
+    void            RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage );
 
 public:
                     ScDrawLayer( ScDocument* pDocument, const String& rName );
diff --git a/sc/inc/postit.hxx b/sc/inc/postit.hxx
index 979fea6..ee90a71 100644
--- a/sc/inc/postit.hxx
+++ b/sc/inc/postit.hxx
@@ -31,30 +31,42 @@
 #ifndef SC_POSTIT_HXX
 #define SC_POSTIT_HXX
 
+#include <boost/shared_ptr.hpp>
+#include <rtl/ustring.hxx>
 #include <tools/gen.hxx>
 #include "address.hxx"
 #include "scdllapi.h"
 
 class EditTextObject;
+class OutlinerParaObject;
 class SdrCaptionObj;
 class SdrPage;
 class SfxItemSet;
 class ScDocument;
+struct ScCaptionInitData;
 
 // ============================================================================
 
+/** Internal data for a cell annotation. */
 struct SC_DLLPUBLIC ScNoteData
 {
-    String              maDate;             /// Creation date of the note.
-    String              maAuthor;           /// Author of the note.
+    typedef ::boost::shared_ptr< ScCaptionInitData > ScCaptionInitDataRef;
+
+    ::rtl::OUString     maDate;             /// Creation date of the note.
+    ::rtl::OUString     maAuthor;           /// Author of the note.
+    ScCaptionInitDataRef mxInitData;        /// Initial data for invisible notes without SdrObject.
     SdrCaptionObj*      mpCaption;          /// Drawing object representing the cell note.
     bool                mbShown;            /// True = note is visible.
 
     explicit            ScNoteData( bool bShown = false );
+                        ~ScNoteData();
 };
 
 // ============================================================================
 
+/** An additional class held by an ScBaseCell instance containing all
+    information for a cell annotation.
+ */
 class SC_DLLPUBLIC ScPostIt
 {
 public:
@@ -65,76 +77,98 @@ public:
     /** Copy constructor. Clones the note and its caption to a new document. */
     explicit            ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote );
 
-    /** Creates a note from the passed note data with existing caption object. */
-    explicit            ScPostIt( ScDocument& rDoc, const ScNoteData& rNoteData );
+    /** Creates a note from the passed note data with existing caption object.
+
+        @param bAlwaysCreateCaption  Instead of a pointer to an existing
+            caption object, the passed note data structure may contain a
+            reference to an ScCaptionInitData structure containing information
+            about how to construct a missing caption object. If TRUE is passed,
+            the caption drawing object will be created immediately from that
+            data. If FALSE is passed and the note is not visible, it will
+            continue to cache that data until the caption object is requested.
+     */
+    explicit            ScPostIt(
+                            ScDocument& rDoc, const ScAddress& rPos,
+                            const ScNoteData& rNoteData, bool bAlwaysCreateCaption );
 
     /** Removes the caption object from drawing layer, if this note is its owner. */
                         ~ScPostIt();
 
-    /** Returns the data struct containing note settings. */
+    /** Clones this note and its caption object, if specified.
+
+        @param bCloneCaption  If TRUE is passed, clones the caption object and
+            inserts it into the drawing layer of the destination document. If
+            FALSE is passed, the cloned note will refer to the old caption
+            object (used e.g. in Undo documents to restore the pointer to the
+            existing caption object).
+     */
+    ScPostIt*           Clone(
+                            const ScAddress& rOwnPos,
+                            ScDocument& rDestDoc, const ScAddress& rDestPos,
+                            bool bCloneCaption ) const;
+
+    /** Returns the data struct containing all note settings. */
     inline const ScNoteData& GetNoteData() const { return maNoteData; }
 
     /** Returns the creation date of this note. */
-    inline const String& GetDate() const { return maNoteData.maDate; }
+    inline const ::rtl::OUString& GetDate() const { return maNoteData.maDate; }
     /** Sets a new creation date for this note. */
-    inline void         SetDate( const String& rDate ) { maNoteData.maDate = rDate; }
+    inline void         SetDate( const ::rtl::OUString& rDate ) { maNoteData.maDate = rDate; }
 
     /** Returns the author date of this note. */
-    inline const String& GetAuthor() const { return maNoteData.maAuthor; }
+    inline const ::rtl::OUString& GetAuthor() const { return maNoteData.maAuthor; }
     /** Sets a new author date for this note. */
-    inline void         SetAuthor( const String& rAuthor ) { maNoteData.maAuthor = rAuthor; }
+    inline void         SetAuthor( const ::rtl::OUString& rAuthor ) { maNoteData.maAuthor = rAuthor; }
 
     /** Sets date and author from system settings. */
     void                AutoStamp();
 
+    /** Returns the pointer to the current outliner object, or null. */
+    const OutlinerParaObject* GetOutlinerObject() const;
     /** Returns the pointer to the current edit text object, or null. */
     const EditTextObject* GetEditTextObject() const;
+
     /** Returns the caption text of this note. */
-    String              GetText() const;
+    ::rtl::OUString     GetText() const;
     /** Returns true, if the caption text of this note contains line breaks. */
     bool                HasMultiLineText() const;
     /** Changes the caption text of this note. All text formatting will be lost. */
-    void                SetText( const String& rText );
+    void                SetText( const ScAddress& rPos, const ::rtl::OUString& rText );
 
-    /** Returns the note caption object. */
+    /** Returns an existing note caption object. returns null, if the note
+        contains initial caption data needed to construct a caption object. */
     inline SdrCaptionObj* GetCaption() const { return maNoteData.mpCaption; }
-    /** Returns and forgets the note caption object. */
-    inline SdrCaptionObj* ForgetCaption() { SdrCaptionObj* pCapt = maNoteData.mpCaption; maNoteData.mpCaption = 0; return pCapt; }
+    /** Returns the caption object of this note. Creates the caption object, if
+        the note contains initial caption data instead of the caption. */
+    SdrCaptionObj*      GetOrCreateCaption( const ScAddress& rPos ) const;
+    /** Forgets the pointer to the note caption object. */
+    void                ForgetCaption();
 
     /** Shows or hides the note caption object. */
-    void                ShowCaption( bool bShow = true );
-    /** Hides the note caption object. */
-    inline void         HideCaption() { ShowCaption( false ); }
+    void                ShowCaption( const ScAddress& rPos, bool bShow = true );
     /** Returns true, if the caption object is visible. */
     inline bool         IsCaptionShown() const { return maNoteData.mbShown; }
 
     /** Shows or hides the caption temporarily (does not change internal visibility state). */
-    void                ShowCaptionTemp( bool bShow = true );
-    /** Hides caption if it has been shown temporarily (does not change internal visibility state). */
-    inline void         HideCaptionTemp() { ShowCaptionTemp( false ); }
+    void                ShowCaptionTemp( const ScAddress& rPos, bool bShow = true );
 
     /** Updates caption position according to position of the passed cell. */
     void                UpdateCaptionPos( const ScAddress& rPos );
 
-    /** Sets caption itemset to default items. */
-    void                SetCaptionDefaultItems();
-    /** Updates caption itemset according to the passed item set while removing shadow items. */
-    void                SetCaptionItems( const SfxItemSet& rItemSet );
-
 private:
                         ScPostIt( const ScPostIt& );
     ScPostIt&           operator=( const ScPostIt& );
 
+    /** Creates the caption object from initial caption data if existing. */
+    void                CreateCaptionFromInitData( const ScAddress& rPos ) const;
     /** Creates a new caption object at the passed cell position, clones passed existing caption. */
     void                CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption = 0 );
     /** Removes the caption object from the drawing layer, if this note is its owner. */
     void                RemoveCaption();
-    /** Updates caption visibility. */
-    void                UpdateCaptionLayer( bool bShow );
 
 private:
     ScDocument&         mrDoc;              /// Parent document containing the note.
-    ScNoteData          maNoteData;         /// Note data with pointer to caption object.
+    mutable ScNoteData  maNoteData;         /// Note data with pointer to caption object.
 };
 
 // ============================================================================
@@ -142,24 +176,89 @@ private:
 class SC_DLLPUBLIC ScNoteUtil
 {
 public:
-    /** Clones the note and its caption object, if specified.
-        @param bCloneCaption  True = clones the caption object and inserts it
-            into the drawing layer of the destination document. False = the
-            cloned note will refer to the old caption object. */
-    static ScPostIt*    CloneNote( ScDocument& rDoc, const ScAddress& rPos,
-                            const ScPostIt& rNote, bool bCloneCaption );
-
     /** Tries to update the position of note caption objects in the specified range. */
     static void         UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange );
 
     /** Creates and returns a caption object for a temporary caption. */
     static SdrCaptionObj* CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos,
-                            SdrPage& rPage, const String& rUserText,
+                            SdrPage& rDrawPage, const ::rtl::OUString& rUserText,
                             const Rectangle& rVisRect, bool bTailFront );
 
-    /** Creates a cell note based on the passed string and inserts it into the document. */
-    static ScPostIt*    CreateNoteFromString( ScDocument& rDoc, const ScAddress& rPos,
-                            const String& rNoteText, bool bShown );
+    /** Creates a cell note using the passed caption drawing object.
+
+        This function is used in import filters to reuse the imported drawing
+        object as note caption object.
+
+        @param rCaption  The drawing object for the cell note. This object MUST
+            be inserted into the document at the correct drawing page already.
+
+        @return  Pointer to the new cell note object if insertion was
+            successful (i.e. the passed cell position was valid), null
+            otherwise. The Calc document is the owner of the note object. The
+            passed item set and outliner object are deleted automatically if
+            creation of the note was not successful.
+     */
+    static ScPostIt*    CreateNoteFromCaption(
+                            ScDocument& rDoc, const ScAddress& rPos,
+                            SdrCaptionObj& rCaption, bool bShown );
+
+    /** Creates a cell note based on the passed caption object data.
+
+        This function is used in import filters to use an existing imported
+        item set and outliner object to create a note caption object. For
+        performance reasons, it is possible to specify that the caption drawing
+        object for the cell note is not created yet but the note caches the
+        passed data needed to create the caption object on demand (see
+        parameter bAlwaysCreateCaption).
+
+        @param pItemSet  Pointer to an item set on heap memory containing all
+            formatting attributes of the caption object. This function takes
+            ownership of the passed item set.
+
+        @param pOutlinerObj  Pointer to an outliner object on heap memory
+            containing (formatted) text for the caption object. This function
+            takes ownership of the passed outliner object.
+
+        @param rCaptionRect  The absolute position and size of the caption
+            object. The rectangle may be empty, in this case the default
+            position and size is used.
+
+        @param bAlwaysCreateCaption  If TRUE is passed, the caption drawing
+            object will be created immediately. If FALSE is passed, the caption
+            drawing object will not be created if the note is not visible
+            (bShown = FALSE), but the cell note will cache the passed data.
+            MUST be set to FALSE outside of import filter implementations!
+
+        @return  Pointer to the new cell note object if insertion was
+            successful (i.e. the passed cell position was valid), null
+            otherwise. The Calc document is the owner of the note object.
+     */
+    static ScPostIt*    CreateNoteFromObjectData(
+                            ScDocument& rDoc, const ScAddress& rPos,
+                            SfxItemSet* pItemSet, OutlinerParaObject* pOutlinerObj,
+                            const Rectangle& rCaptionRect, bool bShown,
+                            bool bAlwaysCreateCaption );
+
+    /** Creates a cell note based on the passed string and inserts it into the
+        document.
+
+        @param rNoteText  The text used to create the note caption object. Must
+            not be empty.
+
+        @param bAlwaysCreateCaption  If TRUE is passed, the caption drawing
+            object will be created immediately. If FALSE is passed, the caption
+            drawing object will not be created if the note is not visible
+            (bShown = FALSE), but the cell note will cache the passed data.
+            MUST be set to FALSE outside of import filter implementations!
+
+        @return  Pointer to the new cell note object if insertion was
+            successful (i.e. the passed cell position was valid), null
+            otherwise. The Calc document is the owner of the note object.
+     */
+    static ScPostIt*    CreateNoteFromString(
+                            ScDocument& rDoc, const ScAddress& rPos,
+                            const ::rtl::OUString& rNoteText, bool bShown,
+                            bool bAlwaysCreateCaption );
 };
 
 // ============================================================================
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 083a6d5..80a1fce 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -32,6 +32,8 @@
 #define SC_TABLE_HXX
 
 #include <vector>
+#include <memory>
+#include <utility>
 #include <tools/gen.hxx>
 #include <tools/color.hxx>
 #include <com/sun/star/uno/Sequence.hxx>
@@ -80,6 +82,10 @@ class ScTable
 {
 private:
     typedef ::std::vector< ScRange > ScRangeVec;
+    typedef ::std::pair< SCCOL, SCROW > ScAddress2D;
+    typedef ::std::vector< ScAddress2D > ScAddress2DVec;
+    typedef ::std::auto_ptr< ScAddress2DVec > ScAddress2DVecPtr;
+
                                             //	Daten pro Tabelle	------------------
     ScColumn		aCol[MAXCOLCOUNT];
 
@@ -121,6 +127,7 @@ private:
 
                                             //	interne Verwaltung	------------------
     BOOL			bVisible;
+    BOOL            bPendingRowHeights;
 
     SCTAB			nTab;
     USHORT			nRecalcLvl;				// Rekursionslevel Size-Recalc
@@ -130,6 +137,8 @@ private:
 
     mutable String  aUpperName;             // #i62977# filled only on demand, reset in SetName
 
+    ScAddress2DVecPtr mxUninitNotes;
+
     // SortierParameter um den Stackbedarf von Quicksort zu Minimieren
     ScSortParam		aSortParam;
     CollatorWrapper*	pSortCollator;
@@ -184,6 +193,9 @@ public:
     BOOL		IsVisible() const							 { return bVisible; }
     void		SetVisible( BOOL bVis );
 
+    BOOL        IsPendingRowHeights() const                  { return bPendingRowHeights; }
+    void        SetPendingRowHeights( BOOL bSet );
+
     BOOL        IsLayoutRTL() const                          { return bLayoutRTL; }
     BOOL        IsLoadingRTL() const                         { return bLoadingRTL; }
     void        SetLayoutRTL( BOOL bSet );
@@ -277,6 +289,9 @@ public:
     ScPostIt*   ReleaseNote( SCCOL nCol, SCROW nRow );
     /** Deletes the note at the passed cell address. */
     void        DeleteNote( SCCOL nCol, SCROW nRow );
+    /** Creates the captions of all uninitialized cell notes.
+        @param bForced  True = always create all captions, false = skip when Undo is disabled. */
+    void        InitializeNoteCaptions( bool bForced = false );
 
     BOOL		TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize );
     void		InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize );
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 94e14ec..2a33623 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -148,7 +148,7 @@ ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, const ScAddress&
     return lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
 }
 
-ScBaseCell* ScBaseCell::CloneWithNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
+ScBaseCell* ScBaseCell::CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
 {
     ScBaseCell* pNewCell = lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
     if( mpNote )
@@ -156,7 +156,7 @@ ScBaseCell* ScBaseCell::CloneWithNote( ScDocument& rDestDoc, const ScAddress& rD
         if( !pNewCell )
             pNewCell = new ScNoteCell;
         bool bCloneCaption = (nCloneFlags & SC_CLONECELL_NOCAPTION) == 0;
-        pNewCell->TakeNote( ScNoteUtil::CloneNote( rDestDoc, rDestPos, *mpNote, bCloneCaption ) );
+        pNewCell->TakeNote( mpNote->Clone( rOwnPos, rDestDoc, rDestPos, bCloneCaption ) );
     }
     return pNewCell;
 }
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 433c810..73d28c4 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1272,11 +1272,14 @@ void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, BOOL bKee
     {
         int nCloneFlags = bCloneNoteCaptions ? SC_CLONECELL_DEFAULT : SC_CLONECELL_NOCAPTION;
         rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
-        ScAddress aPos( rColumn.nCol, 0, rColumn.nTab );
+        ScAddress aOwnPos( nCol, 0, nTab );
+        ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
         for (i = nStartIndex; i <= nEndIndex; i++)
         {
-            aPos.SetRow( pItems[i].nRow );
-            rColumn.Append( aPos.Row(), pItems[i].pCell->CloneWithNote( *rColumn.pDocument, aPos, nCloneFlags ) );
+            aOwnPos.SetRow( pItems[i].nRow );
+            aDestPos.SetRow( pItems[i].nRow );
+            ScBaseCell* pNewCell = pItems[i].pCell->CloneWithNote( aOwnPos, *rColumn.pDocument, aDestPos, nCloneFlags );
+            rColumn.Append( aDestPos.Row(), pNewCell );
         }
     }
 }
@@ -1376,16 +1379,18 @@ void ScColumn::UndoToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarke
 void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
 {
     ScDocument& rDestDoc = *rDestCol.pDocument;
+    ScAddress aOwnPos( nCol, 0, nTab );
     ScAddress aDestPos( rDestCol.nCol, 0, rDestCol.nTab );
 
     SCSIZE nPosCount = rPosCol.nCount;
     for (SCSIZE nPosIndex = 0; nPosIndex < nPosCount; nPosIndex++)
     {
-        aDestPos.SetRow( rPosCol.pItems[nPosIndex].nRow );
+        aOwnPos.SetRow( rPosCol.pItems[nPosIndex].nRow );
+        aDestPos.SetRow( aOwnPos.Row() );
         SCSIZE nThisIndex;
         if ( Search( aDestPos.Row(), nThisIndex ) )
         {
-            ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( rDestDoc, aDestPos );
+            ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( aOwnPos, rDestDoc, aDestPos );
             rDestCol.Insert( aDestPos.Row(), pNew );
         }
     }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 476da6d..521f6e7 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -907,7 +907,8 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, USHORT nFlags, ScDocument& rDestD
         {
             bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0;
             // #i52342# if caption is cloned, the note must be constructed with the destination document
-            ScPostIt* pNewNote = ScNoteUtil::CloneNote( rDestDoc, rDestPos, *pNote, bCloneCaption );
+            ScAddress aOwnPos( nCol, pItems[nIndex].nRow, nTab );
+            ScPostIt* pNewNote = pNote->Clone( aOwnPos, rDestDoc, rDestPos, bCloneCaption );
             if (!pNew)
                 pNew = new ScNoteCell( pNewNote );
             else
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index d5d4438..487b029 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -932,6 +932,7 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
             DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
 
         pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
+        pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
 
         // Update cells containing external references.
         if (pExternalRefMgr.get())
@@ -1110,6 +1111,8 @@ ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
 
         if (bInsertNew)
             TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
+
+        pTab[nDestPos]->SetPendingRowHeights( pSrcDoc->pTab[nSrcPos]->IsPendingRowHeights() );
     }
     if (!bValid)
         nRetVal = 0;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 60a75f2..cd958da 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -507,6 +507,22 @@ BOOL ScDocument::IsVisible( SCTAB nTab ) const
 }
 
 
+BOOL ScDocument::IsPendingRowHeights( SCTAB nTab ) const
+{
+    if ( ValidTab(nTab) && pTab[nTab] )
+        return pTab[nTab]->IsPendingRowHeights();
+
+    return FALSE;
+}
+
+
+void ScDocument::SetPendingRowHeights( SCTAB nTab, BOOL bSet )
+{
+    if ( ValidTab(nTab) && pTab[nTab] )
+        pTab[nTab]->SetPendingRowHeights( bSet );
+}
+
+
 void ScDocument::SetLayoutRTL( SCTAB nTab, BOOL bRTL )
 {
     if ( ValidTab(nTab)  && pTab[nTab] )
@@ -2568,6 +2584,18 @@ void ScDocument::DeleteNote( const ScAddress& rPos )
 }
 
 
+void ScDocument::InitializeNoteCaptions( SCTAB nTab, bool bForced )
+{
+    if( ValidTab( nTab ) && pTab[ nTab ] )
+        pTab[ nTab ]->InitializeNoteCaptions( bForced );
+}
+
+void ScDocument::InitializeAllNoteCaptions( bool bForced )
+{
+    for( SCTAB nTab = 0; nTab < GetTableCount(); ++nTab )
+        InitializeNoteCaptions( nTab, bForced );
+}
+
 void ScDocument::SetDirty()
 {
     BOOL bOldAutoCalc = GetAutoCalc();
@@ -2933,14 +2961,20 @@ BOOL ScDocument::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, U
 
 
 void ScDocument::UpdateAllRowHeights( OutputDevice* pDev, double nPPTX, double nPPTY,
-                                    const Fraction& rZoomX, const Fraction& rZoomY )
+                                    const Fraction& rZoomX, const Fraction& rZoomY, const ScMarkData* pTabMark )
 {
-    // one progress across all sheets
-    ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), GetWeightedCount() );
+    // one progress across all (selected) sheets
+
+    ULONG nCellCount = 0;
+    for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
+        if ( pTab[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
+            nCellCount += pTab[nTab]->GetWeightedCount();
+
+    ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount );
 
     ULONG nProgressStart = 0;
     for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
-        if ( pTab[nTab] )
+        if ( pTab[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
         {
             pTab[nTab]->SetOptimalHeight( 0, MAXROW, 0,
                         pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE, &aProgress, nProgressStart );
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index e7a8572..c696525 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -493,7 +493,7 @@ void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SC
                 if ( pObj->ISA( SdrRectObj ) && pData->maStart.IsValid() && pData->maEnd.IsValid() )
                     pData->maStart.PutInOrder( pData->maEnd );
                 AddCalcUndo( new ScUndoObjData( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd ) );
-                RecalcPos( pObj, *pData, aOldStt, aOldEnd, bNegativePage );
+                RecalcPos( pObj, *pData, bNegativePage );
             }
         }
     }
@@ -522,27 +522,33 @@ void ScDrawLayer::SetPageSize( USHORT nPageNo, const Size& rSize )
             SdrObject* pObj = pPage->GetObj( i );
             ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) );
             if( pData )
-                RecalcPos( pObj, *pData, pData->maStart, pData->maEnd, bNegativePage );
+                RecalcPos( pObj, *pData, bNegativePage );
         }
     }
 }
 
-void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData,
-        const ScAddress& rOldStart, const ScAddress& /*rOldEnd*/, bool bNegativePage )
+void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage )
 {
     DBG_ASSERT( pDoc, "ScDrawLayer::RecalcPos - missing document" );
     if( !pDoc )
         return;
 
+    /*  TODO CleanUp: Updating note position works just by chance currently...
+        When inserting rows/columns, this function is called after the
+        insertion, and the note is located at the new position contained in the
+        passed ScDrawObjData already. But when deleting rows/columns, this
+        function is called *before* the deletion, so the note is still at the
+        old cell position, and ScDocument::GetNote() will fail to get the note
+        or will get another note. But after the rows/columns are deleted, a
+        call to ScDrawLayer::SetPageSize() will call this function again, and
+        now the note is at the expected position in the document. */
     if( rData.mbNote )
     {
-        /*  #i63671# while inserting/deleting cells/rows/columns: note has
-            not been moved yet in document, get it from old position. */
-        DBG_ASSERT( rOldStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
+        DBG_ASSERT( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
         /*  When inside an undo action, there may be pending note captions
             where cell note is already deleted. The caption will be deleted
             later with drawing undo. */
-        if( ScPostIt* pNote = pDoc->GetNote( rOldStart ) )
+        if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) )
             pNote->UpdateCaptionPos( rData.maStart );
         return;
     }
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index 71d7ba6..29618da 100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -128,6 +128,7 @@ EXCEPTIONSFILES= \
     $(SLO)$/dptabdat.obj \
     $(SLO)$/global2.obj \
     $(SLO)$/table1.obj \
+    $(SLO)$/table2.obj \
     $(SLO)$/table3.obj \
     $(SLO)$/tabprotection.obj \
     $(SLO)$/postit.obj \
diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
index 068ec3a..c53694b 100644
--- a/sc/source/core/data/postit.cxx
+++ b/sc/source/core/data/postit.cxx
@@ -33,6 +33,7 @@
 
 #include "postit.hxx"
 
+#include <rtl/ustrbuf.hxx>
 #include <svtools/useroptions.hxx>
 #include <svx/svdpage.hxx>
 #include <svx/svdocapt.hxx>
@@ -57,6 +58,9 @@
 #include "userdat.hxx"
 #include "detfunc.hxx"
 
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
 // ============================================================================
 
 namespace {
@@ -69,8 +73,107 @@ const long SC_NOTECAPTION_OFFSET_Y          = -1500;    /// Default Y offset of
 const long SC_NOTECAPTION_OFFSET_X          =  1500;    /// Default X offset of note captions to left border of anchor cell.
 const long SC_NOTECAPTION_BORDERDIST_TEMP   =   100;    /// Distance of temporary note captions to visible sheet area.
 
+// ============================================================================
+
+/** Static helper functions for caption objects. */
+class ScCaptionUtil
+{
+public:
+    /** Moves the caption object to the correct layer according to passed visibility. */
+    static void         SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown );
+    /** Sets basic caption settings required for note caption objects. */
+    static void         SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown );
+    /** Stores the cell position of the note in the user data area of the caption. */
+    static void         SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos );
+    /** Sets all default formatting attributes to the caption object. */
+    static void         SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc );
+    /** Updates caption item set according to the passed item set while removing shadow items. */
+    static void         SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet );
+};
+
 // ----------------------------------------------------------------------------
 
+void ScCaptionUtil::SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown )
+{
+    SdrLayerID nLayer = bShown ? SC_LAYER_INTERN : SC_LAYER_HIDDEN;
+    if( nLayer != rCaption.GetLayer() )
+        rCaption.SetLayer( nLayer );
+}
+
+void ScCaptionUtil::SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown )
+{
+    ScDrawLayer::SetAnchor( &rCaption, SCA_PAGE );
+    SetCaptionLayer( rCaption, bShown );
+    rCaption.SetFixedTail();
+    rCaption.SetSpecialTextBoxShadow();
+}
+
+void ScCaptionUtil::SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos )
+{
+    // pass true to ScDrawLayer::GetObjData() to create the object data entry
+    ScDrawObjData* pObjData = ScDrawLayer::GetObjData( &rCaption, true );
+    OSL_ENSURE( pObjData, "ScCaptionUtil::SetCaptionUserData - missing drawing object user data" );
+    pObjData->maStart = rPos;
+    pObjData->mbNote = true;
+}
+
+void ScCaptionUtil::SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc )
+{
+    SfxItemSet aItemSet = rCaption.GetMergedItemSet();
+
+    // caption tail arrow
+    ::basegfx::B2DPolygon aTriangle;
+    aTriangle.append( ::basegfx::B2DPoint( 10.0,  0.0 ) );
+    aTriangle.append( ::basegfx::B2DPoint(  0.0, 30.0 ) );
+    aTriangle.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
+    aTriangle.setClosed( true );
+    /*  #99319# Line ends are now created with an empty name. The
+        checkForUniqueItem() method then finds a unique name for the item's
+        value. */
+    aItemSet.Put( XLineStartItem( String::EmptyString(), ::basegfx::B2DPolyPolygon( aTriangle ) ) );
+    aItemSet.Put( XLineStartWidthItem( 200 ) );
+    aItemSet.Put( XLineStartCenterItem( FALSE ) );
+    aItemSet.Put( XFillStyleItem( XFILL_SOLID ) );
+    aItemSet.Put( XFillColorItem( String::EmptyString(), ScDetectiveFunc::GetCommentColor() ) );
+    aItemSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT ) );
+
+    // shadow
+    /*  SdrShadowItem has FALSE, instead the shadow is set for the
+        rectangle only with SetSpecialTextBoxShadow() when the object is
+        created (item must be set to adjust objects from older files). */
+    aItemSet.Put( SdrShadowItem( FALSE ) );
+    aItemSet.Put( SdrShadowXDistItem( 100 ) );
+    aItemSet.Put( SdrShadowYDistItem( 100 ) );
+
+    // text attributes
+    aItemSet.Put( SdrTextLeftDistItem( 100 ) );
+    aItemSet.Put( SdrTextRightDistItem( 100 ) );
+    aItemSet.Put( SdrTextUpperDistItem( 100 ) );
+    aItemSet.Put( SdrTextLowerDistItem( 100 ) );
+    aItemSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+    aItemSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
+    // #78943# use the default cell style to be able to modify the caption font
+    const ScPatternAttr& rDefPattern = static_cast< const ScPatternAttr& >( rDoc.GetPool()->GetDefaultItem( ATTR_PATTERN ) );
+    rDefPattern.FillEditItemSet( &aItemSet );
+
+    rCaption.SetMergedItemSet( aItemSet );
+}
+
+void ScCaptionUtil::SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet )
+{
+    // copy all items
+    rCaption.SetMergedItemSet( rItemSet );
+    // reset shadow items
+    rCaption.SetMergedItem( SdrShadowItem( FALSE ) );
+    rCaption.SetMergedItem( SdrShadowXDistItem( 100 ) );
+    rCaption.SetMergedItem( SdrShadowYDistItem( 100 ) );
+    rCaption.SetSpecialTextBoxShadow();
+}
+
+// ============================================================================
+
+/** Helper for creation and manipulation of caption drawing objects independent
+    from cell annotations. */
 class ScCaptionCreator
 {
 public:
@@ -79,27 +182,32 @@ public:
     /** Manipulate an existing caption. */
     explicit            ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption );
 
+    /** Returns the drawing layer page of the sheet contained in maPos. */
+    SdrPage*            GetDrawPage();
     /** Returns the caption drawing obejct. */
     inline SdrCaptionObj* GetCaption() { return mpCaption; }
 
     /** Moves the caption inside the passed rectangle. Uses page area if 0 is passed. */
     void                FitCaptionToRect( const Rectangle* pVisRect = 0 );
-    /** Places the passed caption inside the passed rectangle, tries to keep the cell rectangle uncovered. Uses page area if 0 is passed. */
+    /** Places the caption inside the passed rectangle, tries to keep the cell rectangle uncovered. Uses page area if 0 is passed. */
     void                AutoPlaceCaption( const Rectangle* pVisRect = 0 );
     /** Updates caption tail and textbox according to current cell position. Uses page area if 0 is passed. */
     void                UpdateCaptionPos( const Rectangle* pVisRect = 0 );
-    /** Sets all default formatting attributes to the caption object. */
-    void                SetDefaultItems();
-    /** Updates caption itemset according to the passed item set while removing shadow items. */
-    void                SetCaptionItems( const SfxItemSet& rItemSet );
+
+protected:
+    /** Helper constructor for derived classes. */
+    explicit            ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos );
+
+    /** Calculates the caption tail position according to current cell position. */
+    Point               CalcTailPos( bool bTailFront );
+    /** Implements creation of the caption object. The caption will not be inserted into the document. */
+    void                CreateCaption( bool bShown, bool bTailFront );
 
 private:
     /** Initializes all members. */
     void                Initialize();
     /** Returns the passed rectangle if existing, page rectangle otherwise. */
     inline const Rectangle& GetVisRect( const Rectangle* pVisRect ) const { return pVisRect ? *pVisRect : maPageRect; }
-    /** Calculates the caption tail position according to current cell position. */
-    Point               CalcTailPos( bool bTailFront );
 
 private:
     ScDocument&         mrDoc;
@@ -118,17 +226,7 @@ ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, boo
     mpCaption( 0 )
 {
     Initialize();
-
-    // create the caption drawing object
-    Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) );
-    Point aTailPos = CalcTailPos( bTailFront );
-    mpCaption = new SdrCaptionObj( aTextRect, aTailPos );
-
-    // basic settings
-    ScDrawLayer::SetAnchor( mpCaption, SCA_PAGE );
-    mpCaption->SetLayer( bShown ? SC_LAYER_INTERN : SC_LAYER_HIDDEN );
-    mpCaption->SetFixedTail();
-    mpCaption->SetSpecialTextBoxShadow();
+    CreateCaption( bShown, bTailFront );
 }
 
 ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption ) :
@@ -139,6 +237,20 @@ ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, Sdr
     Initialize();
 }
 
+ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos ) :
+    mrDoc( rDoc ),
+    maPos( rPos ),
+    mpCaption( 0 )
+{
+    Initialize();
+}
+
+SdrPage* ScCaptionCreator::GetDrawPage()
+{
+    ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
+    return pDrawLayer ? pDrawLayer->GetPage( static_cast< sal_uInt16 >( maPos.Tab() ) ) : 0;
+}
+
 void ScCaptionCreator::FitCaptionToRect( const Rectangle* pVisRect )
 {
     const Rectangle& rVisRect = GetVisRect( pVisRect );
@@ -269,98 +381,131 @@ void ScCaptionCreator::UpdateCaptionPos( const Rectangle* pVisRect )
     }
 }
 
-void ScCaptionCreator::SetDefaultItems()
+Point ScCaptionCreator::CalcTailPos( bool bTailFront )
 {
-    SfxItemSet aItemSet = mpCaption->GetMergedItemSet();
-
-    // caption tail arrow
-    ::basegfx::B2DPolygon aTriangle;
-    aTriangle.append( ::basegfx::B2DPoint( 10.0,  0.0 ) );
-    aTriangle.append( ::basegfx::B2DPoint(  0.0, 30.0 ) );
-    aTriangle.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
-    aTriangle.setClosed( true );
-    /*  #99319# Line ends are now created with an empty name. The
-        checkForUniqueItem() method then finds a unique name for the item's
-        value. */
-    aItemSet.Put( XLineStartItem( String::EmptyString(), ::basegfx::B2DPolyPolygon( aTriangle ) ) );
-    aItemSet.Put( XLineStartWidthItem( 200 ) );
-    aItemSet.Put( XLineStartCenterItem( FALSE ) );
-    aItemSet.Put( XFillStyleItem( XFILL_SOLID ) );
-    aItemSet.Put( XFillColorItem( String::EmptyString(), ScDetectiveFunc::GetCommentColor() ) );
-    aItemSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT ) );
-
-    // shadow
-    /*  SdrShadowItem has FALSE, instead the shadow is set for the
-        rectangle only with SetSpecialTextBoxShadow when the object is
-        created (item must be set to adjust objects from older files). */
-    aItemSet.Put( SdrShadowItem( FALSE ) );
-    aItemSet.Put( SdrShadowXDistItem( 100 ) );
-    aItemSet.Put( SdrShadowYDistItem( 100 ) );
-
-    // text attributes
-    aItemSet.Put( SdrTextLeftDistItem( 100 ) );
-    aItemSet.Put( SdrTextRightDistItem( 100 ) );
-    aItemSet.Put( SdrTextUpperDistItem( 100 ) );
-    aItemSet.Put( SdrTextLowerDistItem( 100 ) );
-    aItemSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
-    aItemSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
-    // #78943# use the default cell style to be able to modify the caption font
-    const ScPatternAttr& rDefPattern = static_cast< const ScPatternAttr& >( mrDoc.GetPool()->GetDefaultItem( ATTR_PATTERN ) );
-    rDefPattern.FillEditItemSet( &aItemSet );
-
-    mpCaption->SetMergedItemSet( aItemSet );
+    // tail position
+    bool bTailLeft = bTailFront != mbNegPage;
+    Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
+    // move caption point 1/10 mm inside cell
+    if( bTailLeft ) aTailPos.X() += 10; else aTailPos.X() -= 10;
+    aTailPos.Y() += 10;
+    return aTailPos;
 }
 
-void ScCaptionCreator::SetCaptionItems( const SfxItemSet& rItemSet )
+void ScCaptionCreator::CreateCaption( bool bShown, bool bTailFront )
 {
-    // copy all items
-    mpCaption->SetMergedItemSet( rItemSet );
-    // reset shadow items
-    mpCaption->SetMergedItem( SdrShadowItem( FALSE ) );
-    mpCaption->SetMergedItem( SdrShadowXDistItem( 100 ) );
-    mpCaption->SetMergedItem( SdrShadowYDistItem( 100 ) );
-    mpCaption->SetSpecialTextBoxShadow();
+    // create the caption drawing object
+    Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) );
+    Point aTailPos = CalcTailPos( bTailFront );
+    mpCaption = new SdrCaptionObj( aTextRect, aTailPos );
+    // basic caption settings
+    ScCaptionUtil::SetBasicCaptionSettings( *mpCaption, bShown );
 }
 
 void ScCaptionCreator::Initialize()
 {
     maCellRect = ScDrawLayer::GetCellRect( mrDoc, maPos, true );
     mbNegPage = mrDoc.IsNegativePage( maPos.Tab() );
+    if( SdrPage* pDrawPage = GetDrawPage() )
+    {
+        maPageRect = Rectangle( Point( 0, 0 ), pDrawPage->GetSize() );
+        /*  #i98141# SdrPage::GetSize() returns negative width in RTL mode.
+            The call to Rectangle::Adjust() orders left/right coordinate
+            accordingly. */
+        maPageRect.Justify();
+    }
+}
+
+// ============================================================================
 
-    if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
+/** Helper for creation of permanent caption drawing objects for cell notes. */
+class ScNoteCaptionCreator : public ScCaptionCreator
+{
+public:
+    /** Create a new caption object and inserts it into the document. */
+    explicit            ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData );
+    /** Manipulate an existing caption. */
+    explicit            ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown );
+};
+
+// ----------------------------------------------------------------------------
+
+ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData ) :
+    ScCaptionCreator( rDoc, rPos )  // use helper c'tor that does not create the caption yet
+{
+    SdrPage* pDrawPage = GetDrawPage();
+    OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
+    if( pDrawPage )
     {
-        if( SdrPage* pPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( maPos.Tab() ) ) )
+        // create the caption drawing object
+        CreateCaption( rNoteData.mbShown, false );
+        rNoteData.mpCaption = GetCaption();
+        OSL_ENSURE( rNoteData.mpCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
+        if( rNoteData.mpCaption )
         {
-            maPageRect = Rectangle( Point( 0, 0 ), pPage->GetSize() );
-            /*  #i98141# SdrPage::GetSize() returns negative width in RTL mode.
-                The call to Rectangle::Adjust() orders left/right coordinate
-                accordingly. */
-            maPageRect.Justify();
+            // store note position in user data of caption object
+            ScCaptionUtil::SetCaptionUserData( *rNoteData.mpCaption, rPos );
+            // insert object into draw page
+            pDrawPage->InsertObject( rNoteData.mpCaption );
         }
     }
 }
 
-Point ScCaptionCreator::CalcTailPos( bool bTailFront )
+ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown ) :
+    ScCaptionCreator( rDoc, rPos, rCaption )
 {
-    // tail position
-    bool bTailLeft = bTailFront != mbNegPage;
-    Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
-    // move caption point 1/10 mm inside cell
-    if( bTailLeft ) aTailPos.X() += 10; else aTailPos.X() -= 10;
-    aTailPos.Y() += 10;
-    return aTailPos;
+    SdrPage* pDrawPage = GetDrawPage();
+    OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
+    OSL_ENSURE( rCaption.GetPage() == pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" );
+    if( pDrawPage && (rCaption.GetPage() == pDrawPage) )
+    {
+        // store note position in user data of caption object
+        ScCaptionUtil::SetCaptionUserData( rCaption, rPos );
+        // basic caption settings
+        ScCaptionUtil::SetBasicCaptionSettings( rCaption, bShown );
+        // set correct tail position
+        rCaption.SetTailPos( CalcTailPos( false ) );
+    }
 }
 
 } // namespace
 
 // ============================================================================
 
+struct ScCaptionInitData
+{
+    typedef ::std::auto_ptr< SfxItemSet >           SfxItemSetPtr;
+    typedef ::std::auto_ptr< OutlinerParaObject >   OutlinerParaObjPtr;
+
+    SfxItemSetPtr       mxItemSet;          /// Caption object formatting.
+    OutlinerParaObjPtr  mxOutlinerObj;      /// Text object with all text portion formatting.
+    ::rtl::OUString     maSimpleText;       /// Simple text without formatting.
+    Point               maCaptionOffset;    /// Caption position relative to cell corner.
+    Size                maCaptionSize;      /// Size of the caption object.
+    bool                mbDefaultPosSize;   /// True = use default position and size for caption.
+
+    explicit            ScCaptionInitData();
+};
+
+// ----------------------------------------------------------------------------
+
+ScCaptionInitData::ScCaptionInitData() :
+    mbDefaultPosSize( true )
+{
+}
+
+// ============================================================================
+
 ScNoteData::ScNoteData( bool bShown ) :
     mpCaption( 0 ),
     mbShown( bShown )
 {
 }
 
+ScNoteData::~ScNoteData()
+{
+}
+
 // ============================================================================
 
 ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, bool bShown ) :
@@ -379,10 +524,12 @@ ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNo
     CreateCaption( rPos, rNote.maNoteData.mpCaption );
 }
 
-ScPostIt::ScPostIt( ScDocument& rDoc, const ScNoteData& rNoteData ) :
+ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScNoteData& rNoteData, bool bAlwaysCreateCaption ) :
     mrDoc( rDoc ),
     maNoteData( rNoteData )
 {
+    if( bAlwaysCreateCaption || maNoteData.mbShown )
+        CreateCaptionFromInitData( rPos );
 }
 
 ScPostIt::~ScPostIt()
@@ -390,164 +537,229 @@ ScPostIt::~ScPostIt()
     RemoveCaption();
 }
 
+ScPostIt* ScPostIt::Clone( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, bool bCloneCaption ) const
+{
+    CreateCaptionFromInitData( rOwnPos );
+    return bCloneCaption ? new ScPostIt( rDestDoc, rDestPos, *this ) : new ScPostIt( rDestDoc, rDestPos, maNoteData, false );
+}
+
 void ScPostIt::AutoStamp()
 {
     maNoteData.maDate = ScGlobal::pLocaleData->getDate( Date() );
     maNoteData.maAuthor = SvtUserOptions().GetID();
 }
 
-const EditTextObject* ScPostIt::GetEditTextObject() const
+const OutlinerParaObject* ScPostIt::GetOutlinerObject() const
 {
     if( maNoteData.mpCaption )
-        if( const OutlinerParaObject* pOPO = maNoteData.mpCaption->GetOutlinerParaObject() )
-            return &pOPO->GetTextObject();
+        return maNoteData.mpCaption->GetOutlinerParaObject();
+    if( maNoteData.mxInitData.get() )
+        return maNoteData.mxInitData->mxOutlinerObj.get();
     return 0;
 }
 
-String ScPostIt::GetText() const
+const EditTextObject* ScPostIt::GetEditTextObject() const
+{
+    const OutlinerParaObject* pOPO = GetOutlinerObject();
+    return pOPO ? &pOPO->GetTextObject() : 0;
+}
+
+OUString ScPostIt::GetText() const
 {
-    String aText;
     if( const EditTextObject* pEditObj = GetEditTextObject() )
     {
+        OUStringBuffer aBuffer;
         for( USHORT nPara = 0, nParaCount = pEditObj->GetParagraphCount(); nPara < nParaCount; ++nPara )
         {
             if( nPara > 0 )
-                aText.Append( '\n' );
-            aText.Append( pEditObj->GetText( nPara ) );
+                aBuffer.append( sal_Unicode( '\n' ) );
+            aBuffer.append( pEditObj->GetText( nPara ) );
         }
+        return aBuffer.makeStringAndClear();
     }
-    return aText;
+    if( maNoteData.mxInitData.get() )
+        return maNoteData.mxInitData->maSimpleText;
+    return OUString();
 }
 
 bool ScPostIt::HasMultiLineText() const
 {
-    const EditTextObject* pEditObj = GetEditTextObject();
-    return pEditObj && (pEditObj->GetParagraphCount() > 1);
+    if( const EditTextObject* pEditObj = GetEditTextObject() )
+        return pEditObj->GetParagraphCount() > 1;
+    if( maNoteData.mxInitData.get() )
+        return maNoteData.mxInitData->maSimpleText.indexOf( '\n' ) >= 0;
+    return false;
 }
 
-void ScPostIt::SetText( const String& rText )
+void ScPostIt::SetText( const ScAddress& rPos, const OUString& rText )
 {
+    CreateCaptionFromInitData( rPos );
     if( maNoteData.mpCaption )
         maNoteData.mpCaption->SetText( rText );
 }
 
-void ScPostIt::ShowCaption( bool bShow )
+SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const
 {
-    maNoteData.mbShown = bShow;
-    UpdateCaptionLayer( maNoteData.mbShown );
+    CreateCaptionFromInitData( rPos );
+    return maNoteData.mpCaption;
 }
 
-void ScPostIt::ShowCaptionTemp( bool bShow )
+void ScPostIt::ForgetCaption()
 {
-    UpdateCaptionLayer( maNoteData.mbShown || bShow );
+    /*  This function is used in undo actions to give up the responsibility for
+        the caption object which is handled by separate drawing undo actions. */
+    maNoteData.mpCaption = 0;
+    maNoteData.mxInitData.reset();
 }
 
-void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
+void ScPostIt::ShowCaption( const ScAddress& rPos, bool bShow )
 {
+    CreateCaptionFromInitData( rPos );
+    // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
+    maNoteData.mbShown = bShow;
     if( maNoteData.mpCaption )
-    {
-        ScCaptionCreator aCreator( mrDoc, rPos, *maNoteData.mpCaption );
-        aCreator.UpdateCaptionPos();
-    }
+        ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, bShow );
 }
 
-void ScPostIt::SetCaptionDefaultItems()
+void ScPostIt::ShowCaptionTemp( const ScAddress& rPos, bool bShow )
 {
+    CreateCaptionFromInitData( rPos );
     if( maNoteData.mpCaption )
-    {
-        ScCaptionCreator aCreator( mrDoc, ScAddress(), *maNoteData.mpCaption );
-        aCreator.SetDefaultItems();
-    }
+        ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, maNoteData.mbShown || bShow );
 }
 
-void ScPostIt::SetCaptionItems( const SfxItemSet& rItemSet )
+void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
 {
+    CreateCaptionFromInitData( rPos );
     if( maNoteData.mpCaption )
     {
-        ScCaptionCreator aCreator( mrDoc, ScAddress(), *maNoteData.mpCaption );
-        aCreator.SetCaptionItems( rItemSet );
+        ScCaptionCreator aCreator( mrDoc, rPos, *maNoteData.mpCaption );
+        aCreator.UpdateCaptionPos();
     }
 }
 
 // private --------------------------------------------------------------------
 
+void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const
+{
+    OSL_ENSURE( maNoteData.mpCaption || maNoteData.mxInitData.get(), "ScPostIt::CreateCaptionFromInitData - need caption object or initial caption data" );
+    if( maNoteData.mxInitData.get() )
+    {
+        /*  This function is called from ScPostIt::Clone() when copying cells
+            to the clipboard/undo document, and when copying cells from the
+            clipboard/undo document. The former should always be called first,
+            so if called in an clipboard/undo document, the caption should have
+            been created already. */
+        OSL_ENSURE( !mrDoc.IsUndo() && !mrDoc.IsClipboard(), "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
+
+        if( !maNoteData.mpCaption )
+        {
+            // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
+            ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
+            if( maNoteData.mpCaption )
+            {
+                ScCaptionInitData& rInitData = *maNoteData.mxInitData;
+
+                // transfer ownership of outliner object to caption, or set simple text
+                OSL_ENSURE( rInitData.mxOutlinerObj.get() || (rInitData.maSimpleText.getLength() > 0),
+                    "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" );
+                if( rInitData.mxOutlinerObj.get() )
+                    maNoteData.mpCaption->SetOutlinerParaObject( rInitData.mxOutlinerObj.release() );
+                else
+                    maNoteData.mpCaption->SetText( rInitData.maSimpleText );
+
+                // copy all items or set default items; reset shadow items
+                ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
+                if( rInitData.mxItemSet.get() )
+                    ScCaptionUtil::SetCaptionItems( *maNoteData.mpCaption, *rInitData.mxItemSet );
+
+                // set position and size of the caption object
+                if( rInitData.mbDefaultPosSize )
+                {
+                    // set other items and fit caption size to text
+                    maNoteData.mpCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
+                    maNoteData.mpCaption->SetMergedItem( SdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) );
+                    maNoteData.mpCaption->AdjustTextFrameWidthAndHeight();
+                    aCreator.AutoPlaceCaption();
+                }
+                else
+                {
+                    Rectangle aCellRect = ScDrawLayer::GetCellRect( mrDoc, rPos, true );
+                    bool bNegPage = mrDoc.IsNegativePage( rPos.Tab() );
+                    long nPosX = bNegPage ? (aCellRect.Left() - rInitData.maCaptionOffset.X()) : (aCellRect.Right() + rInitData.maCaptionOffset.X());
+                    long nPosY = aCellRect.Top() + rInitData.maCaptionOffset.Y();
+                    Rectangle aCaptRect( Point( nPosX, nPosY ), rInitData.maCaptionSize );
+                    maNoteData.mpCaption->SetLogicRect( aCaptRect );
+                    aCreator.FitCaptionToRect();
+                }
+            }
+        }
+        // forget the initial caption data struct
+        maNoteData.mxInitData.reset();
+    }
+}
+
 void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption )
 {
-    DBG_ASSERT( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
+    OSL_ENSURE( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
     maNoteData.mpCaption = 0;
 
     // drawing layer may be missing, if a note is copied into a clipboard document
-    DBG_ASSERT( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
+    OSL_ENSURE( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
     if( mrDoc.IsClipboard() )
         mrDoc.InitDrawLayer();
 
-    if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
+    // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
+    ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
+    if( maNoteData.mpCaption )
     {
-        SdrPage* pDrawPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( rPos.Tab() ) );
-        DBG_ASSERT( pDrawPage, "ScPostIt::CreateCaption - no drawing page" );
-        if( pDrawPage )
+        // clone settings of passed caption
+        if( pCaption )
         {
-            // create the caption drawing object
-            ScCaptionCreator aCreator( mrDoc, rPos, maNoteData.mbShown, false );
-            maNoteData.mpCaption = aCreator.GetCaption();
-
-            // additional user data (pass true to create the object data entry)
-            ScDrawObjData* pData = ScDrawLayer::GetObjData( maNoteData.mpCaption, true );
-            pData->maStart = rPos;
-            pData->mbNote = true;
-
-            // insert object into draw page
-            pDrawPage->InsertObject( maNoteData.mpCaption );
-
-            // clone settings of passed caption
-            if( pCaption )
-            {
-                // copy edit text object (object must be inserted into page already)
-                if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
-                    maNoteData.mpCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
-                // copy formatting items (after text has been copied to apply font formatting)
-                maNoteData.mpCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() );
-                // move textbox position relative to new cell, copy textbox size
-                Rectangle aCaptRect = pCaption->GetLogicRect();
-                Point aDist = maNoteData.mpCaption->GetTailPos() - pCaption->GetTailPos();
-                aCaptRect.Move( aDist.X(), aDist.Y() );
-                maNoteData.mpCaption->SetLogicRect( aCaptRect );
-                aCreator.FitCaptionToRect();
-            }
-            else
-            {
-                // set default formatting and default position
-                aCreator.SetDefaultItems();
-                aCreator.AutoPlaceCaption();
-            }
+            // copy edit text object (object must be inserted into page already)
+            if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
+                maNoteData.mpCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
+            // copy formatting items (after text has been copied to apply font formatting)
+            maNoteData.mpCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() );
+            // move textbox position relative to new cell, copy textbox size
+            Rectangle aCaptRect = pCaption->GetLogicRect();
+            Point aDist = maNoteData.mpCaption->GetTailPos() - pCaption->GetTailPos();
+            aCaptRect.Move( aDist.X(), aDist.Y() );
+            maNoteData.mpCaption->SetLogicRect( aCaptRect );
+            aCreator.FitCaptionToRect();
+        }
+        else
+        {
+            // set default formatting and default position
+            ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
+            aCreator.AutoPlaceCaption();
+        }
 
-            // create undo action
+        // create undo action
+        if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
             if( pDrawLayer->IsRecording() )
                 pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoNewObject( *maNoteData.mpCaption ) );
-        }
     }
 }
 
 void ScPostIt::RemoveCaption()
 {
+
     /*  Remove caption object only, if this note is its owner (e.g. notes in
         undo documents refer to captions in original document, do not remove
         them from drawing layer here). */
-    if( maNoteData.mpCaption && (mrDoc.GetDrawLayer() == maNoteData.mpCaption->GetModel()) )
+    ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
+    if( maNoteData.mpCaption && (pDrawLayer == maNoteData.mpCaption->GetModel()) )
     {
+        OSL_ENSURE( pDrawLayer, "ScPostIt::RemoveCaption - object without drawing layer" );
         SdrPage* pDrawPage = maNoteData.mpCaption->GetPage();
-        DBG_ASSERT( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
+        OSL_ENSURE( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
         if( pDrawPage )
         {
-               pDrawPage->RecalcObjOrdNums();
-
-            ScDrawLayer* pDrawLayer = static_cast< ScDrawLayer* >( maNoteData.mpCaption->GetModel() );
-            DBG_ASSERT( pDrawLayer, "ScPostIt::RemoveCaption - object without drawing layer" );
-
+            pDrawPage->RecalcObjOrdNums();
             // create drawing undo action (before removing the object to have valid draw page in undo action)
             if( pDrawLayer && pDrawLayer->IsRecording() )
                 pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoDeleteObject( *maNoteData.mpCaption ) );
-
             // remove the object from the drawing page, delete if undo is disabled
             pDrawPage->RemoveObject( maNoteData.mpCaption->GetOrdNum() );
         }
@@ -555,21 +767,8 @@ void ScPostIt::RemoveCaption()
     maNoteData.mpCaption = 0;
 }
 
-void ScPostIt::UpdateCaptionLayer( bool bShow )
-{
-    // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
-    SdrLayerID nLayer = bShow ? SC_LAYER_INTERN : SC_LAYER_HIDDEN;
-    if( maNoteData.mpCaption && (nLayer != maNoteData.mpCaption->GetLayer()) )
-        maNoteData.mpCaption->SetLayer( nLayer );
-}
-
 // ============================================================================
 
-ScPostIt* ScNoteUtil::CloneNote( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote, bool bCloneCaption )
-{
-    return bCloneCaption ? new ScPostIt( rDoc, rPos, rNote ) : new ScPostIt( rDoc, rNote.GetNoteData() );
-}
-
 void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange )
 {
     // do not use ScCellIterator, it skips filtered and subtotal cells
@@ -580,25 +779,26 @@ void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange
                     pNote->UpdateCaptionPos( aPos );
 }
 
-SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos,
-        SdrPage& rPage, const String& rUserText, const Rectangle& rVisRect, bool bTailFront )
+SdrCaptionObj* ScNoteUtil::CreateTempCaption(
+        ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage,
+        const OUString& rUserText, const Rectangle& rVisRect, bool bTailFront )
 {
-    String aFinalText = rUserText;
+    OUStringBuffer aBuffer( rUserText );
     // add plain text of invisible (!) cell note (no formatting etc.)
     SdrCaptionObj* pNoteCaption = 0;
-    if( ScPostIt* pNote = rDoc.GetNote( rPos ) )
+    if( const ScPostIt* pNote = rDoc.GetNote( rPos ) )
     {
         if( !pNote->IsCaptionShown() )
         {
-            if( aFinalText.Len() > 0 )
-                   aFinalText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) );
-            aFinalText.Append( pNote->GetText() );
-            pNoteCaption = pNote->GetCaption();
+            if( aBuffer.getLength() > 0 )
+                aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) );
+            aBuffer.append( pNote->GetText() );
+            pNoteCaption = pNote->GetOrCreateCaption( rPos );
         }
     }
 
     // create a caption if any text exists
-    if( aFinalText.Len() == 0 )
+    if( aBuffer.getLength() == 0 )
         return 0;
 
     // prepare visible rectangle (add default distance to all borders)
@@ -612,12 +812,12 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress&
     ScCaptionCreator aCreator( rDoc, rPos, true, bTailFront );
     SdrCaptionObj* pCaption = aCreator.GetCaption();
     // insert caption into page (needed to set caption text)
-    rPage.InsertObject( pCaption );
+    rDrawPage.InsertObject( pCaption );
     // set the text to the object
-    pCaption->SetText( aFinalText );
+    pCaption->SetText( aBuffer.makeStringAndClear() );
 
     // set formatting (must be done after setting text) and resize the box to fit the text
-    if( pNoteCaption && (rUserText.Len() == 0) )
+    if( pNoteCaption && (rUserText.getLength() == 0) )
     {
         pCaption->SetMergedItemSetAndBroadcast( pNoteCaption->GetMergedItemSet() );
         Rectangle aCaptRect( pCaption->GetLogicRect().TopLeft(), pNoteCaption->GetLogicRect().GetSize() );
@@ -625,7 +825,7 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress&
     }
     else
     {
-        aCreator.SetDefaultItems();
+        ScCaptionUtil::SetDefaultItems( *pCaption, rDoc );
         // adjust caption size to text size
         long nMaxWidth = ::std::min< long >( aVisRect.GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
         pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( TRUE ) );
@@ -640,19 +840,74 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress&
     return pCaption;
 }
 
-ScPostIt* ScNoteUtil::CreateNoteFromString( ScDocument& rDoc, const ScAddress& rPos, const String& rNoteText, bool bShown )
+ScPostIt* ScNoteUtil::CreateNoteFromCaption(
+        ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown )
 {
-    if( rNoteText.Len() == 0 )
-        return 0;
-    ScPostIt* pNote = new ScPostIt( rDoc, rPos, bShown );
+    ScNoteData aNoteData( bShown );
+    aNoteData.mpCaption = &rCaption;
+    ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false );
+    pNote->AutoStamp();
     rDoc.TakeNote( rPos, pNote );
-    if( SdrCaptionObj* pCaption = pNote->GetCaption() )
+    // if pNote still points to the note after TakeNote(), insertion was successful
+    if( pNote )
     {
-        pCaption->SetText( rNoteText );
-        pNote->SetCaptionDefaultItems();    // reformat text with default font
-        pCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
-        pCaption->SetMergedItem( SdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) );
-        pCaption->AdjustTextFrameWidthAndHeight();
+        // ScNoteCaptionCreator c'tor updates the caption object to be part of a note
+        ScNoteCaptionCreator aCreator( rDoc, rPos, rCaption, bShown );
+    }
+    return pNote;
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
+        ScDocument& rDoc, const ScAddress& rPos, SfxItemSet* pItemSet,
+        OutlinerParaObject* pOutlinerObj, const Rectangle& rCaptionRect,
+        bool bShown, bool bAlwaysCreateCaption )
+{
+    OSL_ENSURE( pItemSet && pOutlinerObj, "ScNoteUtil::CreateNoteFromObjectData - item set and outliner object expected" );
+    ScNoteData aNoteData( bShown );
+    aNoteData.mxInitData.reset( new ScCaptionInitData );
+    ScCaptionInitData& rInitData = *aNoteData.mxInitData;
+    rInitData.mxItemSet.reset( pItemSet );
+    rInitData.mxOutlinerObj.reset( pOutlinerObj );
+
+    // convert absolute caption position to relative position
+    rInitData.mbDefaultPosSize = rCaptionRect.IsEmpty();
+    if( !rInitData.mbDefaultPosSize )
+    {
+        Rectangle aCellRect = ScDrawLayer::GetCellRect( rDoc, rPos, true );
+        bool bNegPage = rDoc.IsNegativePage( rPos.Tab() );
+        rInitData.maCaptionOffset.X() = bNegPage ? (aCellRect.Left() - rCaptionRect.Right()) : (rCaptionRect.Left() - aCellRect.Right());
+        rInitData.maCaptionOffset.Y() = rCaptionRect.Top() - aCellRect.Top();
+        rInitData.maCaptionSize = rCaptionRect.GetSize();
+    }
+
+    /*  Create the note and insert it into the document. If the note is
+        visible, the caption object will be created automatically. */
+    ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
+    pNote->AutoStamp();
+    rDoc.TakeNote( rPos, pNote );
+    // if pNote still points to the note after TakeNote(), insertion was successful
+    return pNote;
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromString(
+        ScDocument& rDoc, const ScAddress& rPos, const OUString& rNoteText,
+        bool bShown, bool bAlwaysCreateCaption )
+{
+    ScPostIt* pNote = 0;
+    if( rNoteText.getLength() > 0 )
+    {
+        ScNoteData aNoteData( bShown );
+        aNoteData.mxInitData.reset( new ScCaptionInitData );
+        ScCaptionInitData& rInitData = *aNoteData.mxInitData;
+        rInitData.maSimpleText = rNoteText;
+        rInitData.mbDefaultPosSize = true;
+
+        /*  Create the note and insert it into the document. If the note is
+            visible, the caption object will be created automatically. */
+        pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
+        pNote->AutoStamp();
+        rDoc.TakeNote( rPos, pNote );
+        // if pNote still points to the note after TakeNote(), insertion was successful
     }
     return pNote;
 }
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 680281c..d51b7fd 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -141,6 +141,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
     pOutlineTable( NULL ),
     bTableAreaValid( FALSE ),
     bVisible( TRUE ),
+    bPendingRowHeights( FALSE ),
     nTab( nNewTab ),
     nRecalcLvl( 0 ),
     pDocument( pDoc ),
@@ -250,6 +251,11 @@ void ScTable::SetVisible( BOOL bVis )
     bVisible = bVis;
 }
 
+void ScTable::SetPendingRowHeights( BOOL bSet )
+{
+    bPendingRowHeights = bSet;
+}
+
 void ScTable::SetLayoutRTL( BOOL bSet )
 {
     bLayoutRTL = bSet;
@@ -1096,6 +1102,7 @@ void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nR
 {
     if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 )		// only within the table
     {
+        InitializeNoteCaptions();
         ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
         if ( eUpdateRefMode != URM_COPY && pDrawLayer )
         {
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index d33d90b..1bc4d1f 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -117,6 +117,7 @@ BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize )
 void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
 {
     nRecalcLvl++;
+    InitializeNoteCaptions();
     if (nStartCol==0 && nEndCol==MAXCOL)
     {
         if (pRowHeight && pRowFlags)
@@ -143,6 +144,7 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
                             BOOL* pUndoOutline )
 {
     nRecalcLvl++;
+    InitializeNoteCaptions();
     if (nStartCol==0 && nEndCol==MAXCOL)
     {
         if (pRowHeight && pRowFlags)
@@ -186,6 +188,7 @@ BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
 void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
 {
     nRecalcLvl++;
+    InitializeNoteCaptions();
     if (nStartRow==0 && nEndRow==MAXROW)
     {
         if (pColWidth && pColFlags)
@@ -236,6 +239,7 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
                             BOOL* pUndoOutline )
 {
     nRecalcLvl++;
+    InitializeNoteCaptions();
     if (nStartRow==0 && nEndRow==MAXROW)
     {
         if (pColWidth && pColFlags)
@@ -484,9 +488,10 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                 }
                 else							// kopieren
                 {
+                    ScAddress aOwnPos( nCol, nRow, nTab );
                     if (pCell->GetCellType() == CELLTYPE_FORMULA)
                     {
-                        pNew = pCell->CloneWithNote( *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
+                        pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
 
                         //	Referenzen drehen
                         //	bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
@@ -495,7 +500,9 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                             ((ScFormulaCell*)pNew)->TransposeReference();
                     }
                     else
-                        pNew = pCell->CloneWithNote( *pDestDoc, aDestPos );
+                    {
+                        pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos );
+                    }
                 }
                 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
             }
@@ -900,7 +907,15 @@ ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
 void ScTable::TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote )
 {
     if( ValidColRow( nCol, nRow ) )
+    {
         aCol[ nCol ].TakeNote( nRow, rpNote );
+        if( rpNote && rpNote->GetNoteData().mxInitData.get() )
+        {
+            if( !mxUninitNotes.get() )
+                mxUninitNotes.reset( new ScAddress2DVec );
+            mxUninitNotes->push_back( ScAddress2D( nCol, nRow ) );
+        }
+    }
     else
         DELETEZ( rpNote );
 }
@@ -919,6 +934,17 @@ void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
 }
 
 
+void ScTable::InitializeNoteCaptions( bool bForced )
+{
+    if( mxUninitNotes.get() && (bForced || pDocument->IsUndoEnabled()) )
+    {
+        for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt )
+            if( ScPostIt* pNote = GetNote( aIt->first, aIt->second ) )
+                pNote->GetOrCreateCaption( ScAddress( aIt->first, aIt->second, nTab ) );
+        mxUninitNotes.reset();
+    }
+}
+
 CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
 {
     if (ValidColRow( nCol, nRow ))
@@ -1918,6 +1944,7 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
         if ( nNewWidth != pColWidth[nCol] )
         {
             nRecalcLvl++;
+            InitializeNoteCaptions();
             ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
             if (pDrawLayer)
                 pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
@@ -1947,6 +1974,7 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
         if ( nNewHeight != nOldHeight )
         {
             nRecalcLvl++;
+            InitializeNoteCaptions();
             ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
             if (pDrawLayer)
                 pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
@@ -1969,6 +1997,7 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
     if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
     {
         nRecalcLvl++;
+        InitializeNoteCaptions();
         if (!nNewHeight)
         {
             DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
@@ -2235,6 +2264,7 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
         if (bWasVis != bShow)
         {
             nRecalcLvl++;
+            InitializeNoteCaptions();
             ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
             if (pDrawLayer)
             {
@@ -2272,6 +2302,7 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow)
         if (bWasVis != bShow)
         {
             nRecalcLvl++;
+            InitializeNoteCaptions();
             ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
             if (pDrawLayer)
             {
@@ -2307,6 +2338,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
         BYTE nFlags = pRowFlags->GetValue(nRow);
         BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
         nRecalcLvl++;
+        InitializeNoteCaptions();
         if (bWasVis != bShow)
         {
             ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
@@ -2348,6 +2380,7 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
 {
     SCROW nStartRow = nRow1;
     nRecalcLvl++;
+    InitializeNoteCaptions();
     while (nStartRow <= nRow2)
     {
         BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
@@ -2400,6 +2433,7 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
 {
     SCROW nStartRow = nRow1;
     nRecalcLvl++;
+    InitializeNoteCaptions();
     while (nStartRow <= nRow2)
     {
         BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index b2eb704..994596d 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -219,7 +219,7 @@ BOOL ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
                 // NB: rich text format is lost.
                 // This is also true of Cells.
                 if( ScPostIt* pNote = pCell->GetNote() )
-                    pNote->SetText( aString );
+                    pNote->SetText( ScAddress( nCol, nRow, nTab ), aString );
             }
             else if ( cMatrixFlag != MM_NONE )
             {	// #60558# Matrix nicht zerreissen
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index ddd0ba8..7680bda 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -1420,6 +1420,7 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
 
     for( SCTAB nObjTab = 0, nTabCount = rDoc.GetTableCount(); nObjTab < nTabCount; ++nObjTab )
     {
+        rDoc.InitializeNoteCaptions( nObjTab );
         SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
         DBG_ASSERT( pPage, "Page ?" );
         if( pPage )
@@ -1430,6 +1431,7 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
                 if ( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, nObjTab ) )
                 {
                     ScPostIt* pNote = rDoc.GetNote( pData->maStart );
+                    // caption should exist, we iterate over drawing objects...
                     DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" );
                     if( pNote )
                     {
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
index 93823a3..1138a1b 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -847,7 +847,7 @@ XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
         {
             // TODO: additional text
             if( pScNote )
-                if( SdrCaptionObj* pCaption = pScNote->GetCaption() )
+                if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) )
                     if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
                         mnObjId = rRoot.GetOldRoot().pObjRecs->Add( new XclObjComment( rRoot, pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) );
 
@@ -960,7 +960,7 @@ void XclExpComments::SaveXml( XclExpXmlStream& rStrm )
     if( mrNotes.IsEmpty() )
         return;
 
-    sax_fastparser::FSHelperPtr rComments = rStrm.CreateOutputStream( 
+    sax_fastparser::FSHelperPtr rComments = rStrm.CreateOutputStream(
             XclXmlUtils::GetStreamName( "xl/", "comments", mnTab + 1 ),
             XclXmlUtils::GetStreamName( "../", "comments", mnTab + 1 ),
             rStrm.GetCurrentStream()->getOutputStream(),
@@ -968,7 +968,7 @@ void XclExpComments::SaveXml( XclExpXmlStream& rStrm )
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
     rStrm.PushStream( rComments );
 
-    rComments->startElement( XML_comments, 
+    rComments->startElement( XML_comments,
             XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
             FSEND );
     rComments->startElement( XML_authors, FSEND );
@@ -995,7 +995,7 @@ void XclExpComments::SaveXml( XclExpXmlStream& rStrm )
     for( size_t i = 0; i < nNotes; ++i )
     {
         XclExpNoteList::RecordRefType xNote = mrNotes.GetRecord( i );
-        Authors::const_iterator aAuthor = aAuthors.find( 
+        Authors::const_iterator aAuthor = aAuthors.find(
                 XclXmlUtils::ToOUString( xNote->GetAuthor() ) );
         sal_Int32 nAuthorId = distance( aAuthors.begin(), aAuthor );
         xNote->WriteXml( nAuthorId, rStrm );
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index ad164cd..19d831e 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -1644,23 +1644,19 @@ void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags
 
 void XclImpNoteObj::DoProcessSdrObj( SdrObject& rSdrObj ) const
 {
-    SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj );
-    if( pTextObj && maScPos.IsValid() )
+    // create formatted text
+    XclImpTextObj::DoProcessSdrObj( rSdrObj );
+    OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
+    if( maScPos.IsValid() && pOutlinerObj )
     {
-        if( ScPostIt* pNote = GetDoc().GetOrCreateNote( maScPos ) )
-        {
-            if( SdrCaptionObj* pCaption = pNote->GetCaption() )
-            {
-                // create formatted text
-                XclImpTextObj::DoProcessSdrObj( *pCaption );
-                // set textbox rectangle from imported object
-                pCaption->NbcSetLogicRect( pTextObj->GetLogicRect() );
-                // copy all items from imported object (resets shadow items)
-                pNote->SetCaptionItems( pTextObj->GetMergedItemSet() );
-                // move caption to correct layer (visible/hidden)
-                pNote->ShowCaption( ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ) );
-            }
-        }
+        // create cell note with all data from drawing object
+        ScNoteUtil::CreateNoteFromObjectData(
+            GetDoc(), maScPos,
+            rSdrObj.GetMergedItemSet().Clone(),             // new object on heap expected
+            new OutlinerParaObject( *pOutlinerObj ),        // new object on heap expected
+            rSdrObj.GetLogicRect(),
+            ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ),
+            false );
     }
 }
 
@@ -3904,7 +3900,7 @@ void XclImpObjectManager::ReadNote3( XclImpStream& rStrm )
                 nTotalLen = 0;
             }
         }
-        ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false );
+        ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false );
     }
 }
 
diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
index f453d65..36bbfe1 100644
--- a/sc/source/filter/html/htmlpars.cxx
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -1715,31 +1715,29 @@ void ScHTMLLayoutParser::ProcToken( ImportInfo* pInfo )
 // ============================================================================
 
 template< typename Type >
-inline Type bound( const Type& rValue, const Type& rMin, const Type& rMax )
+inline Type getLimitedValue( const Type& rValue, const Type& rMin, const Type& rMax )
 { return ::std::max( ::std::min( rValue, rMax ), rMin ); }
 
-
 // ============================================================================
 
 /** Iterates through all HTML tag options of the passed ImportInfo struct. */
 class ScHTMLOptionIterator
 {
 private:
-    const HTMLOptions*          mpOptions;      /// The options array.
-    const HTMLOption*           mpCurrOption;   /// Current option.
-    sal_uInt16                  mnCount;        /// Size of the options array.
-    sal_uInt16                  mnIndex;        /// Next option to return.
+    const HTMLOptions*  mpOptions;      /// The options array.
+    const HTMLOption*   mpCurrOption;   /// Current option.
+    sal_uInt16          mnCount;        /// Size of the options array.
+    sal_uInt16          mnIndex;        /// Next option to return.
 
 public:
-    explicit                    ScHTMLOptionIterator( const ImportInfo& rInfo );
+    explicit            ScHTMLOptionIterator( const ImportInfo& rInfo );
 
-    inline bool                 is() const { return mnIndex < mnCount; }
-    inline const HTMLOption*    operator->() const { return mpCurrOption; }
-    inline const HTMLOption&    operator*() const { return *mpCurrOption; }
-    ScHTMLOptionIterator&       operator++();
+    inline bool         is() const { return mnIndex < mnCount; }
+    inline const HTMLOption* operator->() const { return mpCurrOption; }
+    inline const HTMLOption& operator*() const { return *mpCurrOption; }
+    ScHTMLOptionIterator& operator++();
 };
 
-
 // ----------------------------------------------------------------------------
 
 ScHTMLOptionIterator::ScHTMLOptionIterator( const ImportInfo& rInfo ) :
@@ -1764,7 +1762,6 @@ ScHTMLOptionIterator& ScHTMLOptionIterator::operator++()
     return *this;
 }
 
-
 // ============================================================================
 
 ScHTMLEntry::ScHTMLEntry( const SfxItemSet& rItemSet, ScHTMLTableId nTableId ) :
@@ -1819,14 +1816,15 @@ void ScHTMLEntry::Strip( const EditEngine& rEditEngine )
     }
 }
 
-
 // ============================================================================
 
 /** A map of ScHTMLTable objects.
-    @descr  Organizes the tables with a unique table key. Stores nested tables inside
-    the parent table and forms in this way a tree structure of tables.
-    An instance of this class ownes the contained table objects and deletes them
-    on destruction. */
+
+    Organizes the tables with a unique table key. Stores nested tables inside
+    the parent table and forms in this way a tree structure of tables. An
+    instance of this class ownes the contained table objects and deletes them
+    on destruction.
+ */
 class ScHTMLTableMap
 {
 private:
@@ -1838,36 +1836,35 @@ public:
     typedef ScHTMLTableStdMap::const_iterator       const_iterator;
 
 private:
-    ScHTMLTable&                mrParentTable;      /// Reference to parent table.
-    ScHTMLTableStdMap           maTables;           /// Container for all table objects.
-    mutable ScHTMLTable*        mpCurrTable;        /// Current table, used for fast search.
+    ScHTMLTable&        mrParentTable;      /// Reference to parent table.
+    ScHTMLTableStdMap   maTables;           /// Container for all table objects.
+    mutable ScHTMLTable* mpCurrTable;       /// Current table, used for fast search.
 
 public:
-    explicit                    ScHTMLTableMap( ScHTMLTable& rParentTable );
-    virtual                     ~ScHTMLTableMap();
+    explicit            ScHTMLTableMap( ScHTMLTable& rParentTable );
+    virtual             ~ScHTMLTableMap();
 
-    inline iterator             begin() { return maTables.begin(); }
-    inline const_iterator       begin() const { return maTables.begin(); }
-    inline iterator             end() { return maTables.end(); }
-    inline const_iterator       end() const { return maTables.end(); }
-    inline bool                 empty() const { return maTables.empty(); }
+    inline iterator     begin() { return maTables.begin(); }
+    inline const_iterator begin() const { return maTables.begin(); }
+    inline iterator     end() { return maTables.end(); }
+    inline const_iterator end() const { return maTables.end(); }
+    inline bool         empty() const { return maTables.empty(); }
 
     /** Returns the specified table.
         @param nTableId  Unique identifier of the table.
         @param bDeep  true = searches deep in all nested table; false = only in this container. */
-    ScHTMLTable*                FindTable( ScHTMLTableId nTableId, bool bDeep = true ) const;
+    ScHTMLTable*        FindTable( ScHTMLTableId nTableId, bool bDeep = true ) const;
 
     /** Inserts a new table into the container. This container owns the created table.
         @param bPreFormText  true = New table is based on preformatted text (<pre> tag). */
-    ScHTMLTable*                CreateTable( const ImportInfo& rInfo, bool bPreFormText );
+    ScHTMLTable*        CreateTable( const ImportInfo& rInfo, bool bPreFormText );
 
 private:
     /** Sets a working table with its index for search optimization. */
-    inline void                 SetCurrTable( ScHTMLTable* pTable ) const
-                                    { if( pTable ) mpCurrTable = pTable; }
+    inline void         SetCurrTable( ScHTMLTable* pTable ) const
+                            { if( pTable ) mpCurrTable = pTable; }
 };
 
-
 // ----------------------------------------------------------------------------
 
 ScHTMLTableMap::ScHTMLTableMap( ScHTMLTable& rParentTable ) :
@@ -1908,28 +1905,29 @@ ScHTMLTable* ScHTMLTableMap::CreateTable( const ImportInfo& rInfo, bool bPreForm
     return pTable;
 }
 
-
 // ----------------------------------------------------------------------------
 
 /** Simplified forward iterator for convenience.
-    @descr  Before the iterator can be dereferenced, it must be tested with the
-    is() method. The iterator may be invalid directly after construction
-    (i.e. empty container). */
+
+    Before the iterator can be dereferenced, it must be tested with the is()
+    method. The iterator may be invalid directly after construction (e.g. empty
+    container).
+ */
 class ScHTMLTableIterator
 {
-private:
-    ScHTMLTableMap::const_iterator maIter;
-    ScHTMLTableMap::const_iterator maEnd;
-
 public:
     /** Constructs the iterator for the passed table map.
         @param pTableMap  Pointer to the table map (is allowed to be NULL). */
-    explicit                    ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
+    explicit            ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
 
-    inline bool                 is() const { return maIter != maEnd; }
-    inline ScHTMLTable*         operator->() { return maIter->second.get(); }
-    inline ScHTMLTable&         operator*() { return *maIter->second; }
+    inline bool         is() const { return maIter != maEnd; }
+    inline ScHTMLTable* operator->() { return maIter->second.get(); }
+    inline ScHTMLTable& operator*() { return *maIter->second; }
     inline ScHTMLTableIterator& operator++() { ++maIter; return *this; }
+
+private:
+    ScHTMLTableMap::const_iterator maIter;
+    ScHTMLTableMap::const_iterator maEnd;
 };
 
 ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap )
@@ -1941,7 +1939,6 @@ ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap )
     }
 }
 
-
 // ============================================================================
 
 ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
@@ -1951,7 +1948,6 @@ ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
     ++mrnUnusedId;
 }
 
-
 // ----------------------------------------------------------------------------
 
 ScHTMLTable::ScHTMLTable( ScHTMLTable& rParentTable, const ImportInfo& rInfo, bool bPreFormText ) :
@@ -2010,7 +2006,7 @@ ScHTMLTable::ScHTMLTable( SfxItemPool& rPool, EditEngine& rEditEngine, ScEEParse
     // open the first "cell" of the document
     ImplRowOn();
     ImplDataOn( ScHTMLSize( 1, 1 ) );
-    mpCurrEntry = CreateEntry();
+    mxCurrEntry = CreateEntry();
 }
 
 ScHTMLTable::~ScHTMLTable()
@@ -2020,45 +2016,46 @@ ScHTMLTable::~ScHTMLTable()
 const SfxItemSet& ScHTMLTable::GetCurrItemSet() const
 {
     // first try cell item set, then row item set, then table item set
-    return mpDataItemSet.get() ? *mpDataItemSet : (mpRowItemSet.get() ? *mpRowItemSet : maTableItemSet);
+    return mxDataItemSet.get() ? *mxDataItemSet : (mxRowItemSet.get() ? *mxRowItemSet : maTableItemSet);
 }
 
 ScHTMLSize ScHTMLTable::GetSpan( const ScHTMLPos& rCellPos ) const
 {
     ScHTMLSize aSpan( 1, 1 );
-    if( ScRange* pRange = maLockList.Find( rCellPos.MakeAddr() ) )
+    ScRange* pRange = 0;
+    if( ((pRange = maVMergedCells.Find( rCellPos.MakeAddr() )) != 0) || ((pRange = maHMergedCells.Find( rCellPos.MakeAddr() )) != 0) )
         aSpan.Set( pRange->aEnd.Col() - pRange->aStart.Col() + 1, pRange->aEnd.Row() - pRange->aStart.Row() + 1 );
     return aSpan;
 }
 
 ScHTMLTable* ScHTMLTable::FindNestedTable( ScHTMLTableId nTableId ) const
 {
-    return mpNestedTables.get() ? mpNestedTables->FindTable( nTableId, true ) : 0;
+    return mxNestedTables.get() ? mxNestedTables->FindTable( nTableId, true ) : 0;
 }
 
 void ScHTMLTable::PutItem( const SfxPoolItem& rItem )
 {
-    DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::PutItem - no current entry" );
-    if( mpCurrEntry.get() && mpCurrEntry->IsEmpty() )
-        mpCurrEntry->GetItemSet().Put( rItem );
+    DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutItem - no current entry" );
+    if( mxCurrEntry.get() && mxCurrEntry->IsEmpty() )
+        mxCurrEntry->GetItemSet().Put( rItem );
 }
 
 void ScHTMLTable::PutText( const ImportInfo& rInfo )
 {
-    DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
-    if( mpCurrEntry.get() )
+    DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
+    if( mxCurrEntry.get() )
     {
-        if( !mpCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
-            mpCurrEntry->AdjustStart( rInfo );
+        if( !mxCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
+            mxCurrEntry->AdjustStart( rInfo );
         else
-            mpCurrEntry->AdjustEnd( rInfo );
+            mxCurrEntry->AdjustEnd( rInfo );
     }
 }
 
 void ScHTMLTable::InsertPara( const ImportInfo& rInfo )
 {
-    if( mpCurrEntry.get() && mbDataOn && !IsEmptyCell() )
-        mpCurrEntry->SetImportAlways();
+    if( mxCurrEntry.get() && mbDataOn && !IsEmptyCell() )
+        mxCurrEntry->SetImportAlways();
     PushEntry( rInfo );
     CreateNewEntry( rInfo );
     InsertLeadingEmptyLine();
@@ -2084,10 +2081,10 @@ void ScHTMLTable::InsertLeadingEmptyLine()
 
 void ScHTMLTable::AnchorOn()
 {
-    DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
+    DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
     // don't skip entries with single hyperlinks
-    if( mpCurrEntry.get() )
-        mpCurrEntry->SetImportAlways();
+    if( mxCurrEntry.get() )
+        mxCurrEntry->SetImportAlways();
 }
 
 ScHTMLTable* ScHTMLTable::TableOn( const ImportInfo& rInfo )
@@ -2118,7 +2115,7 @@ void ScHTMLTable::RowOn( const ImportInfo& rInfo )
     if( mpParentTable && !mbPreFormText )   // no rows allowed in global and preformatted tables
     {
         ImplRowOn();
-        ProcessFormatOptions( *mpRowItemSet, rInfo );
+        ProcessFormatOptions( *mxRowItemSet, rInfo );
     }
     CreateNewEntry( rInfo );
 }
@@ -2144,10 +2141,10 @@ void ScHTMLTable::DataOn( const ImportInfo& rInfo )
             switch( aIter->GetToken() )
             {
                 case HTML_O_COLSPAN:
-                    aSpanSize.mnCols = static_cast< SCCOL >( bound( aIter->GetString().ToInt32(), static_cast<sal_Int32>(1), static_cast<sal_Int32>(256) ) );
+                    aSpanSize.mnCols = static_cast< SCCOL >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
                 break;
                 case HTML_O_ROWSPAN:
-                    aSpanSize.mnRows = static_cast< SCROW >( bound( aIter->GetString().ToInt32(), static_cast<sal_Int32>(1), static_cast<sal_Int32>(256) ) );
+                    aSpanSize.mnRows = static_cast< SCROW >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
                 break;
                 case HTML_O_SDVAL:
                     pValStr.reset( new String( aIter->GetString() ) );
@@ -2159,10 +2156,10 @@ void ScHTMLTable::DataOn( const ImportInfo& rInfo )
         }
 
         ImplDataOn( aSpanSize );
-        ProcessFormatOptions( *mpDataItemSet, rInfo );
+        ProcessFormatOptions( *mxDataItemSet, rInfo );
         CreateNewEntry( rInfo );
-        mpCurrEntry->pValStr = pValStr.release();
-        mpCurrEntry->pNumStr = pNumStr.release();
+        mxCurrEntry->pValStr = pValStr.release();
+        mxCurrEntry->pNumStr = pNumStr.release();
     }
     else
         CreateNewEntry( rInfo );
@@ -2186,7 +2183,7 @@ void ScHTMLTable::BodyOn( const ImportInfo& rInfo )
             ImplRowOn();
         if( bPushed || !mbDataOn )
             ImplDataOn( ScHTMLSize( 1, 1 ) );
-        ProcessFormatOptions( *mpDataItemSet, rInfo );
+        ProcessFormatOptions( *mxDataItemSet, rInfo );
     }
     CreateNewEntry( rInfo );
 }
@@ -2220,29 +2217,33 @@ ScHTMLTable* ScHTMLTable::CloseTable( const ImportInfo& rInfo )
 
 SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
 {
-    const ScSizeVec& rSizes = maSizes[ eOrient ];
-    return (static_cast< size_t >( nCellPos ) < rSizes.size()) ? rSizes[ nCellPos ] : 0;
+    const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+    size_t nIndex = static_cast< size_t >( nCellPos );
+    if( nIndex >= rSizes.size() ) return 0;
+    return (nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]);
 }
 
 SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const
 {
-    SCCOLROW nSize = 0;
-    for( SCCOLROW nCellPos = nCellBegin; nCellPos < nCellEnd; ++nCellPos )
-        nSize += GetDocSize( eOrient, nCellPos );
-    return nSize;
+    const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+    size_t nBeginIdx = static_cast< size_t >( ::std::max< SCCOLROW >( nCellBegin, 0 ) );
+    size_t nEndIdx = static_cast< size_t >( ::std::min< SCCOLROW >( nCellEnd, static_cast< SCCOLROW >( rSizes.size() ) ) );
+    if (nBeginIdx >= nEndIdx ) return 0;
+    return rSizes[ nEndIdx - 1 ] - ((nBeginIdx == 0) ? 0 : rSizes[ nBeginIdx - 1 ]);
 }
 
 SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient ) const
 {
-    return GetDocSize( eOrient, 0, maSize.Get( eOrient ) );
+    const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+    return rSizes.empty() ? 0 : rSizes.back();
 }
 
 ScHTMLSize ScHTMLTable::GetDocSize( const ScHTMLPos& rCellPos ) const
 {
-    ScHTMLSize aCellSpan( GetSpan( rCellPos ) );
+    ScHTMLSize aCellSpan = GetSpan( rCellPos );
     return ScHTMLSize(
-        static_cast<SCCOL>(GetDocSize( tdCol, rCellPos.mnCol, rCellPos.mnCol + aCellSpan.mnCols )),
-        static_cast<SCROW>(GetDocSize( tdRow, static_cast<SCCOLROW>(rCellPos.mnRow), static_cast<SCCOLROW>(rCellPos.mnRow + aCellSpan.mnRows) )) );
+        static_cast< SCCOL >( GetDocSize( tdCol, rCellPos.mnCol, rCellPos.mnCol + aCellSpan.mnCols ) ),
+        static_cast< SCROW >( GetDocSize( tdRow, rCellPos.mnRow, rCellPos.mnRow + aCellSpan.mnRows ) ) );
 }
 
 SCCOLROW ScHTMLTable::GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
@@ -2252,13 +2253,15 @@ SCCOLROW ScHTMLTable::GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
 
 ScHTMLPos ScHTMLTable::GetDocPos( const ScHTMLPos& rCellPos ) const
 {
-    return ScHTMLPos( static_cast<SCCOL>(GetDocPos( tdCol, static_cast<SCCOLROW>(rCellPos.mnCol)) ), static_cast<SCROW>(GetDocPos( tdRow, static_cast<SCCOLROW>(rCellPos.mnRow) )) );
+    return ScHTMLPos(
+        static_cast< SCCOL >( GetDocPos( tdCol, rCellPos.mnCol ) ),
+        static_cast< SCROW >( GetDocPos( tdRow, rCellPos.mnRow ) ) );
 }
 
 void ScHTMLTable::GetDocRange( ScRange& rRange ) const
 {
     rRange.aStart = rRange.aEnd = maDocBasePos.MakeAddr();
-    rRange.aEnd.Move( static_cast<SCsCOL>(GetDocSize( tdCol )) - 1, GetDocSize( tdRow ) - 1, 0 );
+    rRange.aEnd.Move( static_cast< SCsCOL >( GetDocSize( tdCol ) ) - 1, static_cast< SCsROW >( GetDocSize( tdRow ) ) - 1, 0 );
 }
 
 void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const
@@ -2281,8 +2284,8 @@ void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos
         {
             SvxBorderLine* pLeftLine = (nCol == 0) ? &aOuterLine : &aInnerLine;
             SvxBorderLine* pRightLine = (nCol == nLastCol) ? &aOuterLine : &aInnerLine;
-            SCCOL nCellCol1 = static_cast<SCCOL>(GetDocPos( tdCol, nCol )) + rFirstPos.Col();
-            SCCOL nCellCol2 = nCellCol1 + static_cast<SCCOL>(GetDocSize( tdCol, nCol )) - 1;
+            SCCOL nCellCol1 = static_cast< SCCOL >( GetDocPos( tdCol, nCol ) ) + rFirstPos.Col();
+            SCCOL nCellCol2 = nCellCol1 + static_cast< SCCOL >( GetDocSize( tdCol, nCol ) ) - 1;
             for( SCROW nRow = 0; nRow <= nLastRow; ++nRow )
             {
                 SvxBorderLine* pTopLine = (nRow == 0) ? &aOuterLine : &aInnerLine;
@@ -2304,11 +2307,10 @@ void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos
         }
     }
 
-    for( ScHTMLTableIterator aIter( mpNestedTables.get() ); aIter.is(); ++aIter )
+    for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
         aIter->ApplyCellBorders( pDoc, rFirstPos );
 }
 
-
 // ----------------------------------------------------------------------------
 
 bool ScHTMLTable::IsEmptyCell() const
@@ -2328,37 +2330,39 @@ ScHTMLTable::ScHTMLEntryPtr ScHTMLTable::CreateEntry() const
 
 void ScHTMLTable::CreateNewEntry( const ImportInfo& rInfo )
 {
-    DBG_ASSERT( !mpCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
-    mpCurrEntry = CreateEntry();
-    mpCurrEntry->aSel = rInfo.aSelection;
+    DBG_ASSERT( !mxCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
+    mxCurrEntry = CreateEntry();
+    mxCurrEntry->aSel = rInfo.aSelection;
 }
 
-void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rpEntry )
+void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry )
 {
     // HTML entry list does not own the entries
-    rEntryList.push_back( rpEntry.get() );
+    rEntryList.push_back( rxEntry.get() );
     // mrEEParseList (reference to member of ScEEParser) owns the entries
-    mrEEParseList.Insert( rpEntry.release(), LIST_APPEND );
+    mrEEParseList.Insert( rxEntry.release(), LIST_APPEND );
 }
 
-bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rpEntry )
+bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rxEntry )
 {
     bool bPushed = false;
-    if( rpEntry.get() && rpEntry->HasContents() )
+    if( rxEntry.get() && rxEntry->HasContents() )
     {
         if( mpCurrEntryList )
         {
             if( mbPushEmptyLine )
             {
-                ScHTMLEntryPtr pEmptyEntry = CreateEntry();
-                ImplPushEntryToList( *mpCurrEntryList, pEmptyEntry );
+                ScHTMLEntryPtr xEmptyEntry = CreateEntry();
+                ImplPushEntryToList( *mpCurrEntryList, xEmptyEntry );
                 mbPushEmptyLine = false;
             }
-            ImplPushEntryToList( *mpCurrEntryList, rpEntry );
+            ImplPushEntryToList( *mpCurrEntryList, rxEntry );
             bPushed = true;
         }
         else if( mpParentTable )
-            bPushed = mpParentTable->PushEntry( rpEntry );
+        {
+            bPushed = mpParentTable->PushEntry( rxEntry );
+        }
         else
         {
             DBG_ERRORFILE( "ScHTMLTable::PushEntry - cannot push entry, no parent found" );
@@ -2369,24 +2373,24 @@ bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rpEntry )
 
 bool ScHTMLTable::PushEntry( const ImportInfo& rInfo, bool bLastInCell )
 {
-    DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
+    DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
     bool bPushed = false;
-    if( mpCurrEntry.get() )
+    if( mxCurrEntry.get() )
     {
-        mpCurrEntry->AdjustEnd( rInfo );
-        mpCurrEntry->Strip( mrEditEngine );
+        mxCurrEntry->AdjustEnd( rInfo );
+        mxCurrEntry->Strip( mrEditEngine );
 
         // import entry always, if it is the last in cell, and cell is still empty
         if( bLastInCell && IsEmptyCell() )
         {
-            mpCurrEntry->SetImportAlways();
+            mxCurrEntry->SetImportAlways();
             // don't insert empty lines before single empty entries
-            if( mpCurrEntry->IsEmpty() )
+            if( mxCurrEntry->IsEmpty() )
                 mbPushEmptyLine = false;
         }
 
-        bPushed = PushEntry( mpCurrEntry );
-        mpCurrEntry.reset();
+        bPushed = PushEntry( mxCurrEntry );
+        mxCurrEntry.reset();
     }
     return bPushed;
 }
@@ -2397,27 +2401,27 @@ bool ScHTMLTable::PushTableEntry( ScHTMLTableId nTableId )
     bool bPushed = false;
     if( nTableId != SC_HTML_GLOBAL_TABLE )
     {
-        ScHTMLEntryPtr pEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
-        bPushed = PushEntry( pEntry );
+        ScHTMLEntryPtr xEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
+        bPushed = PushEntry( xEntry );
     }
     return bPushed;
 }
 
 ScHTMLTable* ScHTMLTable::GetExistingTable( ScHTMLTableId nTableId ) const
 {
-    ScHTMLTable* pTable = ((nTableId != SC_HTML_GLOBAL_TABLE) && mpNestedTables.get()) ?
-        mpNestedTables->FindTable( nTableId, false ) : 0;
+    ScHTMLTable* pTable = ((nTableId != SC_HTML_GLOBAL_TABLE) && mxNestedTables.get()) ?
+        mxNestedTables->FindTable( nTableId, false ) : 0;
     DBG_ASSERT( pTable || (nTableId == SC_HTML_GLOBAL_TABLE), "ScHTMLTable::GetExistingTable - table not found" );
     return pTable;
 }
 
 ScHTMLTable* ScHTMLTable::InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText )
 {
-    if( !mpNestedTables.get() )
-        mpNestedTables.reset( new ScHTMLTableMap( *this ) );
+    if( !mxNestedTables.get() )
+        mxNestedTables.reset( new ScHTMLTableMap( *this ) );
     if( bPreFormText )      // enclose new preformatted table with empty lines
         InsertLeadingEmptyLine();
-    return mpNestedTables->CreateTable( rInfo, bPreFormText );
+    return mxNestedTables->CreateTable( rInfo, bPreFormText );
 }
 
 void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
@@ -2425,20 +2429,29 @@ void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
     ScRange* pRange;
 
     // find an unused cell
-    while( (pRange = maLockList.Find( maCurrCell.MakeAddr() )) != 0 )
+    while( (pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0 )
         maCurrCell.mnCol = pRange->aEnd.Col() + 1;
     mpCurrEntryList = &maEntryMap[ maCurrCell ];
 
     // try to find collisions, shrink existing ranges
     SCCOL nColEnd = maCurrCell.mnCol + rSpanSize.mnCols;
     for( ScAddress aAddr( maCurrCell.MakeAddr() ); aAddr.Col() < nColEnd; aAddr.IncCol() )
-        if( (pRange = maLockList.Find( aAddr )) != 0 )
+        if( (pRange = maVMergedCells.Find( aAddr )) != 0 )
             pRange->aEnd.SetRow( maCurrCell.mnRow - 1 );
 
-    // insert the new range into the lock list
+    // insert the new range into the cell lists
     ScRange aNewRange( maCurrCell.MakeAddr() );
     aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 );
-    maLockList.Append( aNewRange );
+    if( rSpanSize.mnCols > 1 )
+    {
+        maVMergedCells.Append( aNewRange );
+    }
+    else
+    {
+        if( rSpanSize.mnRows > 1 )
+            maHMergedCells.Append( aNewRange );
+        maUsedCells.Join( aNewRange );
+    }
 
     // adjust table size
     maSize.mnCols = ::std::max< SCCOL >( maSize.mnCols, aNewRange.aEnd.Col() + 1 );
@@ -2449,7 +2462,7 @@ void ScHTMLTable::ImplRowOn()
 {
     if( mbRowOn )
         ImplRowOff();
-    mpRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
+    mxRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
     maCurrCell.mnCol = 0;
     mbRowOn = true;
     mbDataOn = false;
@@ -2461,7 +2474,7 @@ void ScHTMLTable::ImplRowOff()
         ImplDataOff();
     if( mbRowOn )
     {
-        mpRowItemSet.reset();
+        mxRowItemSet.reset();
         ++maCurrCell.mnRow;
         mbRowOn = mbDataOn = false;
     }
@@ -2473,7 +2486,7 @@ void ScHTMLTable::ImplDataOn( const ScHTMLSize& rSpanSize )
         ImplDataOff();
     if( !mbRowOn )
         ImplRowOn();
-    mpDataItemSet.reset( new SfxItemSet( *mpRowItemSet ) );
+    mxDataItemSet.reset( new SfxItemSet( *mxRowItemSet ) );
     InsertNewCell( rSpanSize );
     mbDataOn = true;
     mbPushEmptyLine = false;
@@ -2483,7 +2496,7 @@ void ScHTMLTable::ImplDataOff()
 {
     if( mbDataOn )
     {
-        mpDataItemSet.reset();
+        mxDataItemSet.reset();
         ++maCurrCell.mnCol;
         mpCurrEntryList = 0;
         mbDataOn = false;
@@ -2546,11 +2559,17 @@ void ScHTMLTable::ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo&
 
 void ScHTMLTable::SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize )
 {
-    ScSizeVec& rSizes = maSizes[ eOrient ];
-    if( static_cast< size_t >( nCellPos ) >= rSizes.size() )
-        rSizes.resize( static_cast< size_t >( nCellPos + 1 ), 1 );    // expand with minimum height/width == 1
-    if( rSizes[ nCellPos ] < nSize )
-        rSizes[ nCellPos ] = nSize;
+    DBG_ASSERT( nCellPos >= 0, "ScHTMLTable::SetDocSize - unexpected negative position" );
+    ScSizeVec& rSizes = maCumSizes[ eOrient ];
+    size_t nIndex = static_cast< size_t >( nCellPos );
+    // expand with height/width == 1
+    while( nIndex >= rSizes.size() )
+        rSizes.push_back( rSizes.empty() ? 1 : (rSizes.back() + 1) );
+    // update size of passed position and all following
+    SCsCOLROW nDiff = nSize - ((nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]));
+    if( nDiff != 0 )
+        for( ScSizeVec::iterator aIt = rSizes.begin() + nIndex, aEnd = rSizes.end(); aIt != aEnd; ++aIt )
+            *aIt += nDiff;
 }
 
 void ScHTMLTable::CalcNeededDocSize(
@@ -2569,31 +2588,35 @@ void ScHTMLTable::CalcNeededDocSize(
     SetDocSize( eOrient, nCellPos, nRealDocSize );
 }
 
-
 // ----------------------------------------------------------------------------
 
 void ScHTMLTable::FillEmptyCells()
 {
-    for( ScHTMLTableIterator aIter( mpNestedTables.get() ); aIter.is(); ++aIter )
+    for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
         aIter->FillEmptyCells();
 
+    for( const ScRange* pRange = maVMergedCells.First(); pRange; pRange = maVMergedCells.Next() )
+        maUsedCells.Join( *pRange );
+
     for( ScAddress aAddr; aAddr.Row() < maSize.mnRows; aAddr.IncRow() )
     {
         for( aAddr.SetCol( 0 ); aAddr.Col() < maSize.mnCols; aAddr.IncCol() )
         {
-            if( !maLockList.Find( aAddr ) )
+            if( !maUsedCells.Find( aAddr ) )
             {
                 // create a range for the lock list (used to calc. cell span)
                 ScRange aRange( aAddr );
                 do
+                {
                     aRange.aEnd.IncCol();
-                while( (aRange.aEnd.Col() < maSize.mnCols) && !maLockList.Find( aRange.aEnd ) );
+                }
+                while( (aRange.aEnd.Col() < maSize.mnCols) && !maUsedCells.Find( aRange.aEnd ) );
                 aRange.aEnd.IncCol( -1 );
-                maLockList.Append( aRange );
+                maUsedCells.Join( aRange );
 
                 // insert a dummy entry
-                ScHTMLEntryPtr pEntry = CreateEntry();
-                ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], pEntry );
+                ScHTMLEntryPtr xEntry = CreateEntry();
+                ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], xEntry );
             }
         }
     }
@@ -2602,7 +2625,7 @@ void ScHTMLTable::FillEmptyCells()
 void ScHTMLTable::RecalcDocSize()
 {
     // recalc table sizes recursively from inner to outer
-    for( ScHTMLTableIterator aIter( mpNestedTables.get() ); aIter.is(); ++aIter )
+    for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
         aIter->RecalcDocSize();
 
     /*  Two passes: first calculates the sizes of single columns/rows, then
@@ -2617,7 +2640,7 @@ void ScHTMLTable::RecalcDocSize()
         for( ScHTMLEntryMap::const_iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
         {
             const ScHTMLPos& rCellPos = aMapIter->first;
-            ScHTMLSize aCellSpan( GetSpan( rCellPos ) );
+            ScHTMLSize aCellSpan = GetSpan( rCellPos );
 
             const ScHTMLEntryList& rEntryList = aMapIter->second;
             ScHTMLEntryList::const_iterator aListIter;
@@ -2637,7 +2660,7 @@ void ScHTMLTable::RecalcDocSize()
                     ScHTMLTable* pTable = GetExistingTable( (*aListIter)->GetTableId() );
                     // find entry with maximum width
                     if( bProcessColWidth && pTable )
-                        aDocSize.mnCols = ::std::max( aDocSize.mnCols, static_cast<SCCOL>(pTable->GetDocSize( tdCol )) );
+                        aDocSize.mnCols = ::std::max( aDocSize.mnCols, static_cast< SCCOL >( pTable->GetDocSize( tdCol ) ) );
                     // add up height of each entry
                     if( bProcessRowHeight )
                         aDocSize.mnRows += pTable ? pTable->GetDocSize( tdRow ) : 1;
@@ -2646,9 +2669,9 @@ void ScHTMLTable::RecalcDocSize()
                     aDocSize.mnRows = 1;
 
                 if( bProcessColWidth )
-                    CalcNeededDocSize( tdCol, static_cast<SCCOLROW>(rCellPos.mnCol), static_cast<SCCOLROW>(aCellSpan.mnCols), static_cast<SCCOLROW>(aDocSize.mnCols) );
+                    CalcNeededDocSize( tdCol, rCellPos.mnCol, aCellSpan.mnCols, aDocSize.mnCols );
                 if( bProcessRowHeight )
-                    CalcNeededDocSize( tdRow, static_cast<SCCOLROW>(rCellPos.mnRow), static_cast<SCCOLROW>(aCellSpan.mnRows), static_cast<SCCOLROW>(aDocSize.mnRows) );
+                    CalcNeededDocSize( tdRow, rCellPos.mnRow, aCellSpan.mnRows, aDocSize.mnRows );
             }
         }
     }
@@ -2682,12 +2705,12 @@ void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
                 pTable->RecalcDocPos( aEntryDocPos );   // recalc nested table
                 pEntry->nCol = SCCOL_MAX;
                 pEntry->nRow = SCROW_MAX;
-                SCROW nTableRows = static_cast<SCROW>(pTable->GetDocSize( tdRow ));
+                SCROW nTableRows = static_cast< SCROW >( pTable->GetDocSize( tdRow ) );
 
                 // use this entry to pad empty space right of table
                 if( mpParentTable )     // ... but not in global table
                 {
-                    SCCOL nStartCol = aEntryDocPos.mnCol + static_cast<SCCOL>(pTable->GetDocSize( tdCol ));
+                    SCCOL nStartCol = aEntryDocPos.mnCol + static_cast< SCCOL >( pTable->GetDocSize( tdCol ) );
                     SCCOL nNextCol = aEntryDocPos.mnCol + aCellDocSize.mnCols;
                     if( nStartCol < nNextCol )
                     {
@@ -2723,11 +2746,11 @@ void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
                 SCROW nFirstUnusedRow = aCellDocPos.mnRow + aCellDocSize.mnRows;
                 while( aEntryDocPos.mnRow < nFirstUnusedRow )
                 {
-                    ScHTMLEntryPtr pDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
-                    pDummyEntry->nCol = aEntryDocPos.mnCol;
-                    pDummyEntry->nRow = aEntryDocPos.mnRow;
-                    pDummyEntry->nColOverlap = aCellDocSize.mnCols;
-                    ImplPushEntryToList( rEntryList, pDummyEntry );
+                    ScHTMLEntryPtr xDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
+                    xDummyEntry->nCol = aEntryDocPos.mnCol;
+                    xDummyEntry->nRow = aEntryDocPos.mnRow;
+                    xDummyEntry->nColOverlap = aCellDocSize.mnCols;
+                    ImplPushEntryToList( rEntryList, xDummyEntry );
                     ++aEntryDocPos.mnRow;
                 }
             }
@@ -2735,7 +2758,6 @@ void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
     }
 }
 
-
 // ============================================================================
 
 ScHTMLGlobalTable::ScHTMLGlobalTable( SfxItemPool& rPool, EditEngine& rEditEngine, ScEEParseList& rEEParseList, ScHTMLTableId& rnUnusedId ) :
@@ -2757,7 +2779,6 @@ void ScHTMLGlobalTable::Recalc()
     RecalcDocPos( GetDocPos() );
 }
 
-
 // ============================================================================
 
 ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
@@ -2765,8 +2786,8 @@ ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc
     mnUnusedId( SC_HTML_GLOBAL_TABLE ),
     mbTitleOn( false )
 {
-    mpGlobTable.reset( new ScHTMLGlobalTable( *pPool, *pEdit, *pList, mnUnusedId ) );
-    mpCurrTable = mpGlobTable.get();
+    mxGlobTable.reset( new ScHTMLGlobalTable( *pPool, *pEdit, *pList, mnUnusedId ) );
+    mpCurrTable = mxGlobTable.get();
 }
 
 ScHTMLQueryParser::~ScHTMLQueryParser()
@@ -2804,16 +2825,16 @@ ULONG ScHTMLQueryParser::Read( SvStream& rStrm, const String& rBaseURL  )
     ULONG nErr = pEdit->Read( rStrm, rBaseURL, EE_FORMAT_HTML, pAttributes );
     pEdit->SetImportHdl( aOldLink );
 
-    mpGlobTable->Recalc();
-    nColMax = static_cast<SCCOL>(mpGlobTable->GetDocSize( tdCol ) - 1);
-    nRowMax = static_cast<SCROW>(mpGlobTable->GetDocSize( tdRow ) - 1);
+    mxGlobTable->Recalc();
+    nColMax = static_cast< SCCOL >( mxGlobTable->GetDocSize( tdCol ) - 1 );
+    nRowMax = static_cast< SCROW >( mxGlobTable->GetDocSize( tdRow ) - 1 );
 
     return nErr;
 }
 
 const ScHTMLTable* ScHTMLQueryParser::GetGlobalTable() const
 {
-    return mpGlobTable.get();
+    return mxGlobTable.get();
 }
 
 void ScHTMLQueryParser::ProcessToken( const ImportInfo& rInfo )
@@ -2928,7 +2949,7 @@ void ScHTMLQueryParser::FontOn( const ImportInfo& rInfo )
             break;
             case HTML_O_SIZE :
             {
-                sal_uInt32 nSize = bound( aIter->GetNumber(), static_cast<sal_uInt32>(1UL), SC_HTML_FONTSIZES );
+                sal_uInt32 nSize = getLimitedValue< sal_uInt32 >( aIter->GetNumber(), 1, SC_HTML_FONTSIZES );
                 mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ nSize - 1 ], 100, ATTR_FONT_HEIGHT ) );
             }
             break;
@@ -3004,7 +3025,6 @@ void ScHTMLQueryParser::CloseTable( const ImportInfo& rInfo )
     mpCurrTable = mpCurrTable->CloseTable( rInfo );
 }
 
-
 // ----------------------------------------------------------------------------
 
 IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
@@ -3039,6 +3059,5 @@ IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
     return 0;
 }
 
-
 // ============================================================================
 
diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx
index 1ba1518..47e5a94 100644
--- a/sc/source/filter/inc/htmlpars.hxx
+++ b/sc/source/filter/inc/htmlpars.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -218,30 +218,29 @@ const ScHTMLTableId SC_HTML_GLOBAL_TABLE = 0;
 /** Used as table index for normal (non-table) entries in ScHTMLEntry structs. */
 const ScHTMLTableId SC_HTML_NO_TABLE = 0;
 
-
 // ============================================================================
 
 /** A 2D cell position in an HTML table. */
 struct ScHTMLPos
 {
-    SCCOL                  mnCol;
-    SCROW                  mnRow;
-
-    inline explicit             ScHTMLPos() : mnCol( 0 ), mnRow( 0 ) {}
-    inline explicit             ScHTMLPos( SCCOL nCol, SCROW nRow ) :
-                                    mnCol( nCol ), mnRow( nRow ) {}
-    inline explicit             ScHTMLPos( const ScAddress& rAddr ) { Set( rAddr ); }
-
-    inline SCCOLROW           Get( ScHTMLOrient eOrient ) const
-                                    { return (eOrient == tdCol) ? static_cast<SCCOLROW>(mnCol) : static_cast<SCCOLROW>(mnRow); }
-    inline void                 Set( SCCOL nCol, SCROW nRow )
-                                    { mnCol = nCol; mnRow = nRow; }
-    inline void                 Set( const ScAddress& rAddr )
-                                    { Set( rAddr.Col(), rAddr.Row() ); }
-    inline void                 Move( SCsCOL nColDiff, SCsROW nRowDiff )
-                                    { mnCol = mnCol + nColDiff; mnRow = mnRow + nRowDiff; }
-    inline ScAddress            MakeAddr() const
-                                    { return ScAddress( mnCol, mnRow, 0 ); }
+    SCCOL               mnCol;
+    SCROW               mnRow;
+
+    inline explicit     ScHTMLPos() : mnCol( 0 ), mnRow( 0 ) {}
+    inline explicit     ScHTMLPos( SCCOL nCol, SCROW nRow ) :
+                            mnCol( nCol ), mnRow( nRow ) {}
+    inline explicit     ScHTMLPos( const ScAddress& rAddr ) { Set( rAddr ); }
+
+    inline SCCOLROW     Get( ScHTMLOrient eOrient ) const
+                            { return (eOrient == tdCol) ? mnCol : mnRow; }
+    inline void         Set( SCCOL nCol, SCROW nRow )
+                            { mnCol = nCol; mnRow = nRow; }
+    inline void         Set( const ScAddress& rAddr )
+                            { Set( rAddr.Col(), rAddr.Row() ); }
+    inline void         Move( SCsCOL nColDiff, SCsROW nRowDiff )
+                            { mnCol = mnCol + nColDiff; mnRow = mnRow + nRowDiff; }
+    inline ScAddress    MakeAddr() const
+                            { return ScAddress( mnCol, mnRow, 0 ); }
 };
 
 inline bool operator==( const ScHTMLPos& rPos1, const ScHTMLPos& rPos2 )
@@ -254,25 +253,24 @@ inline bool operator<( const ScHTMLPos& rPos1, const ScHTMLPos& rPos2 )
     return (rPos1.mnRow < rPos2.mnRow) || ((rPos1.mnRow == rPos2.mnRow) && (rPos1.mnCol < rPos2.mnCol));
 }
 
-
 // ----------------------------------------------------------------------------
 
 /** A 2D cell size in an HTML table. */
 struct ScHTMLSize
 {
-    SCCOL                  mnCols;
-    SCROW                  mnRows;
-
-    inline explicit             ScHTMLSize() : mnCols( 0 ), mnRows( 0 ) {}
-    inline explicit             ScHTMLSize( SCCOL nCols, SCROW nRows ) :
-                                    mnCols( nCols ), mnRows( nRows ) {}
-
-    inline SCCOLROW           Get( ScHTMLOrient eOrient ) const
-                                    { return (eOrient == tdCol) ? static_cast<SCCOLROW>(mnCols) : static_cast<SCCOLROW>(mnRows); }
-    inline void                 Set( SCCOL nCols, SCROW nRows )
-                                    { mnCols = nCols; mnRows = nRows; }
-    inline void                 Expand( SCsCOL nColDiff, SCsROW nRowDiff )
-                                    { mnCols = mnCols + nColDiff; mnRows = mnRows + nRowDiff; }
+    SCCOL               mnCols;
+    SCROW               mnRows;
+
+    inline explicit     ScHTMLSize() : mnCols( 0 ), mnRows( 0 ) {}
+    inline explicit     ScHTMLSize( SCCOL nCols, SCROW nRows ) :
+                            mnCols( nCols ), mnRows( nRows ) {}
+
+    inline SCCOLROW     Get( ScHTMLOrient eOrient ) const
+                            { return (eOrient == tdCol) ? mnCols : mnRows; }
+    inline void         Set( SCCOL nCols, SCROW nRows )
+                            { mnCols = nCols; mnRows = nRows; }
+    inline void         Expand( SCsCOL nColDiff, SCsROW nRowDiff )
+                            { mnCols = mnCols + nColDiff; mnRows = mnRows + nRowDiff; }
 };
 
 inline bool operator==( const ScHTMLSize& rSize1, const ScHTMLSize& rSize2 )
@@ -280,183 +278,182 @@ inline bool operator==( const ScHTMLSize& rSize1, const ScHTMLSize& rSize2 )
     return (rSize1.mnRows == rSize2.mnRows) && (rSize1.mnCols == rSize2.mnCols);
 }
 
-
 // ============================================================================
 
 /** A single entry containing a line of text or representing a table. */
 struct ScHTMLEntry : public ScEEParseEntry
 {
 public:
-    explicit                    ScHTMLEntry(
-                                    const SfxItemSet& rItemSet,
-                                    ScHTMLTableId nTableId = SC_HTML_NO_TABLE );
+    explicit            ScHTMLEntry(
+                            const SfxItemSet& rItemSet,
+                            ScHTMLTableId nTableId = SC_HTML_NO_TABLE );
 
     /** Returns true, if the selection of the entry is empty. */
-    inline bool                 IsEmpty() const { return !aSel.HasRange(); }
+    inline bool         IsEmpty() const { return !aSel.HasRange(); }
     /** Returns true, if the entry has any content to be imported. */
-    bool                        HasContents() const;
+    bool                HasContents() const;
     /** Returns true, if the entry represents a table. */
-    inline bool                 IsTable() const { return nTab != SC_HTML_NO_TABLE; }
+    inline bool         IsTable() const { return nTab != SC_HTML_NO_TABLE; }
     /** Returns true, if the entry represents a table. */
-    inline ScHTMLTableId        GetTableId() const { return nTab; }
+    inline ScHTMLTableId GetTableId() const { return nTab; }
 
     /** Sets or cleares the import always state. */
-    inline void                 SetImportAlways( bool bSet = true ) { mbImportAlways = bSet; }
+    inline void         SetImportAlways( bool bSet = true ) { mbImportAlways = bSet; }
     /** Sets start point of the entry selection to the start of the import info object. */
-    void                        AdjustStart( const ImportInfo& rInfo );
+    void                AdjustStart( const ImportInfo& rInfo );
     /** Sets end point of the entry selection to the end of the import info object. */
-    void                        AdjustEnd( const ImportInfo& rInfo );
+    void                AdjustEnd( const ImportInfo& rInfo );
     /** Deletes leading and trailing empty paragraphs from the entry. */
-    void                        Strip( const EditEngine& rEditEngine );
+    void                Strip( const EditEngine& rEditEngine );
 
     /** Returns read/write access to the item set of this entry. */
-    inline SfxItemSet&          GetItemSet() { return aItemSet; }
+    inline SfxItemSet&  GetItemSet() { return aItemSet; }
     /** Returns read-only access to the item set of this entry. */
-    inline const SfxItemSet&    GetItemSet() const { return aItemSet; }
+    inline const SfxItemSet& GetItemSet() const { return aItemSet; }
 
 private:
-    bool                        mbImportAlways; /// true = Always import this entry.
+    bool                mbImportAlways;     /// true = Always import this entry.
 };
 
-
 // ============================================================================
 
 /** This struct handles creation of unique table identifiers. */
 struct ScHTMLTableAutoId
 {
-    const ScHTMLTableId         mnTableId;          /// The created unique table identifier.
-    ScHTMLTableId&              mrnUnusedId;        /// Reference to global unused identifier variable.
+    const ScHTMLTableId mnTableId;          /// The created unique table identifier.
+    ScHTMLTableId&      mrnUnusedId;        /// Reference to global unused identifier variable.
 
     /** The constructor assigns an unused identifier to member mnTableId. */
-    explicit                    ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId );
+    explicit            ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId );
 };
 
-
 // ----------------------------------------------------------------------------
 
 class ScHTMLTableMap;
 
 /** Stores data for one table in an HTML document.
-    @descr  This class does the main work for importing an HTML document. It manages
-    the correct insertion of parse entries into the correct cells and the creation
-    of nested tables. Recalculation of resulting document size and position is done
-    recursively in all nested tables. */
+
+    This class does the main work for importing an HTML document. It manages
+    the correct insertion of parse entries into the correct cells and the
+    creation of nested tables. Recalculation of resulting document size and
+    position is done recursively in all nested tables.
+ */
 class ScHTMLTable
 {
 public:
     /** Creates a new HTML table without content.
-        @descr  Internally handles a current cell position. This position is invalid
-        until first calls of RowOn() and DataOn().
+        @descr  Internally handles a current cell position. This position is
+            invalid until first calls of RowOn() and DataOn().
         @param rParentTable  Reference to the parent table that owns this table.
         @param bPreFormText  true = Table is based on preformatted text (<pre> tag). */
-    explicit                    ScHTMLTable(
-                                    ScHTMLTable& rParentTable,
-                                    const ImportInfo& rInfo,
-                                    bool bPreFormText );
+    explicit            ScHTMLTable(
+                            ScHTMLTable& rParentTable,
+                            const ImportInfo& rInfo,
+                            bool bPreFormText );
 
-    virtual                     ~ScHTMLTable();
+    virtual             ~ScHTMLTable();
 
     /** Returns the name of the table, specified in the TABLE tag. */
-    inline const String&        GetTableName() const { return maTableName; }
+    inline const String& GetTableName() const { return maTableName; }
     /** Returns the unique identifier of the table. */
-    inline ScHTMLTableId        GetTableId() const { return maTableId.mnTableId; }
+    inline ScHTMLTableId GetTableId() const { return maTableId.mnTableId; }
     /** Returns the table size. */
-    inline const ScHTMLSize&    GetSize() const { return maSize; }
+    inline const ScHTMLSize& GetSize() const { return maSize; }
     /** Returns the cell spanning of the specified cell. */
-    ScHTMLSize                  GetSpan( const ScHTMLPos& rCellPos ) const;
+    ScHTMLSize          GetSpan( const ScHTMLPos& rCellPos ) const;
 
     /** Searches in all nested tables for the specified table.
         @param nTableId  Unique identifier of the table. */
-    ScHTMLTable*                FindNestedTable( ScHTMLTableId nTableId ) const;
+    ScHTMLTable*        FindNestedTable( ScHTMLTableId nTableId ) const;
 
     /** Puts the item into the item set of the current entry. */
-    void                        PutItem( const SfxPoolItem& rItem );
+    void                PutItem( const SfxPoolItem& rItem );
     /** Inserts a text portion into current entry. */
-    void                        PutText( const ImportInfo& rInfo );
+    void                PutText( const ImportInfo& rInfo );
     /** Inserts a new line, if in preformatted text, else does nothing. */
-    void                        InsertPara( const ImportInfo& rInfo );
+    void                InsertPara( const ImportInfo& rInfo );
 
     /** Inserts a line break (<br> tag).
         @descr  Inserts the current entry regardless if it is empty. */
-    void                        BreakOn();
+    void                BreakOn();
     /** Inserts a heading line (<p> and <h*> tags). */
-    void                        HeadingOn();
+    void                HeadingOn();
     /** Processes a hyperlink (<a> tag). */
-    void                        AnchorOn();
+    void                AnchorOn();
 
     /** Starts a *new* table nested in this table (<table> tag).
         @return  Pointer to the new table. */
-    ScHTMLTable*                TableOn( const ImportInfo& rInfo );
+    ScHTMLTable*        TableOn( const ImportInfo& rInfo );
     /** Closes *this* table (</table> tag).
         @return  Pointer to the parent table. */
-    ScHTMLTable*                TableOff( const ImportInfo& rInfo );
+    ScHTMLTable*        TableOff( const ImportInfo& rInfo );
     /** Starts a *new* table based on preformatted text (<pre> tag).
         @return  Pointer to the new table. */
-    ScHTMLTable*                PreOn( const ImportInfo& rInfo );
+    ScHTMLTable*        PreOn( const ImportInfo& rInfo );
     /** Closes *this* table based on preformatted text (</pre> tag).
         @return  Pointer to the parent table. */
-    ScHTMLTable*                PreOff( const ImportInfo& rInfo );
+    ScHTMLTable*        PreOff( const ImportInfo& rInfo );
 
     /** Starts next row (<tr> tag).
         @descr  Cell address is invalid until first call of DataOn(). */
-    void                        RowOn( const ImportInfo& rInfo );
+    void                RowOn( const ImportInfo& rInfo );
     /** Closes the current row (<tr> tag).
         @descr  Cell address is invalid until call of RowOn() and DataOn(). */
-    void                        RowOff( const ImportInfo& rInfo );
+    void                RowOff( const ImportInfo& rInfo );
     /** Starts the next cell (<td> or <th> tag). */
-    void                        DataOn( const ImportInfo& rInfo );
+    void                DataOn( const ImportInfo& rInfo );
     /** Closes the current cell (</td> or </th> tag).
         @descr  Cell address is invalid until next call of DataOn(). */
-    void                        DataOff( const ImportInfo& rInfo );
+    void                DataOff( const ImportInfo& rInfo );
 
     /** Starts the body of the HTML document (<body> tag). */
-    void                        BodyOn( const ImportInfo& rInfo );
+    void                BodyOn( const ImportInfo& rInfo );
     /** Closes the body of the HTML document (</body> tag). */
-    void                        BodyOff( const ImportInfo& rInfo );
+    void                BodyOff( const ImportInfo& rInfo );
 
     /** Closes *this* table (</table> tag) or preformatted text (</pre> tag).
         @descr  Used to close this table object regardless on opening tag type.
         @return  Pointer to the parent table, or this, if no parent found. */
-    ScHTMLTable*                CloseTable( const ImportInfo& rInfo );
+    ScHTMLTable*        CloseTable( const ImportInfo& rInfo );
 
     /** Returns the resulting document row/column count of the specified HTML row/column. */
-    SCCOLROW                  GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const;
-    /** Returns the resulting document row/column count in the range [nCellBegin, nCellEnd). */
-    SCCOLROW                  GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const;
+    SCCOLROW            GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const;
+    /** Returns the resulting document row/column count in the half-open range [nCellBegin, nCellEnd). */
+    SCCOLROW            GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const;
     /** Returns the total document row/column count in the specified direction. */
-    SCCOLROW                  GetDocSize( ScHTMLOrient eOrient ) const;
+    SCCOLROW            GetDocSize( ScHTMLOrient eOrient ) const;
     /** Returns the total document row/column count of the specified HTML cell. */
-    ScHTMLSize                  GetDocSize( const ScHTMLPos& rCellPos ) const;
+    ScHTMLSize          GetDocSize( const ScHTMLPos& rCellPos ) const;
 
     /** Returns the resulting Calc position of the top left edge of the table. */
-    inline const ScHTMLPos&     GetDocPos() const { return maDocBasePos; }
+    inline const ScHTMLPos& GetDocPos() const { return maDocBasePos; }
     /** Calculates the resulting Calc position of the specified HTML column/row. */
-    SCCOLROW                  GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos = 0 ) const;
+    SCCOLROW            GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos = 0 ) const;
     /** Calculates the resulting Calc position of the specified HTML cell. */
-    ScHTMLPos                   GetDocPos( const ScHTMLPos& rCellPos ) const;
+    ScHTMLPos           GetDocPos( const ScHTMLPos& rCellPos ) const;
 
     /** Calculates the current Calc document area of this table. */
-    void                        GetDocRange( ScRange& rRange ) const;
+    void                GetDocRange( ScRange& rRange ) const;
 
     /** Applies border formatting to the passed document. */
-    void                        ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const;
+    void                ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const;
 
 protected:
     /** Creates a new HTML table without parent.
         @descr  This constructor is used to create the "global table". */
-    explicit                    ScHTMLTable(
-                                    SfxItemPool& rPool,
-                                    EditEngine& rEditEngine,
-                                    ScEEParseList& rEEParseList,
-                                    ScHTMLTableId& rnUnusedId );
+    explicit            ScHTMLTable(
+                            SfxItemPool& rPool,
+                            EditEngine& rEditEngine,
+                            ScEEParseList& rEEParseList,
+                            ScHTMLTableId& rnUnusedId );
 
     /** Fills all empty cells in this and nested tables with dummy parse entries. */
-    void                        FillEmptyCells();
+    void                FillEmptyCells();
     /** Recalculates the size of all columns/rows in the table, regarding nested tables. */
-    void                        RecalcDocSize();
+    void                RecalcDocSize();
     /** Recalculates the position of all cell entries and nested tables.
         @param rBasePos  The origin of the table in the Calc document. */
-    void                        RecalcDocPos( const ScHTMLPos& rBasePos );
+    void                RecalcDocPos( const ScHTMLPos& rBasePos );
 
 private:
     typedef ::std::auto_ptr< ScHTMLTableMap >           ScHTMLTableMapPtr;
@@ -467,172 +464,174 @@ private:
     typedef ::std::auto_ptr< ScHTMLEntry >              ScHTMLEntryPtr;
 
     /** Returns true, if the current cell does not contain an entry yet. */
-    bool                        IsEmptyCell() const;
+    bool                IsEmptyCell() const;
     /** Returns the item set from cell, row, or table, depending on current state. */
-    const SfxItemSet&           GetCurrItemSet() const;
+    const SfxItemSet&   GetCurrItemSet() const;
 
     /** Returns true, if import info represents a space character. */
-    static bool                 IsSpaceCharInfo( const ImportInfo& rInfo );
+    static bool         IsSpaceCharInfo( const ImportInfo& rInfo );
 
     /** Creates and returns a new empty flying entry at position (0,0). */
-    ScHTMLEntryPtr              CreateEntry() const;
+    ScHTMLEntryPtr      CreateEntry() const;
     /** Creates a new flying entry.
         @param rInfo  Contains the initial edit engine selection for the entry. */
-    void                        CreateNewEntry( const ImportInfo& rInfo );
+    void                CreateNewEntry( const ImportInfo& rInfo );
 
     /** Inserts an empty line in front of the next entry. */
-    void                        InsertLeadingEmptyLine();
+    void                InsertLeadingEmptyLine();
 
     /** Pushes the passed entry into the list of the current cell. */
-    void                        ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rpEntry );
+    void                ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry );
     /** Tries to insert the entry into the current cell.
         @descr  If insertion is not possible (i.e., currently no cell open), the
         entry will be inserted into the parent table.
         @return  true = Entry as been pushed into the current cell; false = Entry dropped. */
-    bool                        PushEntry( ScHTMLEntryPtr& rpEntry );
+    bool                PushEntry( ScHTMLEntryPtr& rxEntry );
     /** Puts the current entry into the entry list, if it is not empty.
         @param rInfo  The import info struct containing the end position of the current entry.
         @param bLastInCell  true = If cell is still empty, put this entry always.
         @return  true = Entry as been pushed into the current cell; false = Entry dropped. */
-    bool                        PushEntry( const ImportInfo& rInfo, bool bLastInCell = false );
+    bool                PushEntry( const ImportInfo& rInfo, bool bLastInCell = false );
     /** Pushes a new entry into current cell which references a nested table.
         @return  true = Entry as been pushed into the current cell; false = Entry dropped. */
-    bool                        PushTableEntry( ScHTMLTableId nTableId );
+    bool                PushTableEntry( ScHTMLTableId nTableId );
 
     /** Tries to find a table from the table container.
         @descr  Assumes that the table is located in the current container or
         that the passed table identifier is 0.
         @param nTableId  Unique identifier of the table or 0. */
-    ScHTMLTable*                GetExistingTable( ScHTMLTableId nTableId ) const;
+    ScHTMLTable*        GetExistingTable( ScHTMLTableId nTableId ) const;
     /** Inserts a nested table in the current cell at the specified position.
         @param bPreFormText  true = New table is based on preformatted text (<pre> tag). */
-    ScHTMLTable*                InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText );
+    ScHTMLTable*        InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText );
 
     /** Inserts a new cell in an unused position, starting from current cell position. */
-    void                        InsertNewCell( const ScHTMLSize& rSpanSize );
+    void                InsertNewCell( const ScHTMLSize& rSpanSize );
 
     /** Set internal states for a new table row. */
-    void                        ImplRowOn();
+    void                ImplRowOn();
     /** Set internal states for leaving a table row. */
-    void                        ImplRowOff();
+    void                ImplRowOff();
     /** Set internal states for entering a new table cell. */
-    void                        ImplDataOn( const ScHTMLSize& rSpanSize );
+    void                ImplDataOn( const ScHTMLSize& rSpanSize );
     /** Set internal states for leaving a table cell. */
-    void                        ImplDataOff();
+    void                ImplDataOff();
 
     /** Inserts additional formatting options from import info into the item set. */
-    void                        ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo );
+    void                ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo );
 
     /** Updates the document column/row size of the specified column or row.
         @descr  Only increases the present count, never decreases. */
-    void                        SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize );
+    void                SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize );
     /** Calculates and sets the resulting size the cell needs in the document.
         @descr  Reduces the needed size in merged cells.
         @param nCellPos  The first column/row position of the (merged) cell.
         @param nCellSpan  The cell spanning in the specified orientation.
         @param nRealDocSize  The raw document size of all entries of the cell. */
-    void                        CalcNeededDocSize(
-                                    ScHTMLOrient eOrient, SCCOLROW nCellPos,
-                                    SCCOLROW nCellSpan, SCCOLROW nRealDocSize );
+    void                CalcNeededDocSize(
+                            ScHTMLOrient eOrient, SCCOLROW nCellPos,
+                            SCCOLROW nCellSpan, SCCOLROW nRealDocSize );
 
 private:
-    ScHTMLTable*                mpParentTable;      /// Pointer to parent table.
-    ScHTMLTableMapPtr           mpNestedTables;     /// Table of nested HTML tables.
-    String                      maTableName;        /// Table name from <table id> option.
-    ScHTMLTableAutoId           maTableId;          /// Unique identifier of this table.
-    SfxItemSet                  maTableItemSet;     /// Items for the entire table.
-    SfxItemSetPtr               mpRowItemSet;       /// Items for the current table row.
-    SfxItemSetPtr               mpDataItemSet;      /// Items for the current cell.
-    ScRangeList                 maLockList;         /// Locked cells (needed for merged cells).
-    EditEngine&                 mrEditEngine;       /// Edit engine (from ScEEParser).
-    ScEEParseList&              mrEEParseList;      /// List that owns the parse entries (from ScEEParser).
-    ScHTMLEntryMap              maEntryMap;         /// List of entries for each cell.
-    ScHTMLEntryList*            mpCurrEntryList;    /// Current entry list from map for faster access.
-    ScHTMLEntryPtr              mpCurrEntry;        /// Working entry, not yet inserted in a list.
-    ScSizeVec                   maSizes[ 2 ];       /// Calc cell count of each HTML table column/row.
-    ScHTMLSize                  maSize;             /// Size of the table.
-    ScHTMLPos                   maCurrCell;         /// Address of current cell to fill.
-    ScHTMLPos                   maDocBasePos;       /// Resulting base address in a Calc document.
-    bool                        mbBorderOn;         /// true = Table borders on.
-    bool                        mbPreFormText;      /// true = Table from preformatted text (<pre> tag).
-    bool                        mbRowOn;            /// true = Inside of <tr> </tr>.
-    bool                        mbDataOn;           /// true = Inside of <td> </td> or <th> </th>.
-    bool                        mbPushEmptyLine;    /// true = Insert empty line before current entry.
+    ScHTMLTable*        mpParentTable;      /// Pointer to parent table.
+    ScHTMLTableMapPtr   mxNestedTables;     /// Table of nested HTML tables.
+    String              maTableName;        /// Table name from <table id> option.
+    ScHTMLTableAutoId   maTableId;          /// Unique identifier of this table.
+    SfxItemSet          maTableItemSet;     /// Items for the entire table.
+    SfxItemSetPtr       mxRowItemSet;       /// Items for the current table row.
+    SfxItemSetPtr       mxDataItemSet;      /// Items for the current cell.
+    ScRangeList         maHMergedCells;     /// List of all horizontally merged cells.
+    ScRangeList         maVMergedCells;     /// List of all vertically merged cells.
+    ScRangeList         maUsedCells;        /// List of all used cells.
+    EditEngine&         mrEditEngine;       /// Edit engine (from ScEEParser).
+    ScEEParseList&      mrEEParseList;      /// List that owns the parse entries (from ScEEParser).
+    ScHTMLEntryMap      maEntryMap;         /// List of entries for each cell.
+    ScHTMLEntryList*    mpCurrEntryList;    /// Current entry list from map for faster access.
+    ScHTMLEntryPtr      mxCurrEntry;        /// Working entry, not yet inserted in a list.
+    ScSizeVec           maCumSizes[ 2 ];    /// Cumulated cell counts for each HTML table column/row.
+    ScHTMLSize          maSize;             /// Size of the table.
+    ScHTMLPos           maCurrCell;         /// Address of current cell to fill.
+    ScHTMLPos           maDocBasePos;       /// Resulting base address in a Calc document.
+    bool                mbBorderOn;         /// true = Table borders on.
+    bool                mbPreFormText;      /// true = Table from preformatted text (<pre> tag).
+    bool                mbRowOn;            /// true = Inside of <tr> </tr>.
+    bool                mbDataOn;           /// true = Inside of <td> </td> or <th> </th>.
+    bool                mbPushEmptyLine;    /// true = Insert empty line before current entry.
 };
 
-
 // ----------------------------------------------------------------------------
 
 /** The "global table" representing the entire HTML document. */
 class ScHTMLGlobalTable : public ScHTMLTable
 {
 public:
-    explicit                    ScHTMLGlobalTable(
-                                    SfxItemPool& rPool,
-                                    EditEngine& rEditEngine,
-                                    ScEEParseList& rEEParseList,
-                                    ScHTMLTableId& rnUnusedId );
+    explicit            ScHTMLGlobalTable(
+                            SfxItemPool& rPool,
+                            EditEngine& rEditEngine,
+                            ScEEParseList& rEEParseList,
+                            ScHTMLTableId& rnUnusedId );
 
-    virtual                     ~ScHTMLGlobalTable();
+    virtual             ~ScHTMLGlobalTable();
 
     /** Recalculates sizes and resulting positions of all document entries. */
-    void                        Recalc();
+    void                Recalc();
 };
 
-
 // ============================================================================
 
 /** The HTML parser for data queries. Focuses on data import, not on layout.
-    @descr  Builds the table structure correctly, ignores extended formatting
-    like pictures or column widths. */
+
+    Builds the table structure correctly, ignores extended formatting like
+    pictures or column widths.
+ */
 class ScHTMLQueryParser : public ScHTMLParser
 {
 public:
-    explicit                    ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc );
-    virtual                     ~ScHTMLQueryParser();
+    explicit            ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc );
+    virtual             ~ScHTMLQueryParser();
 
-    virtual ULONG               Read( SvStream& rStrm, const String& rBaseURL  );
+    virtual ULONG       Read( SvStream& rStrm, const String& rBaseURL  );
 
     /** Returns the "global table" which contains the entire HTML document. */
-    virtual const ScHTMLTable*  GetGlobalTable() const;
+    virtual const ScHTMLTable* GetGlobalTable() const;
 
 private:
     /** Handles all possible tags in the HTML document. */
-    void                        ProcessToken( const ImportInfo& rInfo );
+    void                ProcessToken( const ImportInfo& rInfo );
     /** Inserts a text portion into current entry. */
-    void                        InsertText( const ImportInfo& rInfo );
+    void                InsertText( const ImportInfo& rInfo );
     /** Processes the <font> tag. */
-    void                        FontOn( const ImportInfo& rInfo );
+    void                FontOn( const ImportInfo& rInfo );
 
     /** Processes the <meta> tag. */
-    void                        MetaOn( const ImportInfo& rInfo );
+    void                MetaOn( const ImportInfo& rInfo );
     /** Opens the title of the HTML document (<title> tag). */
-    void                        TitleOn( const ImportInfo& rInfo );
+    void                TitleOn( const ImportInfo& rInfo );
     /** Closes the title of the HTML document (</title> tag). */
-    void                        TitleOff( const ImportInfo& rInfo );
+    void                TitleOff( const ImportInfo& rInfo );
 
     /** Opens a new table at the current position. */
-    void                        TableOn( const ImportInfo& rInfo );
+    void                TableOn( const ImportInfo& rInfo );
     /** Closes the current table. */
-    void                        TableOff( const ImportInfo& rInfo );
+    void                TableOff( const ImportInfo& rInfo );
     /** Opens a new table based on preformatted text. */
-    void                        PreOn( const ImportInfo& rInfo );
+    void                PreOn( const ImportInfo& rInfo );
     /** Closes the current preformatted text table. */
-    void                        PreOff( const ImportInfo& rInfo );
+    void                PreOff( const ImportInfo& rInfo );
 
     /** Closes the current table, regardless on opening tag. */
-    void                        CloseTable( const ImportInfo& rInfo );
+    void                CloseTable( const ImportInfo& rInfo );
 
     DECL_LINK( HTMLImportHdl, const ImportInfo* );
 
 private:
     typedef ::std::auto_ptr< ScHTMLGlobalTable >    ScHTMLGlobalTablePtr;
 
-    String                      maTitle;            /// The title of the document.
-    ScHTMLGlobalTablePtr        mpGlobTable;        /// Contains the entire imported document.
-    ScHTMLTable*                mpCurrTable;        /// Pointer to current table (performance).
-    ScHTMLTableId               mnUnusedId;         /// First unused table identifier.
-    bool                        mbTitleOn;          /// true = Inside of <title> </title>.
+    String              maTitle;            /// The title of the document.
+    ScHTMLGlobalTablePtr mxGlobTable;       /// Contains the entire imported document.
+    ScHTMLTable*        mpCurrTable;        /// Pointer to current table (performance).
+    ScHTMLTableId       mnUnusedId;         /// First unused table identifier.
+    bool                mbTitleOn;          /// true = Inside of <title> </title>.
 };
 
 
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx
index b186f9a..c5132d0 100644
--- a/sc/source/filter/lotus/op.cxx
+++ b/sc/source/filter/lotus/op.cxx
@@ -466,7 +466,7 @@ void OP_Note123( SvStream& r, UINT16 n)
     delete [] pText;
 
     ScAddress aPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab) );
-    ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false );
+    ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
 }
 
 void OP_HorAlign123( BYTE nAlignPattern, SfxItemSet& rPatternItemSet )
diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx
index 831e837..df86612 100644
--- a/sc/source/filter/starcalc/scflt.cxx
+++ b/sc/source/filter/starcalc/scflt.cxx
@@ -1714,7 +1714,7 @@ void Sc10Import::LoadCol(SCCOL Col, SCTAB Tab)
                 String aNoteText( SC10TOSTRING(pNote));
                 delete [] pNote;
                 ScAddress aPos( Col, static_cast<SCROW>(Row), Tab );
-                ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false );
+                ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
             }
         }
         pPrgrsBar->Progress();
diff --git a/sc/source/filter/xml/xmlannoi.cxx b/sc/source/filter/xml/xmlannoi.cxx
index 85967f2..5ea1865 100644
--- a/sc/source/filter/xml/xmlannoi.cxx
+++ b/sc/source/filter/xml/xmlannoi.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -31,13 +31,10 @@
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_sc.hxx"
 
-
-
 // INCLUDE ---------------------------------------------------------------
 
 #include "xmlannoi.hxx"
 #include "xmlimprt.hxx"
-#include "xmlcelli.hxx"
 #include "xmlconti.hxx"
 #include "XMLTableShapeImportHelper.hxx"
 
@@ -45,25 +42,34 @@
 #include <xmloff/nmspmap.hxx>
 #include <xmloff/xmlnmspe.hxx>
 #include <xmloff/xmltoken.hxx>
-#include <svx/unoshape.hxx>
-#include <svx/svdobj.hxx>
-#include <svx/outlobj.hxx>
 
 using namespace com::sun::star;
 using namespace xmloff::token;
 
 //------------------------------------------------------------------
 
+ScXMLAnnotationData::ScXMLAnnotationData() :
+    mbUseShapePos( false ),
+    mbShown( false )
+{
+}
+
+ScXMLAnnotationData::~ScXMLAnnotationData()
+{
+}
+
+//------------------------------------------------------------------
+
 ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport,
                                       USHORT nPrfx,
                                       const ::rtl::OUString& rLName,
                                       const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+                                      ScXMLAnnotationData& rAnnotationData,
                                       ScXMLTableRowCellContext* pTempCellContext) :
     SvXMLImportContext( rImport, nPrfx, rLName ),
+    mrAnnotationData( rAnnotationData ),
     nParagraphCount(0),
-    bDisplay(sal_False),
     bHasTextP(sal_False),
-    bHasPos(sal_False),
     pCellContext(pTempCellContext),
     pShapeContext(NULL)
 {
@@ -91,32 +97,32 @@ ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport,
         {
             case XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR:
             {
-                sAuthorBuffer = sValue;
+                maAuthorBuffer = sValue;
             }
             break;
             case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE:
             {
-                sCreateDateBuffer = sValue;
+                maCreateDateBuffer = sValue;
             }
             break;
             case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING:
             {
-                sCreateDateStringBuffer = sValue;
+                maCreateDateStringBuffer = sValue;
             }
             break;
             case XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY:
             {
-                bDisplay = IsXMLToken(sValue, XML_TRUE);
+                mrAnnotationData.mbShown = IsXMLToken(sValue, XML_TRUE);
             }
             break;
             case XML_TOK_TABLE_ANNOTATION_ATTR_X:
             {
-                bHasPos = sal_True;
+                mrAnnotationData.mbUseShapePos = true;
             }
             break;
             case XML_TOK_TABLE_ANNOTATION_ATTR_Y:
             {
-                bHasPos = sal_True;
+                mrAnnotationData.mbUseShapePos = true;
             }
             break;
         }
@@ -144,28 +150,28 @@ SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( USHORT nPrefix,
     {
         if( IsXMLToken( rLName, XML_CREATOR ) )
             pContext = new ScXMLContentContext(GetScImport(), nPrefix,
-                                            rLName, xAttrList, sAuthorBuffer);
+                                            rLName, xAttrList, maAuthorBuffer);
         else if( IsXMLToken( rLName, XML_DATE ) )
             pContext = new ScXMLContentContext(GetScImport(), nPrefix,
-                                            rLName, xAttrList, sCreateDateBuffer);
+                                            rLName, xAttrList, maCreateDateBuffer);
     }
     else if( XML_NAMESPACE_META == nPrefix )
     {
         if( IsXMLToken( rLName, XML_DATE_STRING ) )
             pContext = new ScXMLContentContext(GetScImport(), nPrefix,
-                                            rLName, xAttrList, sCreateDateStringBuffer);
+                                            rLName, xAttrList, maCreateDateStringBuffer);
     }
 /*	else if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_P) )
     {
         if (!bHasTextP)
         {
             bHasTextP = sal_True;
-            sOUText.setLength(0);
+            maTextBuffer.setLength(0);
         }
         if(nParagraphCount)
-            sOUText.append(static_cast<sal_Unicode>('\n'));
+            maTextBuffer.append(static_cast<sal_Unicode>('\n'));
         ++nParagraphCount;
-        pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sOUText);
+        pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, maTextBuffer);
     }*/
 
     if( !pContext && pShapeContext )
@@ -180,7 +186,7 @@ SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( USHORT nPrefix,
 void ScXMLAnnotationContext::Characters( const ::rtl::OUString& rChars )
 {
     if (!bHasTextP)
-        sOUText.append(rChars);
+        maTextBuffer.append(rChars);
 }
 
 void ScXMLAnnotationContext::EndElement()
@@ -191,41 +197,19 @@ void ScXMLAnnotationContext::EndElement()
         delete pShapeContext;
     }
 
-    ScMyImportAnnotation* pMyAnnotation = new ScMyImportAnnotation();
-    pMyAnnotation->sAuthor = sAuthorBuffer.makeStringAndClear();
-    pMyAnnotation->sCreateDate = sCreateDateBuffer.makeStringAndClear();
-    if (!pMyAnnotation->sCreateDate.getLength())
-        pMyAnnotation->sCreateDate = sCreateDateStringBuffer.makeStringAndClear();
-    pMyAnnotation->sText = sOUText.makeStringAndClear();
-    pMyAnnotation->bDisplay = bDisplay;
-
-    if (xShape.is() && xShapes.is())
-    {
-        SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
-        if (pShapeImp)
-        {
-            SdrObject *pSdrObj = pShapeImp->GetSdrObject();
-            if (pSdrObj)
-            {
-                if (bHasPos)
-                {
-                    pMyAnnotation->pItemSet = pSdrObj->GetMergedItemSet().Clone();
-                    awt::Point aPos = xShape->getPosition();
-                    awt::Size aSize = xShape->getSize();
-                    Rectangle aRect(Point(aPos.X, aPos.Y), Size(aSize.Width, aSize.Height));
-                    pMyAnnotation->pRect = new Rectangle(aRect);
-                }
-
-                if( OutlinerParaObject* pOPO = pSdrObj->GetOutlinerParaObject() )
-                    pMyAnnotation->pOPO = new OutlinerParaObject( *pOPO );
-
-                xShapes->remove(xShape);
-            }
-        }
-    }
+    mrAnnotationData.maAuthor = maAuthorBuffer.makeStringAndClear();
+    mrAnnotationData.maCreateDate = maCreateDateBuffer.makeStringAndClear();
+    if (!mrAnnotationData.maCreateDate.getLength())
+        mrAnnotationData.maCreateDate = maCreateDateStringBuffer.makeStringAndClear();
+    mrAnnotationData.maSimpleText = maTextBuffer.makeStringAndClear();
 
     XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
     pTableShapeImport->SetAnnotation(NULL);
+}
 
-    pCellContext->AddAnnotation(pMyAnnotation);
+void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes )
+{
+    mrAnnotationData.mxShape = rxShape;
+    mrAnnotationData.mxShapes = rxShapes;
 }
+
diff --git a/sc/source/filter/xml/xmlannoi.hxx b/sc/source/filter/xml/xmlannoi.hxx
index c834f55..c509b72 100644
--- a/sc/source/filter/xml/xmlannoi.hxx
+++ b/sc/source/filter/xml/xmlannoi.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -30,6 +30,7 @@
 #ifndef SC_XMLANNOI_HXX
 #define SC_XMLANNOI_HXX
 
+#include <memory>
 #include <xmloff/xmlictxt.hxx>
 #include <xmloff/xmlimp.hxx>
 #include <rtl/ustrbuf.hxx>
@@ -39,30 +40,31 @@
 class ScXMLImport;
 class ScXMLTableRowCellContext;
 
-class ScXMLAnnotationContext : public SvXMLImportContext
+struct ScXMLAnnotationData
 {
-    rtl::OUStringBuffer	sOUText;
-    rtl::OUStringBuffer	sAuthorBuffer;
-    rtl::OUStringBuffer	sCreateDateBuffer;
-    rtl::OUStringBuffer	sCreateDateStringBuffer;
-    sal_Int32		nParagraphCount;
-    sal_Bool		bDisplay;
-    sal_Bool		bHasTextP;
-    sal_Bool        bHasPos;
-    ScXMLTableRowCellContext*	pCellContext;
-    SvXMLImportContext*         pShapeContext;
-    com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
-    com::sun::star::uno::Reference< com::sun::star::drawing::XShapes > xShapes;
+    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+                        mxShape;
+    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+                        mxShapes;
+    ::rtl::OUString     maAuthor;
+    ::rtl::OUString     maCreateDate;
+    ::rtl::OUString     maSimpleText;
+    bool                mbUseShapePos;
+    bool                mbShown;
 
-    const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
-    ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+    explicit            ScXMLAnnotationData();
+                        ~ScXMLAnnotationData();
+};
 
+class ScXMLAnnotationContext : public SvXMLImportContext
+{
 public:
 
     ScXMLAnnotationContext( ScXMLImport& rImport, USHORT nPrfx,
                         const ::rtl::OUString& rLName,
                         const ::com::sun::star::uno::Reference<
                                         ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+                        ScXMLAnnotationData& rAnnotationData,
                         ScXMLTableRowCellContext* pCellContext);
 
     virtual ~ScXMLAnnotationContext();
@@ -78,8 +80,23 @@ public:
 
     virtual void EndElement();
 
-    void SetShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xTempShape,
-        const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& xTempShapes) { xShape.set(xTempShape); xShapes.set(xTempShapes); }
+    void SetShape(
+        const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+        const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes );
+
+private:
+    ScXMLAnnotationData& mrAnnotationData;
+    rtl::OUStringBuffer maTextBuffer;
+    rtl::OUStringBuffer maAuthorBuffer;
+    rtl::OUStringBuffer maCreateDateBuffer;
+    rtl::OUStringBuffer maCreateDateStringBuffer;
+    sal_Int32           nParagraphCount;
+    sal_Bool            bHasTextP;
+    ScXMLTableRowCellContext* pCellContext;
+    SvXMLImportContext* pShapeContext;
+
+    const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+    ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
 };
 
 
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 1c4948e..91a9368 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -68,6 +68,7 @@
 #include <svx/svdocapt.hxx>
 #include <svx/outlobj.hxx>
 #include <svx/editobj.hxx>
+#include <svx/unoapi.hxx>
 #include <svtools/languageoptions.hxx>
 
 #include <com/sun/star/frame/XModel.hpp>
@@ -99,15 +100,6 @@ using namespace xmloff::token;
 
 //------------------------------------------------------------------
 
-ScMyImportAnnotation::~ScMyImportAnnotation()
-{
-    delete pRect;
-    delete pItemSet;
-    delete pOPO;
-}
-
-//------------------------------------------------------------------
-
 ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
                                       USHORT nPrfx,
                                       const ::rtl::OUString& rLName,
@@ -117,7 +109,6 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
                                       const sal_Int32 nTempRepeatedRows ) :
     SvXMLImportContext( rImport, nPrfx, rLName ),
     pContentValidationName(NULL),
-    pMyAnnotation(NULL),
     pDetectiveObjVec(NULL),
     pCellRangeSource(NULL),
     fValue(0.0),
@@ -283,8 +274,6 @@ ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
 {
     if (pContentValidationName)
         delete pContentValidationName;
-    if (pMyAnnotation)
-        delete pMyAnnotation;
     if (pDetectiveObjVec)
         delete pDetectiveObjVec;
     if (pCellRangeSource)
@@ -425,8 +414,10 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( USHORT nPrefix
     case XML_TOK_TABLE_ROW_CELL_ANNOTATION:
         {
             bIsEmpty = sal_False;
+            DBG_ASSERT( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" );
+            mxAnnotationData.reset( new ScXMLAnnotationData );
             pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName,
-                                                    xAttrList, this);
+                                                    xAttrList, *mxAnnotationData, this);
         }
         break;
     case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
@@ -607,71 +598,98 @@ void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCe
 
 void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddress)
 {
-    /*uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor(xCell, uno::UNO_QUERY);
-    if (xSheetAnnotationAnchor.is())
+    ScDocument* pDoc = rXMLImport.GetDocument();
+    if( !pDoc || !mxAnnotationData.get() )
+        return;
+
+    LockSolarMutex();
+
+    ScAddress aPos;
+    ScUnoConversion::FillScAddress( aPos, aCellAddress );
+    ScPostIt* pNote = 0;
+
+    uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes();
+    uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY );
+    sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0;
+
+    DBG_ASSERT( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(),
+        "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" );
+    if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() )
     {
-        uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation (xSheetAnnotationAnchor->getAnnotation());
-        uno::Reference<text::XSimpleText> xSimpleText(xSheetAnnotation, uno::UNO_QUERY);
-        if (xSheetAnnotation.is() && xSimpleText.is())
+        DBG_ASSERT( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" );
+        SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape );
+        DBG_ASSERT( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" );
+
+        /*  Try to reuse the drawing object already created (but only if the
+            note is visible, and the object is a caption object). */
+        if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos )
         {
-            xSimpleText->setString(aMyAnnotation.sText);
-            //xSheetAnnotation->setAuthor(aMyAnnotation.sAuthor);
-            //xSheetAnnotation->setDate();
-            xSheetAnnotation->setIsVisible(aMyAnnotation.bDisplay);
+            if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
+            {
+                OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" );
+                // create the cell note with the caption object
+                pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, aPos, *pCaption, true );
+                // forget pointer to object (do not create note again below)
+                pObject = 0;
+            }
         }
-    }*/
-    if( pMyAnnotation )
-    {
-        double fDate;
-        rXMLImport.GetMM100UnitConverter().convertDateTime(fDate, pMyAnnotation->sCreateDate);
-        ScDocument* pDoc = rXMLImport.GetDocument();
-        if (pDoc)
+
+        // drawing object has not been used to create a note -> use shape data
+        if( pObject )
         {
-            LockSolarMutex();
-            SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
-            sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
-            String sDate;
-            Color* pColor = NULL;
-            Color** ppColor = &pColor;
-            pNumForm->GetOutputString(fDate, nfIndex, sDate, ppColor);
+            // rescue settings from drawing object before the shape is removed
+            ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) );
+            ::std::auto_ptr< OutlinerParaObject > xOutlinerObj;
+            if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() )
+                xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) );
+            Rectangle aCaptionRect;
+            if( mxAnnotationData->mbUseShapePos )
+                aCaptionRect = pObject->GetLogicRect();
+            // remove the shape from the drawing page, this invalidates pObject
+            mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape );
+            pObject = 0;
+            // update current number of existing objects
+            if( xShapesIA.is() )
+                nOldShapeCount = xShapesIA->getCount();
 
-            ScAddress aPos;
-            ScUnoConversion::FillScAddress( aPos, aCellAddress );
-            if( ScPostIt* pNote = pDoc->GetOrCreateNote( aPos ) )
+            // an outliner object is required (empty note captions not allowed)
+            if( xOutlinerObj.get() )
             {
-                pNote->SetDate( sDate );
-                pNote->SetAuthor( pMyAnnotation->sAuthor );
-                if( SdrCaptionObj* pCaption = pNote->GetCaption() )
-                {
-                    if( pMyAnnotation->pOPO )
-                    {
-                        // transfer outliner object to caption
-                        pCaption->SetOutlinerParaObject( pMyAnnotation->pOPO );
-                        // do not delete the object in ScMyImportAnnotation d'tor 
-                        pMyAnnotation->pOPO = 0;
-                    }
-                    else
-                        pCaption->SetText( pMyAnnotation->sText );
-                    // copy all items and reset shadow items
-                    if( pMyAnnotation->pItemSet )
-                        pNote->SetCaptionItems( *pMyAnnotation->pItemSet );
-                    else
-                        pNote->SetCaptionDefaultItems();    // default items need to be applied to text
-                    if( pMyAnnotation->pRect )
-                        pCaption->SetLogicRect( *pMyAnnotation->pRect );
-
-                    uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
-                    if (xShapesIndex.is())
-                    {
-                        sal_Int32 nShapes = xShapesIndex->getCount();
-                        uno::Reference < drawing::XShape > xShape;
-                        rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
-                    }
-                }
-                pNote->ShowCaption( pMyAnnotation->bDisplay );
+                // create cell note with all data from drawing object
+                pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, aPos,
+                    xItemSet.release(), xOutlinerObj.release(),
+                    aCaptionRect, mxAnnotationData->mbShown, false );
             }
         }
     }
+    else if( mxAnnotationData->maSimpleText.getLength() > 0 )
+    {
+        // create note from simple text
+        pNote = ScNoteUtil::CreateNoteFromString( *pDoc, aPos,
+            mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false );
+    }
+
+    // set author and date
+    if( pNote )
+    {
+        double fDate;
+        rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate );
+        SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
+        sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM );
+        String aDate;
+        Color* pColor = 0;
+        Color** ppColor = &pColor;
+        pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor );
+        pNote->SetDate( aDate );
+        pNote->SetAuthor( mxAnnotationData->maAuthor );
+    }
+
+    // register a shape that has been newly created in the ScNoteUtil functions
+    if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) )
+    {
+        uno::Reference< drawing::XShape > xShape;
+        rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
+    }
 }
 
 // core implementation
@@ -760,7 +778,7 @@ void ScXMLTableRowCellContext::EndElement()
             if ( !pOUFormula )
             {
                 ::boost::optional< rtl::OUString > pOUText;
-                
+
                 if(nCellType == util::NumberFormat::TEXT)
                 {
                     if (xLockable.is())
@@ -790,7 +808,7 @@ void ScXMLTableRowCellContext::EndElement()
                     }
                     if (     (!pOUTextContent && !pOUText && !pOUTextValue)
                         && ( (pOUTextContent && !pOUTextContent->getLength()) || !pOUTextContent )
-                        && ( (pOUText && !pOUText->getLength()) || !pOUText ) 
+                        && ( (pOUText && !pOUText->getLength()) || !pOUText )
                         && ( (pOUTextValue && !pOUTextValue->getLength()) || !pOUTextValue ))
                             bIsEmpty = sal_True;
                 }
@@ -798,7 +816,7 @@ void ScXMLTableRowCellContext::EndElement()
 //				uno::Reference <table::XCell> xCell;
                 table::CellAddress aCurrentPos( aCellPos );
                 if ((pContentValidationName && pContentValidationName->getLength()) ||
-                    pMyAnnotation || pDetectiveObjVec || pCellRangeSource)
+                    mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource)
                     bIsEmpty = sal_False;
 
                 ScMyTables& rTables = rXMLImport.GetTables();
@@ -980,7 +998,7 @@ void ScXMLTableRowCellContext::EndElement()
                             }
                             else
                             {
-                                if (!bWasEmpty || (pMyAnnotation))
+                                if (!bWasEmpty || mxAnnotationData.get())
                                 {
                                     if (aCurrentPos.Row > MAXROW)
                                         rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 8ce894a..644ddb0 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -30,6 +30,7 @@
 #ifndef SC_XMLCELLI_HXX
 #define SC_XMLCELLI_HXX
 
+#include <memory>
 #include "XMLDetectiveContext.hxx"
 #include "XMLCellRangeSourceContext.hxx"
 #include <xmloff/xmlictxt.hxx>
@@ -37,7 +38,6 @@
 #include <com/sun/star/table/XCell.hpp>
 #include <tools/time.hxx>
 #include <com/sun/star/util/DateTime.hpp>
-#include <sal/types.h>
 #include <com/sun/star/table/XCellRange.hpp>
 #include <com/sun/star/table/CellRangeAddress.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
@@ -48,21 +48,7 @@
 #include <boost/optional.hpp>
 
 class ScXMLImport;
-class OutlinerParaObject;
-
-struct ScMyImportAnnotation
-{
-    rtl::OUString sAuthor;
-    rtl::OUString sCreateDate;
-    rtl::OUString sText;
-    sal_Bool bDisplay;
-    Rectangle* pRect;
-    SfxItemSet* pItemSet;
-    OutlinerParaObject* pOPO;
-
-    ScMyImportAnnotation() : bDisplay(sal_False), pRect(NULL), pItemSet(NULL), pOPO(NULL) {}
-    ~ScMyImportAnnotation();
-};
+struct ScXMLAnnotationData;
 
 class ScXMLTableRowCellContext : public SvXMLImportContext
 {
@@ -72,7 +58,7 @@ class ScXMLTableRowCellContext : public SvXMLImportContext
     ::boost::optional< rtl::OUString > pOUTextContent;
     ::boost::optional< rtl::OUString > pOUFormula;
     rtl::OUString* pContentValidationName;
-    ScMyImportAnnotation*	pMyAnnotation;
+    ::std::auto_ptr< ScXMLAnnotationData > mxAnnotationData;
     ScMyImpDetectiveObjVec*	pDetectiveObjVec;
     ScMyImpCellRangeSource*	pCellRangeSource;
     double		fValue;
@@ -140,8 +126,6 @@ public:
     void SetCellRangeSource( const ::com::sun::star::table::CellAddress& rPosition );
 
     virtual void EndElement();
-
-    void AddAnnotation(ScMyImportAnnotation* pValue) { pMyAnnotation = pValue; }
 };
 
 #endif
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index ef4fa69..975d9b2 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -596,6 +596,7 @@ void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCo
                 if (!pSharedData)
                     CreateSharedData(nTableCount);
                 pCellStyles->AddNewTable(nTableCount - 1);
+                pDoc->InitializeAllNoteCaptions( true );
                 if (HasDrawPages(xSpreadDoc))
                 {
                     rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index d37e622..8e95e26 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -2850,6 +2850,43 @@ void ScXMLImport::ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc)
     }
 }
 
+sal_Int32 ScXMLImport::GetVisibleSheet()
+{
+    // Get the visible sheet number from model's view data (after settings were loaded),
+    // or 0 (default: first sheet) if no settings available.
+
+    uno::Reference<document::XViewDataSupplier> xSupp(GetModel(), uno::UNO_QUERY);
+    if (xSupp.is())
+    {
+        uno::Reference<container::XIndexAccess> xIndex = xSupp->getViewData();
+        if ( xIndex.is() && xIndex->getCount() > 0 )
+        {
+            uno::Any aAny( xIndex->getByIndex(0) );
+            uno::Sequence<beans::PropertyValue> aViewSettings;  // settings for (first) view
+            if ( aAny >>= aViewSettings )
+            {
+                sal_Int32 nCount = aViewSettings.getLength();
+                for (sal_Int32 i = 0; i < nCount; ++i)
+                {
+                    if ( aViewSettings[i].Name.compareToAscii(SC_ACTIVETABLE) == 0 )
+                    {
+                        rtl::OUString sValue;
+                        if(aViewSettings[i].Value >>= sValue)
+                        {
+                            String sTabName(sValue);
+                            SCTAB nTab = 0;
+                            if (pDoc->GetTable(sTabName, nTab))
+                                return nTab;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
 // static
 bool ScXMLImport::IsAcceptedFormulaNamespace( const sal_uInt16 nFormulaPrefix,
                                              const rtl::OUString & rValue, formula::FormulaGrammar::Grammar& rGrammar,
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index ad17e2a..efb2b14 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -983,6 +983,7 @@ public:
     void SetLabelRanges();
     void AddDefaultNote( const com::sun::star::table::CellAddress& aCell );
 
+    sal_Int32   GetVisibleSheet();
 
     /** If namespace prefix is an accepted formula namespace.
 
diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx
index e6dd105..d3748c3 100644
--- a/sc/source/filter/xml/xmlstyli.cxx
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -248,8 +248,14 @@ void ScXMLRowImportPropertyMapper::finished(::std::vector< XMLPropertyState >& r
         if (::cppu::any2bool(pOptimalHeight->maValue))
         {
             if (pHeight)
+            {
+                // set the stored height, but keep "optimal" flag:
+                // pass the height value as OptimalHeight property (only allowed while loading!)
+                pOptimalHeight->maValue = pHeight->maValue;
                 pHeight->mnIndex = -1;
-            pOptimalHeight->mnIndex = -1;
+            }
+            else
+                pOptimalHeight->mnIndex = -1;
         }
     }
     else if (pHeight)
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 6464ee6..81d830a 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -38,11 +38,13 @@
 #include "xmlstyli.hxx"
 #include "xmlimprt.hxx"
 #include "document.hxx"
+#include "markdata.hxx"
 #include "XMLConverter.hxx"
 #include "docuno.hxx"
 #include "cellsuno.hxx"
 #include "XMLStylesImportHelper.hxx"
 #include "tabprotection.hxx"
+#include <svx/svdpage.hxx>
 
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/nmspmap.hxx>
@@ -581,7 +583,35 @@ void ScMyTables::UpdateRowHeights()
     {
         rImport.LockSolarMutex();
         // update automatic row heights
-        ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights();
+
+        // For sheets with any kind of shapes (including notes),
+        // update row heights immediately (before setting the positions).
+        // For sheets without shapes, set "pending" flag
+        // and update row heights when a sheet is shown.
+        // The current sheet (from view settings) is always updated immediately.
+
+        ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+        if (pDoc)
+        {
+            SCTAB nCount = pDoc->GetTableCount();
+            ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+
+            SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() );
+
+            ScMarkData aUpdateSheets;
+            for (SCTAB nTab=0; nTab<nCount; ++nTab)
+            {
+                const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL;
+                if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) )
+                    aUpdateSheets.SelectTable( nTab, TRUE );
+                else
+                    pDoc->SetPendingRowHeights( nTab, TRUE );
+            }
+
+            if (aUpdateSheets.GetSelectCount())
+                ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
+        }
+
         rImport.UnlockSolarMutex();
     }
 }
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index c52e8d6..884b95f 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1052,7 +1052,7 @@ bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
     if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;
 
     // move the caption to internal or hidden layer and create undo action
-    pNote->ShowCaption( bShow );
+    pNote->ShowCaption( rPos, bShow );
     if( rDoc.IsUndoEnabled() )
         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
 
@@ -1080,7 +1080,7 @@ bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, BOOL bA
     aNewText.ConvertLineEnd();		//! ist das noetig ???
 
     if( ScPostIt* pNote = (aNewText.Len() > 0) ? pDoc->GetOrCreateNote( rPos ) : pDoc->GetNote( rPos ) )
-        pNote->SetText( aNewText );
+        pNote->SetText( rPos, aNewText );
 
     //!	Undo !!!
 
@@ -1104,23 +1104,26 @@ bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, con
         ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
         SfxUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;
 
-        // collect drawing undo actions for deleting/inserting caption obejcts
-        if( pUndoMgr )
-            pDrawLayer->BeginCalcUndo();
-
-        // delete old note
         ScNoteData aOldData;
-        if( ScPostIt* pOldNote = rDoc.ReleaseNote( rPos ) )
+        ScPostIt* pOldNote = rDoc.ReleaseNote( rPos );
+        if( pOldNote )
         {
+            // ensure existing caption object before draw undo tracking starts
+            pOldNote->GetOrCreateCaption( rPos );
             // rescue note data for undo
             aOldData = pOldNote->GetNoteData();
-            // delete the note (creates drawing undo action for the caption object)
-            delete pOldNote;
         }
 
+        // collect drawing undo actions for deleting/inserting caption obejcts
+        if( pUndoMgr )
+            pDrawLayer->BeginCalcUndo();
+
+        // delete the note (creates drawing undo action for the caption object)
+        delete pOldNote;
+
         // create new note (creates drawing undo action for the new caption object)
         ScNoteData aNewData;
-        if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false ) )
+        if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true ) )
         {
             if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
             if( pDate ) pNewNote->SetDate( *pDate );
@@ -1613,7 +1616,7 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
                 rDocShell.GetUndoManager()->LeaveListAction();
             }
 
-            rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells( 
+            rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
                 &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
                 nUndoPos, pTabs, pScenarios, eCmd, pRefUndoDoc, pUndoData, bPartOfPaste ) );
         }
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index a463660..a3e866b 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1842,6 +1842,10 @@ void lcl_GetPrintData( ScDocShell* pDocShell /*in*/,
         rOptions = SC_MOD()->GetPrintOptions();
     }
 
+    // update all pending row heights with a single progress bar,
+    // instead of a separate progress for each sheet from ScPrintFunc
+    pDocShell->UpdatePendingRowHeights( MAXTAB, true );
+
     // get number of total pages
     rnTotalPages = 0;
     SCTAB nTabCount = pDocument->GetTableCount();
diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
index e288b74..dd8e609 100644
--- a/sc/source/ui/docshell/docsh5.cxx
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -393,13 +393,51 @@ BOOL ScDocShell::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab )
     return bChange;
 }
 
-void ScDocShell::UpdateAllRowHeights()
+void ScDocShell::UpdateAllRowHeights( const ScMarkData* pTabMark )
 {
     // update automatic row heights
 
     ScSizeDeviceProvider aProv(this);
     Fraction aZoom(1,1);
-    aDocument.UpdateAllRowHeights( aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), aZoom, aZoom );
+    aDocument.UpdateAllRowHeights( aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), aZoom, aZoom, pTabMark );
+}
+
+void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore )
+{
+    BOOL bIsUndoEnabled = aDocument.IsUndoEnabled();
+    aDocument.EnableUndo( FALSE );
+    if ( bBefore )          // check all sheets up to nUpdateTab
+    {
+        SCTAB nTabCount = aDocument.GetTableCount();
+        if ( nUpdateTab >= nTabCount )
+            nUpdateTab = nTabCount-1;     // nUpdateTab is inclusive
+
+        ScMarkData aUpdateSheets;
+        SCTAB nTab;
+        for (nTab=0; nTab<=nUpdateTab; ++nTab)
+            if ( aDocument.IsPendingRowHeights( nTab ) )
+                aUpdateSheets.SelectTable( nTab, TRUE );
+
+        if (aUpdateSheets.GetSelectCount())
+            UpdateAllRowHeights(&aUpdateSheets);        // update with a single progress bar
+
+        for (nTab=0; nTab<=nUpdateTab; ++nTab)
+            if ( aUpdateSheets.GetTableSelect( nTab ) )
+            {
+                aDocument.UpdatePageBreaks( nTab );
+                aDocument.SetPendingRowHeights( nTab, FALSE );
+            }
+    }
+    else                    // only nUpdateTab
+    {
+        if ( aDocument.IsPendingRowHeights( nUpdateTab ) )
+        {
+            AdjustRowHeight( 0, MAXROW, nUpdateTab );
+            aDocument.UpdatePageBreaks( nUpdateTab );
+            aDocument.SetPendingRowHeights( nUpdateTab, FALSE );
+        }
+    }
+    aDocument.EnableUndo( bIsUndoEnabled );
 }
 
 #if OLD_PIVOT_IMPLEMENTATION
diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx
index 4477c66..0a339af 100644
--- a/sc/source/ui/drawfunc/futext3.cxx
+++ b/sc/source/ui/drawfunc/futext3.cxx
@@ -130,7 +130,7 @@ void FuText::StopEditMode(BOOL /*bTextDirection*/)
     if( pNote )
     {
         // hide the caption object if it is in hidden state
-        pNote->HideCaptionTemp();
+        pNote->ShowCaptionTemp( aNotePos, false );
 
         // update author and date
         pNote->AutoStamp();
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index beaa918..8daa034 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -33,7 +33,6 @@
 
 #include <tools/link.hxx>
 #include "global.hxx"
-#include "postit.hxx"
 #include "formula/grammar.hxx"
 
 class ScEditEngineDefaulter;
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index a1a7795..572a862 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -290,7 +290,8 @@ public:
     BOOL			IsEditable() const;
 
     BOOL			AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab );
-    void            UpdateAllRowHeights();
+    void            UpdateAllRowHeights( const ScMarkData* pTabMark = NULL );
+    void            UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore = false );
 
 #if OLD_PIVOT_IMPLEMENTATION
     void			PivotUpdate( ScPivot* pOldPivot, ScPivot* pNewPivot,
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index 474ffdf..597241d 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -1197,14 +1197,10 @@ void __EXPORT ScUndoReplace::Undo()
     }
     else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE)
     {
-        if (ScPostIt* pNote = pDoc->GetNote(aCursorPos))
-        {
-            pNote->SetText( aUndoStr );
-        }
-        else
-        {
-            DBG_ERROR("ScUndoReplace: Hier ist keine Notizzelle");
-        }
+        ScPostIt* pNote = pDoc->GetNote( aCursorPos );
+        DBG_ASSERT( pNote, "ScUndoReplace::Undo - cell does not contain a note" );
+        if (pNote)
+            pNote->SetText( aCursorPos, aUndoStr );
         if (pViewShell)
             pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
                                        SC_FOLLOW_JUMP, FALSE, FALSE );
diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx
index b50e703..338093e 100644
--- a/sc/source/ui/undo/undocell.cxx
+++ b/sc/source/ui/undo/undocell.cxx
@@ -829,6 +829,7 @@ ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rP
     mpDrawUndo( pDrawUndo )
 {
     DBG_ASSERT( maOldData.mpCaption || maNewData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
+    DBG_ASSERT( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected unitialized note" );
 }
 
 ScUndoReplaceNote::~ScUndoReplaceNote()
@@ -883,7 +884,7 @@ void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
     {
         ScDocument& rDoc = *pDocShell->GetDocument();
         DBG_ASSERT( !rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
-        ScPostIt* pNote = new ScPostIt( rDoc, rNoteData );
+        ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
         rDoc.TakeNote( maPos, pNote );
     }
 }
@@ -896,7 +897,9 @@ void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
         DBG_ASSERT( rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
         if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
         {
-            // forget caption (already handled in drawing undo)
+            /*  Forget pointer to caption object to suppress removing the
+                caption object from the drawing layer while deleting pNote
+                (removing the caption is done by a drawing undo action). */
             pNote->ForgetCaption();
             delete pNote;
         }
@@ -920,7 +923,7 @@ void ScUndoShowHideNote::Undo()
 {
     BeginUndo();
     if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
-        pNote->ShowCaption( !mbShown );
+        pNote->ShowCaption( maPos, !mbShown );
     EndUndo();
 }
 
@@ -928,7 +931,7 @@ void ScUndoShowHideNote::Redo()
 {
     BeginRedo();
     if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
-        pNote->ShowCaption( mbShown );
+        pNote->ShowCaption( maPos, mbShown );
     EndRedo();
 }
 
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 9648361..896fc13 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -271,10 +271,10 @@ SfxObjectShell* ScModelObj::GetEmbeddedObject() const
     return pDocShell;
 }
 
-void ScModelObj::UpdateAllRowHeights()
+void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark)
 {
     if (pDocShell)
-        pDocShell->UpdateAllRowHeights();
+        pDocShell->UpdateAllRowHeights(pTabMark);
 }
 
 ScDrawLayer* ScModelObj::MakeDrawLayer()
@@ -2791,7 +2791,26 @@ void SAL_CALL ScTableRowsObj::setPropertyValue(
     nRowArr[1] = nEndRow;
     String aNameString(aPropertyName);
 
-    if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
+    if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
+    {
+        sal_Int32 nNewHeight = 0;
+        if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) )
+        {
+            // used to set the stored row height for rows with optimal height when loading
+            pDoc->SetRowHeightRange( nStartRow, nEndRow, nTab, (USHORT)HMMToTwips(nNewHeight) );
+        }
+        else
+        {
+            BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+            if (bOpt)
+                aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, TRUE, TRUE );
+            else
+            {
+                //! manually set old heights again?
+            }
+        }
+    }
+    else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
     {
         sal_Int32 nNewHeight = 0;
         if ( aValue >>= nNewHeight )
@@ -2813,16 +2832,6 @@ void SAL_CALL ScTableRowsObj::setPropertyValue(
         else
             pDoc->GetRowFlagsArrayModifiable( nTab).AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) );
     }
-    else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
-    {
-        BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
-        if (bOpt)
-            aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, TRUE, TRUE );
-        else
-        {
-            //!	manually set old heights again?
-        }
-    }
     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
     {
         //!	single function to set/remove all breaks?
diff --git a/sc/source/ui/unoobj/editsrc.cxx b/sc/source/ui/unoobj/editsrc.cxx
index c507d4d..70093e6 100644
--- a/sc/source/ui/unoobj/editsrc.cxx
+++ b/sc/source/ui/unoobj/editsrc.cxx
@@ -51,6 +51,7 @@
 #include "unoguard.hxx"
 #include "drwlayer.hxx"
 #include "userdat.hxx"
+#include "postit.hxx"
 #include "AccessibleText.hxx"
 
 //------------------------------------------------------------------------
@@ -223,7 +224,7 @@ SvxEditSource* ScAnnotationEditSource::Clone() const
 SdrObject* ScAnnotationEditSource::GetCaptionObj()
 {
     ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos );
-    return pNote ? pNote->GetCaption() : 0;
+    return pNote ? pNote->GetOrCreateCaption( aCellPos ) : 0;
 }
 
 SvxTextForwarder* ScAnnotationEditSource::GetTextForwarder()
diff --git a/sc/source/ui/unoobj/notesuno.cxx b/sc/source/ui/unoobj/notesuno.cxx
index 92f1821..2e025f2 100644
--- a/sc/source/ui/unoobj/notesuno.cxx
+++ b/sc/source/ui/unoobj/notesuno.cxx
@@ -220,14 +220,14 @@ rtl::OUString SAL_CALL ScAnnotationObj::getAuthor() throw(uno::RuntimeException)
 {
     ScUnoGuard aGuard;
     const ScPostIt* pNote = ImplGetNote();
-    return pNote ? pNote->GetAuthor() : EMPTY_STRING;
+    return pNote ? pNote->GetAuthor() : rtl::OUString();
 }
 
 rtl::OUString SAL_CALL ScAnnotationObj::getDate() throw(uno::RuntimeException)
 {
     ScUnoGuard aGuard;
     const ScPostIt* pNote = ImplGetNote();
-    return pNote ? pNote->GetDate() : EMPTY_STRING;
+    return pNote ? pNote->GetDate() : rtl::OUString();
 }
 
 sal_Bool SAL_CALL ScAnnotationObj::getIsVisible() throw(uno::RuntimeException)
@@ -298,7 +298,7 @@ uno::Reference < drawing::XShape > ScAnnotationShapeObj::GetXShape()
 {
     if (!xShape.is())
         if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos ) )
-            if( SdrObject* pCaption = pNote->GetCaption() )
+            if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ) )
                 xShape.set( pCaption->getUnoShape(), uno::UNO_QUERY );
     return xShape;
 }
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 8785b84..77b3189 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -103,6 +103,7 @@
 #include "dpsave.hxx"
 #include "dpgroup.hxx"      // for ScDPNumGroupInfo
 #include "spellparam.hxx"
+#include "postit.hxx"
 
 #include "globstr.hrc"
 #include "scui_def.hxx" //CHINA001
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 2871e8b..b161e04 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -120,6 +120,7 @@
 #include "attrib.hxx"
 #include "validat.hxx"
 #include "tabprotection.hxx"
+#include "postit.hxx"
 
 // #114409#
 #include <vcl/salbtype.hxx>		// FRound
diff --git a/sc/source/ui/view/preview.cxx b/sc/source/ui/view/preview.cxx
index 4d50b10..d1e59ca 100644
--- a/sc/source/ui/view/preview.cxx
+++ b/sc/source/ui/view/preview.cxx
@@ -244,6 +244,10 @@ void ScPreview::CalcPages( SCTAB /*nToWhichTab*/ )
         nTabsTested = 0;
     }
 
+    // update all pending row heights with a single progress bar,
+    // instead of a separate progress for each sheet from ScPrintFunc
+    pDocShell->UpdatePendingRowHeights( nAnz-1, true );
+
     //	PrintOptions is passed to PrintFunc for SkipEmpty flag,
     //	but always all sheets are used (there is no selected sheet)
     ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index 12d5f54..f463948 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -185,6 +185,7 @@ long lcl_LineTotal(const SvxBorderLine* pLine)
 
 void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
 {
+    pDocShell->UpdatePendingRowHeights( nPrintTab );
     pDoc = pDocShell->GetDocument();
 
     SfxPrinter* pDocPrinter = pDoc->GetPrinter();	// auch fuer Preview den Drucker nehmen
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 1696bbb..125aa3b 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -1595,6 +1595,10 @@ void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection )
         ScDocument* pDoc = aViewData.GetDocument();
         pDoc->MakeTable( nTab );
 
+        // Update pending row heights before switching the sheet, so Reschedule from the progress bar
+        // doesn't paint the new sheet with old heights
+        aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
+
         SCTAB nTabCount = pDoc->GetTableCount();
         SCTAB nOldPos = nTab;
         while (!pDoc->IsVisible(nTab))				// naechste sichtbare suchen
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
index 4d3dfc1..a0a4138 100644
--- a/sc/source/ui/view/tabvwsh4.cxx
+++ b/sc/source/ui/view/tabvwsh4.cxx
@@ -1190,6 +1190,10 @@ PrintDialog* __EXPORT ScTabViewShell::CreatePrintDialog( Window *pParent )
     bool bAllTabs = SC_MOD()->GetPrintOptions().GetAllSheets();
     pDlg->CheckSheetRange( bAllTabs ? PRINTSHEETS_ALL : PRINTSHEETS_SELECTED_SHEETS );
 
+    // update all pending row heights with a single progress bar,
+    // instead of a separate progress for each sheet from ScPrintFunc
+    pDocShell->UpdatePendingRowHeights( MAXTAB, true );
+
     for ( SCTAB i=0; i<nTabCount; i++ )
     {
         ScPrintFunc aPrintFunc( pDocShell, pPrinter, i );
diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx
index 065a184..43e1c4f 100644
--- a/sc/source/ui/view/tabvwsh5.cxx
+++ b/sc/source/ui/view/tabvwsh5.cxx
@@ -47,6 +47,7 @@
 #include "tabvwsh.hxx"
 #include "sc.hrc"
 #include "global.hxx"
+#include "docsh.hxx"
 #include "document.hxx"
 #include "cell.hxx"
 #include "globstr.hrc"
@@ -160,6 +161,10 @@ void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint
                 if (PaintExtras())
                     nParts = PAINT_ALL;
 
+            // if the current sheet has pending row height updates (sheet links refreshed),
+            // execute them before invalidating the window
+            GetViewData()->GetDocShell()->UpdatePendingRowHeights( GetViewData()->GetTabNo() );
+
             if (nParts & PAINT_SIZE)
                 RepeatResize(); 					//! InvalidateBorder ???
             if (nParts & PAINT_GRID)
diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx
index 37a9ca9..43b3db1 100644
--- a/sc/source/ui/view/viewfun6.cxx
+++ b/sc/source/ui/view/viewfun6.cxx
@@ -175,9 +175,11 @@ void ScViewFunc::EditNote()
         // hide temporary note caption
         HideNoteMarker();
         // show caption object without changing internal visibility state
-        pNote->ShowCaptionTemp();
+        pNote->ShowCaptionTemp( aPos );
 
-        // drawing object has been created in ScDocument::GetOrCreateNote
+        /*  Drawing object has been created in ScDocument::GetOrCreateNote() or
+            in ScPostIt::ShowCaptionTemp(), so ScPostIt::GetCaption() should
+            return a caption object. */
         if( SdrCaptionObj* pCaption = pNote->GetCaption() )
         {
             // #i33764# enable the resize handles before starting edit mode
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index da65f46..7ba2130 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -2181,6 +2181,7 @@ void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR
             const SCCOLROW* pTabRanges = pRanges;
 
             pDoc->IncSizeRecalcLevel( nTab );		// nicht fuer jede Spalte einzeln
+            pDoc->InitializeNoteCaptions( nTab );
             for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
             {
                 SCCOLROW nStartNo = *(pTabRanges++);
commit 220c5f9de6dfe8e7a9b343be0480be3d4d3ca3cb
Author: Release Engineers <releng at openoffice.org>
Date:   Fri Jul 3 11:00:47 2009 +0000

    CWS-TOOLING: integrate CWS koheiformula03
    2009-04-24 17:45:29 +0200 kohei  r271229 : #i101330# Extend Excel's maximum column to Calc's maximum column upon import.
    2009-04-14 21:45:35 +0200 kohei  r270810 : #i101048# fixed - now the autofilter menu item is disabled when the current cursor
    overlaps a datapilot table.
    2009-04-14 21:41:22 +0200 kohei  r270809 : #i101047# fixed by removing all merge flags when a new row is inserted.  The old code
    did remove merge flags, but it didn't remove SC_MF_BUTTON flag.
    2009-04-14 18:00:16 +0200 kohei  r270806 : #i101091# fixed the issue.  When creating a data sequence via passing a range
    representation, the syntax must be the Calc A1 syntax regardless of current
    formula syntax.  However, for other operations that affects chart's UI, the
    syntax must be the current formula syntax.
    In the future we should have an API to directly pass formula reference tokens
    to chart objects.
    2009-04-14 17:46:36 +0200 kohei  r270804 : #i101090# fixed the issue of referenced ranges not being highlighted & formula tooltip
    not working when the separators are not ';'.
    2009-04-14 17:37:55 +0200 kohei  r270802 : #i101043# Fixed.  Defining a named range via the named range box should now
    work for non-default formula syntax.
    2009-04-14 17:35:08 +0200 kohei  r270800 : #i101041#  Fixed.  Always interpret DDE's address using the Calc A1 syntax regardless of
    current formula syntax.

diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 2140998..c41c15d 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -353,6 +353,7 @@ public:
 
     static BOOL EnQuote( String& rStr );
     
+    sal_Unicode GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const;
 
     // Check if it is a valid english function name
     bool IsEnglishSymbol( const String& rName ); 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4070837..451c590 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -593,7 +593,7 @@ public:
     SC_DLLPUBLIC BOOL			IsActiveScenario( SCTAB nTab ) const;
     SC_DLLPUBLIC void			SetActiveScenario( SCTAB nTab, BOOL bActive );		// nur fuer Undo etc.
     SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const;
-    formula::FormulaGrammar::Grammar GetGrammar() const;
+    SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const;
     void            SetGrammar( formula::FormulaGrammar::Grammar eGram );
     SC_DLLPUBLIC BYTE			GetLinkMode( SCTAB nTab ) const;
     BOOL			IsLinked( SCTAB nTab ) const;
diff --git a/sc/inc/reftokenhelper.hxx b/sc/inc/reftokenhelper.hxx
index b1159cc..d7b335f 100644
--- a/sc/inc/reftokenhelper.hxx
+++ b/sc/inc/reftokenhelper.hxx
@@ -56,7 +56,8 @@ public:
      * The source range may consist of multiple ranges separated by ';'s. 
      */
     static void compileRangeRepresentation(
-        ::std::vector<ScSharedTokenRef>& rRefTokens, const ::rtl::OUString& rRangeStr, ScDocument* pDoc);
+        ::std::vector<ScSharedTokenRef>& rRefTokens, const ::rtl::OUString& rRangeStr, ScDocument* pDoc,
+        ::formula::FormulaGrammar::Grammar eGrammar = ::formula::FormulaGrammar::GRAM_ENGLISH);
 
     static bool getRangeFromToken(ScRange& rRange, const ScSharedTokenRef& pToken, bool bExternal = false);
 
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 0836f77..bc0767a 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -2104,9 +2104,8 @@ void ScAttrArray::InsertRow( SCROW nStartRow, SCSIZE nSize )
         //	im eingefuegten Bereich ist nichts zusammengefasst
     }
 
-    //	Flags nicht duplizieren
-    //!	direkt am Pattern testen ??
-    RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
+    // Don't duplicate the merge flags in the inserted row.
+    RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_ALL );
 }
 
 
diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx
index c894c74..24cbf48 100644
--- a/sc/source/core/data/documen5.cxx
+++ b/sc/source/core/data/documen5.cxx
@@ -130,6 +130,7 @@ void lcl_SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartD
 
             if( xLabel.is())
             {
+                // the range string must be in Calc A1 format.
                 uno::Reference< chart2::data::XDataSequence > xNewSeq(
                     xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] ));
                 
@@ -145,6 +146,7 @@ void lcl_SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartD
 
             if( xValues.is())
             {
+                // the range string must be in Calc A1 format.
                 uno::Reference< chart2::data::XDataSequence > xNewSeq(
                     xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] ));
                 
@@ -391,7 +393,7 @@ void ScDocument::GetChartRanges( const String& rChartName, ::std::vector< ScRang
         for( sal_Int32 nN=0; nN<aRangeStrings.getLength(); nN++ )
         {
             ScRangeList aRanges;
-            aRanges.Parse( aRangeStrings[nN], pSheetNameDoc );
+            aRanges.Parse( aRangeStrings[nN], pSheetNameDoc, SCA_VALID, pSheetNameDoc->GetAddressConvention() );
             rRangesVector.push_back(aRanges);
         }
     }
@@ -407,8 +409,8 @@ void ScDocument::SetChartRanges( const String& rChartName, const ::std::vector<
         for( sal_Int32 nN=0; nN<nCount; nN++ )
         {
             ScRangeList aScRangeList( rRangesVector[nN] );
-            String sRangeStr;
-            aScRangeList.Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
+            String sRangeStr; // This range must be in Calc A1 format.
+            aScRangeList.Format( sRangeStr, SCR_ABS_3D, this );
             aRangeStrings[nN]=sRangeStr;
         }
         lcl_SetChartRanges( xChartDoc, aRangeStrings );
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index d07787f..2c52db6 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -5060,6 +5060,11 @@ BOOL ScCompiler::EnQuote( String& rStr )
     return TRUE;
 }
 
+sal_Unicode ScCompiler::GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const
+{
+    return pConv->getSpecialSymbol(eType);
+}
+
 void ScCompiler::fillAddInToken(::std::vector< ::com::sun::star::sheet::FormulaOpCodeMapEntry >& _rVec,bool _bIsEnglish) const
 {
     // All known AddIn functions.
diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx
index 0cbb085..524eaf1 100644
--- a/sc/source/core/tool/editutil.cxx
+++ b/sc/source/core/tool/editutil.cxx
@@ -64,12 +64,13 @@
 #include "patattr.hxx"
 #include "scmod.hxx"
 #include "inputopt.hxx"
+#include "compiler.hxx"
 
 // STATIC DATA -----------------------------------------------------------
 
 //	Delimiters zusaetzlich zu EditEngine-Default:
 
-const sal_Char __FAR_DATA ScEditUtil::pCalcDelimiters[] = "=();+-*/^&<>";
+const sal_Char __FAR_DATA ScEditUtil::pCalcDelimiters[] = "=()+-*/^&<>";
 
 
 //------------------------------------------------------------------------
@@ -79,6 +80,7 @@ String ScEditUtil::ModifyDelimiters( const String& rOld )
     String aRet = rOld;
     aRet.EraseAllChars( '_' );	// underscore is used in function argument names
     aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( pCalcDelimiters ) );
+    aRet.Append(ScCompiler::GetNativeSymbol(ocSep)); // argument separator is localized.
     return aRet;
 }
 
diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx
index 8ecb44a..0e07819 100644
--- a/sc/source/core/tool/reftokenhelper.cxx
+++ b/sc/source/core/tool/reftokenhelper.cxx
@@ -49,7 +49,7 @@ using ::std::auto_ptr;
 using ::rtl::OUString;
 
 void ScRefTokenHelper::compileRangeRepresentation(
-    vector<ScSharedTokenRef>& rRefTokens, const OUString& rRangeStr, ScDocument* pDoc)
+    vector<ScSharedTokenRef>& rRefTokens, const OUString& rRangeStr, ScDocument* pDoc, FormulaGrammar::Grammar eGrammar)
 {
     const sal_Unicode cSep = ';';
     const sal_Unicode cQuote = '\'';
@@ -63,7 +63,7 @@ void ScRefTokenHelper::compileRangeRepresentation(
             break;
         
         ScCompiler aCompiler(pDoc, ScAddress(0,0,0));
-        aCompiler.SetGrammar(FormulaGrammar::GRAM_ENGLISH);
+        aCompiler.SetGrammar(eGrammar);
         auto_ptr<ScTokenArray> pArray(aCompiler.CompileString(aToken));
 
         // There should only be one reference per range token.
diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx
index a5b6f9d..174ab20 100644
--- a/sc/source/filter/excel/colrowst.cxx
+++ b/sc/source/filter/excel/colrowst.cxx
@@ -95,6 +95,12 @@ void XclImpColRowSettings::SetWidthRange( SCCOL nScCol1, SCCOL nScCol2, sal_uInt
 {
     DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetColWidthRange - invalid column range" );
     nScCol2 = ::std::min( nScCol2, MAXCOL );
+    if (nScCol2 == 256)
+        // In BIFF8, the column range is 0-255, and the use of 256 probably
+        // means the range should extend to the max column if the loading app
+        // support columns beyond 255.
+        nScCol2 = MAXCOL;
+
     nScCol1 = ::std::min( nScCol1, nScCol2 );
     ::std::fill( maWidths.begin() + nScCol1, maWidths.begin() + nScCol2 + 1, nWidth );
     for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx
index ea52e00..cf80876 100644
--- a/sc/source/filter/excel/xechart.cxx
+++ b/sc/source/filter/excel/xechart.cxx
@@ -814,10 +814,11 @@ sal_uInt16 XclExpChSourceLink::ConvertDataSequence( Reference< XDataSequence > x
     if( !xDataSeq.is() )
         return nDefCount;
 
-    // compile the range representation string into token array
+    // Compile the range representation string into token array.  Note that the 
+    // source range text depends on the current grammar.
     OUString aRangeRepr = xDataSeq->getSourceRangeRepresentation();
     ScCompiler aComp( GetDocPtr(), ScAddress() );
-    aComp.SetGrammar( FormulaGrammar::GRAM_ENGLISH );
+    aComp.SetGrammar( GetDocPtr()->GetGrammar() );
     ScTokenArray* pArray = aComp.CompileString( aRangeRepr );
     if( !pArray )
         return nDefCount;
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 226c7d2..d7d1f3c 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -113,14 +113,22 @@ extern USHORT nEditAdjust;		//! Member an ViewData
 
 //==================================================================
 
+static sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc)
+{
+    ScCompiler aComp(pDoc, ScAddress());
+    aComp.SetGrammar(pDoc->GetGrammar());
+    return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR);
+}
+
 void ScInputHandler::InitRangeFinder( const String& rFormula )
 {
     DeleteRangeFinder();
+    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+    ScDocument* pDoc = pDocSh->GetDocument();
+    const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDoc);
 
     if ( !pActiveViewSh || !SC_MOD()->GetInputOptions().GetRangeFinder() )
         return;
-    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
-    ScDocument* pDoc = pDocSh->GetDocument();
 
 //	String aDelimiters = pEngine->GetWordDelimiters();
     String aDelimiters = ScEditUtil::ModifyDelimiters(
@@ -129,7 +137,7 @@ void ScInputHandler::InitRangeFinder( const String& rFormula )
     xub_StrLen nColon = aDelimiters.Search(':');
     if ( nColon != STRING_NOTFOUND )
         aDelimiters.Erase( nColon, 1 );				// Delimiter ohne Doppelpunkt
-    xub_StrLen nDot = aDelimiters.Search('.');
+    xub_StrLen nDot = aDelimiters.Search(cSheetSep);
     if ( nDot != STRING_NOTFOUND )
         aDelimiters.Erase( nDot, 1 );				// Delimiter ohne Punkt
 
@@ -702,6 +710,9 @@ void ScInputHandler::ShowTipCursor()
     HideTip();
     HideTipBelow();
     EditView* pActiveView = pTopView ? pTopView : pTableView;
+    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+    const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+    const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
 
     if ( bFormulaMode && pActiveView && pFormulaDataPara && pEngine->GetParagraphCount() == 1 )
     {
@@ -764,8 +775,8 @@ void ScInputHandler::ShowTipCursor()
                                 }
                                 if( bFlag )
                                 {
-                                    nCountSemicolon = aNew.GetTokenCount(';')-1;
-                                    nCountDot = aNew.GetTokenCount('.')-1;
+                                    nCountSemicolon = aNew.GetTokenCount(cSep)-1;
+                                    nCountDot = aNew.GetTokenCount(cSheetSep)-1;
 
                                     if( !nCountSemicolon )
                                     {
@@ -787,7 +798,7 @@ void ScInputHandler::ShowTipCursor()
                                             {
                                                 nStartPosition = i+1;
                                             }
-                                            else if( cNext == ';' )
+                                            else if( cNext == cSep )
                                             {
                                                 nCount ++;
                                                 nEndPosition = i;
@@ -808,7 +819,7 @@ void ScInputHandler::ShowTipCursor()
                                             {
                                                 nStartPosition = i+1;
                                             }
-                                            else if( cNext == ';' )
+                                            else if( cNext == cSep )
                                             {
                                                 nCount ++;
                                                 nEndPosition = i;
@@ -818,7 +829,7 @@ void ScInputHandler::ShowTipCursor()
                                                 }
                                                 nStartPosition = nEndPosition+1;
                                             }
-                                            else if( cNext == '.' )
+                                            else if( cNext == cSheetSep )
                                             {
                                                 continue;
                                             }
@@ -919,6 +930,9 @@ void ScInputHandler::ShowTipBelow( const String& rText )
 void ScInputHandler::UseFormulaData()
 {
     EditView* pActiveView = pTopView ? pTopView : pTableView;
+    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+    const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+    const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
 
     //	Formeln duerfen nur 1 Absatz haben
     if ( pActiveView && pFormulaData && pEngine->GetParagraphCount() == 1 )
@@ -1003,8 +1017,8 @@ void ScInputHandler::UseFormulaData()
                             }
                             if( bFlag )
                             {
-                                nCountSemicolon = aNew.GetTokenCount(';')-1;
-                                nCountDot = aNew.GetTokenCount('.')-1;
+                                nCountSemicolon = aNew.GetTokenCount(cSep)-1;
+                                nCountDot = aNew.GetTokenCount(cSheetSep)-1;
                                 
                                if( !nCountSemicolon )
                                {
@@ -1026,7 +1040,7 @@ void ScInputHandler::UseFormulaData()
                                         {
                                             nStartPosition = i+1;
                                         }
-                                        else if( cNext == ';' )
+                                        else if( cNext == cSep )
                                         {
                                             nCount ++;
                                             nEndPosition = i;
@@ -1047,7 +1061,7 @@ void ScInputHandler::UseFormulaData()
                                         {
                                             nStartPosition = i+1;
                                         }
-                                        else if( cNext == ';' )
+                                        else if( cNext == cSep )
                                         {
                                             nCount ++;
                                             nEndPosition = i;
@@ -1057,7 +1071,7 @@ void ScInputHandler::UseFormulaData()
                                             }
                                             nStartPosition = nEndPosition+1;
                                         }
-                                        else if( cNext == '.' )
+                                        else if( cNext == cSheetSep )
                                         {
                                             continue;
                                         }
@@ -2740,6 +2754,7 @@ BOOL ScInputHandler::IsModalMode( SfxObjectShell* pDocSh )
 
 void ScInputHandler::AddRefEntry()
 {
+    const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
     UpdateActiveView();
     if (!pTableView && !pTopView)
         return; 							// z.B. FillMode
@@ -2748,9 +2763,9 @@ void ScInputHandler::AddRefEntry()
 
     RemoveSelection();
     if (pTableView)
-        pTableView->InsertText( ';', FALSE );
+        pTableView->InsertText( cSep, FALSE );
     if (pTopView)
-        pTopView->InsertText( ';', FALSE );
+        pTopView->InsertText( cSep, FALSE );
 
     DataChanged();
 }
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index 0cbc44d..80625f0 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1699,7 +1699,7 @@ void ScPosWnd::DoEnter()
                         ScRangeName aNewRanges( *pNames );
                         ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
                         String aContent;
-                        aSelection.Format( aContent, SCR_ABS_3D, pDoc );
+                        aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
                         ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
                         if ( aNewRanges.Insert(pNew) )
                         {
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 2ba11df..a463660 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -2501,10 +2501,14 @@ long __EXPORT ScDocShell::DdeSetData( const String& rItem,
                 pData->GetSymbol( aPos );			// continue with the name's contents
         }
     }
+
+    // Address in DDE function must be always parsed as CONV_OOO so that it 
+    // would always work regardless of current address convension.  We do this
+    // because the address item in a DDE entry is *not* normalized when saved
+    // into ODF.
     ScRange aRange;
-    formula::FormulaGrammar::AddressConvention eConv = aDocument.GetAddressConvention();
-    BOOL bValid = ( ( aRange.Parse( aPos, &aDocument, eConv ) & SCA_VALID ) ||
-                    ( aRange.aStart.Parse( aPos, &aDocument, eConv ) & SCA_VALID ) );
+    bool bValid = ( (aRange.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO ) & SCA_VALID) ||
+                    (aRange.aStart.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO) & SCA_VALID) );
 
     ScServerObject* pObj = NULL;			// NULL = error
     if ( bValid )
diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx
index 587f664..dae97f1 100644
--- a/sc/source/ui/drawfunc/fuins2.cxx
+++ b/sc/source/ui/drawfunc/fuins2.cxx
@@ -167,8 +167,10 @@ void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScVie
             if ( aRangeListRef->Count() )
             {
                 pScDoc->LimitChartIfAll( aRangeListRef );               // limit whole columns/rows to used area
+
+                // update string from modified ranges.  The ranges must be in the current formula syntax.
                 String aTmpStr;                            
-                aRangeListRef->Format( aTmpStr, SCR_ABS_3D, pScDoc, pScDoc->GetAddressConvention() );   // update string from changed ranges
+                aRangeListRef->Format( aTmpStr, SCR_ABS_3D, pScDoc, pScDoc->GetAddressConvention() );
                 aRangeString = aTmpStr;
 
                 ScChartPositioner aChartPositioner( pScDoc, aRangeListRef );
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 2de3365..c8ad1f1 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -1051,7 +1051,7 @@ void lcl_SeperateOneRowRange(ScRange aR, const ScAddress& rPos, ScRangeListRef&
     }
 
     vector<ScSharedTokenRef> aTokens;
-    ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument);
+    ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
     return !aTokens.empty();
 }
 
@@ -1445,7 +1445,7 @@ ScChart2DataProvider::createDataSource(
     }
 
     vector<ScSharedTokenRef> aRefTokens;
-    ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument);
+    ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
     if (aRefTokens.empty())
         // Invalid range representation.  Bail out.
         throw lang::IllegalArgumentException();
@@ -2180,7 +2180,7 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum
         return false;
 
     vector<ScSharedTokenRef> aTokens;
-    ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument);
+    ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
     return !aTokens.empty();
 }
 
@@ -2197,6 +2197,12 @@ uno::Reference< chart2::data::XDataSequence > SAL_CALL
     if(!m_pDocument || (aRangeRepresentation.getLength() == 0))
         return xResult;
 
+    // Note: the range representation must be in Calc A1 format.  The import 
+    // filters use this method to pass data ranges, and they have no idea what
+    // the current formula syntax is.  In the future we should add another
+    // method to allow the client code to directly pass tokens representing
+    // ranges.
+
     vector<ScSharedTokenRef> aRefTokens;
     ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument);
     if (aRefTokens.empty())
@@ -2242,7 +2248,7 @@ rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const rtl::OUStr
         return aRet;
 
     vector<ScSharedTokenRef> aRefTokens;
-    ScRefTokenHelper::compileRangeRepresentation(aRefTokens, sRangeRepresentation, m_pDocument);
+    ScRefTokenHelper::compileRangeRepresentation(aRefTokens, sRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
     if (aRefTokens.empty())
         throw lang::IllegalArgumentException();
 
@@ -2483,7 +2489,7 @@ void ScChart2DataProvider::detectRangesFromDataSource(vector<ScSharedTokenRef>&
     {
         const OUString& rRangeRep = *itr;
         vector<ScSharedTokenRef> aTokens;
-        ScRefTokenHelper::compileRangeRepresentation(aTokens, rRangeRep, m_pDocument);
+        ScRefTokenHelper::compileRangeRepresentation(aTokens, rRangeRep, m_pDocument, m_pDocument->GetGrammar());
 
         CollectRefTokens func;
         func = for_each(aTokens.begin(), aTokens.end(), func);
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index c272e02..e3748ab 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -1242,6 +1242,10 @@ void __EXPORT ScCellShell::GetDBState( SfxItemSet& rSet )
                         {
                             rSet.DisableItem( nWhich );
                         }
+                        else if (pDoc->GetDPAtBlock(aDummy))
+                        {    
+                            rSet.DisableItem( nWhich );
+                        }
                         else
                             rSet.Put( SfxBoolItem( nWhich, bAutoFilter ) );
                     }


More information about the ooo-build-commit mailing list