diff options
author | Release Engineers <releng@openoffice.org> | 2009-07-03 12:42:53 +0000 |
---|---|---|
committer | Release Engineers <releng@openoffice.org> | 2009-07-03 12:42:53 +0000 |
commit | 2b954fb11782e3e0f5a02ca496fdd4713a6f997d (patch) | |
tree | 9708323cd7eb4d3393b9f577122e3e45f5548c79 | |
parent | 220c5f9de6dfe8e7a9b343be0480be3d4d3ca3cb (diff) |
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@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
56 files changed, 1515 insertions, 844 deletions
diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index 8d1485054..9437abc42 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 af952b44b..2ea9f14cb 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 4e633568a..371b3bbfd 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 1bdbc1a30..6c5ddcfd5 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 451c590ee..d7bbc471a 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 f8511035c..bc51c7425 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 a08fd6035..faa6b8b9f 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 979fea652..ee90a7137 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 083a6d560..80a1fcebe 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 94e14eca2..2a336237c 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 433c81025..73d28c403 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 476da6dd1..521f6e736 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 d5d443868..487b029b1 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 60a75f2ab..cd958dac2 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 e7a85721a..c69652551 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 71d7ba627..29618da66 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 068ec3ade..c53694b76 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 680281cdb..d51b7fde5 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 d33d90bbf..1bc4d1fba 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 b2eb704ef..994596d30 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 ddd0ba8f4..7680bdaf4 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 93823a387..1138a1b5c 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 ad164cd69..19d831ee1 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 f453d655b..36bbfe1d2 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 1ba1518aa..47e5a9419 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 b186f9a6b..c5132d07e 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 831e837cc..df8661200 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 85967f20c..5ea1865c2 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 c834f55d1..c509b7212 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 1c4948eaa..91a936895 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 8ce894a0f..644ddb0b8 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 ef4fa69d8..975d9b20d 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 d37e62250..8e95e2683 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 ad17e2abd..efb2b1499 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 e6dd10539..d3748c351 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 6464ee698..81d830a1b 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 c52e8d66b..884b95f5a 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 a46366084..a3e866b23 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 e288b7426..dd8e60988 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 4477c669f..0a339af7f 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 beaa9186d..8daa03486 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 a1a779515..572a862ec 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 474ffdfae..597241d24 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 b50e703b3..338093eb4 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 9648361a4..896fc134b 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 c507d4d12..70093e659 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 92f182117..2e025f21c 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 8785b84e4..77b318955 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 2871e8b57..b161e0461 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 4d50b10aa..d1e59cafb 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 12d5f5418..f463948c8 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 1696bbbdd..125aa3b5f 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 4d3dfc107..a0a4138cd 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 065a1848c..43e1c4f29 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 37a9ca92a..43b3db1b1 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 da65f467e..7ba21306b 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++); |