Index: inc/postit.hxx =================================================================== RCS file: /cvs/sc/sc/inc/postit.hxx,v retrieving revision 1.5 diff -u -r1.5 postit.hxx --- inc/postit.hxx 13 Jan 2005 17:21:26 -0000 1.5 +++ inc/postit.hxx 18 Feb 2005 16:43:14 -0000 @@ -103,6 +103,31 @@ class EditTextObject; class ScDocument; +/** Represents the position (anchor) of a Note object in a Calc document. */ +class NoteAnchor +{ +private: + sal_uInt16 mnLCol; /// Left column index. + sal_uInt16 mnLX; /// X offset in left column (1/1024 of column width). + sal_uInt16 mnTRow; /// Top row index. + sal_uInt16 mnTY; /// Y offset in top row (1/256 of row height). + sal_uInt16 mnRCol; /// Right column index. + sal_uInt16 mnRX; /// X offset in right column (1/1024 of column width). + sal_uInt16 mnBRow; /// Bottom row index. + sal_uInt16 mnBY; /// Y offset in bottom row (1/256 of row height). + SCTAB mnScTab; /// Calc sheet index. + +public: + explicit NoteAnchor(); + + /** Calculates a rectangle from the contained coordinates. */ + Rectangle GetRect( ScDocument& rDoc ) const; + /** Initializes the anchor coordinates from a rectangle. */ + void SetRect( ScDocument& rDoc, const Rectangle& rRect, SCTAB nTab ); + /** Updates the anchor source coordinates to the destination coordinates. */ + void UpdateRect( const ScAddress& rSrc, const ScAddress& rDest); +}; + //================================================================== // Notes //================================================================== Index: source/core/data/postit.cxx =================================================================== RCS file: /cvs/sc/sc/source/core/data/postit.cxx,v retrieving revision 1.6 diff -u -r1.6 postit.cxx --- source/core/data/postit.cxx 17 Jan 2005 10:31:22 -0000 1.6 +++ source/core/data/postit.cxx 18 Feb 2005 16:43:31 -0000 @@ -143,6 +143,158 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::frame::XModel; +// Note anchor ======================================================= + +namespace { + +/** Calculates a drawing layer X position (in twips) from a Note Anchor object column position. */ +long lclGetXFromCol( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nCol, sal_uInt16 nOffset, double fScale ) +{ + SCCOL nScCol = static_cast< SCCOL >( nCol ); + return static_cast< long >( fScale * (rDoc.GetColOffset( nScCol, nScTab ) + + ::std::min( nOffset / 1024.0, 1.0 ) * rDoc.GetColWidth( nScCol, nScTab )) + 0.5 ); +} + +/** Calculates a drawing layer Y position (in twips) from a Note Anchor object row position. */ +long lclGetYFromRow( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nRow, sal_uInt16 nOffset, double fScale ) +{ + SCROW nScRow = static_cast< SCROW >( nRow ); + return static_cast< long >( fScale * (rDoc.GetRowOffset( nScRow, nScTab ) + + ::std::min( nOffset / 256.0, 1.0 ) * rDoc.GetRowHeight( nScRow, nScTab )) + 0.5 ); +} + +/** Calculates a Note Anchor object column position from a drawing layer X position (in twips). */ +void lclGetColFromX( + ScDocument& rDoc, SCTAB nScTab, sal_uInt16& rnCol, + sal_uInt16& rnOffset, sal_uInt16 nStartCol, + long& rnStartW, long nX, double fScale ) +{ + // rnStartW in conjunction with nStartCol is used as buffer for previously calculated width + long nTwipsX = static_cast< long >( nX / fScale + 0.5 ); + long nColW = 0; + for( rnCol = nStartCol; rnCol <= MAXCOL; ++rnCol ) + { + nColW = rDoc.GetColWidth( static_cast(rnCol), nScTab ); + if( rnStartW + nColW > nTwipsX ) + break; + rnStartW += nColW; + } + rnOffset = nColW ? static_cast< sal_uInt16 >( (nTwipsX - rnStartW) * 1024.0 / nColW + 0.5 ) : 0; +} + +/** Calculates a Note Anchor object row position from a drawing layer Y position (in twips). */ +void lclGetRowFromY( + ScDocument& rDoc, SCTAB nScTab, + sal_uInt16& rnRow, sal_uInt16& rnOffset, sal_uInt16 nStartRow, + long& rnStartH, long nY, double fScale ) +{ + // rnStartH in conjunction with nStartRow is used as buffer for previously calculated height + long nTwipsY = static_cast< long >( nY / fScale + 0.5 ); + long nRowH = 0; + ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( + rDoc.GetRowFlagsArray( nScTab), static_cast(nStartRow), + MAXROW, CR_HIDDEN, 0, rDoc.GetRowHeightArray( nScTab)); + for ( ; aIter; ++aIter ) + { + nRowH = *aIter; + if( rnStartH + nRowH > nTwipsY ) + { + rnRow = static_cast< sal_uInt16 >( aIter.GetPos() ); + break; + } + rnStartH += nRowH; + } + if (!aIter) + rnRow = static_cast< sal_uInt16 >( aIter.GetIterEnd() ); // down to the bottom.. + rnOffset = static_cast< sal_uInt16 >( nRowH ? ((nTwipsY - rnStartH) * 256.0 / nRowH + 0.5) : 0 ); +} + +/** Mirrors a rectangle (from LTR to RTL layout or vice versa). */ +void lclMirrorRectangle( Rectangle& rRect ) +{ + long nLeft = rRect.Left(); + rRect.Left() = -rRect.Right(); + rRect.Right() = -nLeft; +} + +} // namespace + +//======================================================================== + +NoteAnchor::NoteAnchor() : + mnLCol( 0 ), mnLX( 0 ), + mnTRow( 0 ), mnTY( 0 ), + mnRCol( 0 ), mnRX( 0 ), + mnBRow( 0 ), mnBY( 0 ), + mnScTab( 0 ) +{ +} + +Rectangle NoteAnchor::GetRect( ScDocument& rDoc ) const +{ + double fScale = HMM_PER_TWIPS; + Rectangle aRect( + lclGetXFromCol( rDoc, mnScTab, mnLCol, mnLX, fScale ), + lclGetYFromRow( rDoc, mnScTab, mnTRow, mnTY, fScale ), + lclGetXFromCol( rDoc, mnScTab, mnRCol, mnRX + 1, fScale ), + lclGetYFromRow( rDoc, mnScTab, mnBRow, mnBY, fScale ) ); + + if( rDoc.IsLayoutRTL( mnScTab ) ) + lclMirrorRectangle( aRect ); + return aRect; +} + +void NoteAnchor::SetRect( ScDocument& rDoc, const Rectangle& rRect, SCTAB nTab ) +{ + mnScTab = nTab; + Rectangle aRect( rRect ); + if( rDoc.IsLayoutRTL( mnScTab ) ) + lclMirrorRectangle( aRect ); + + double fScale = HMM_PER_TWIPS; + long nDummy = 0; + lclGetColFromX( rDoc, mnScTab, mnLCol, mnLX, 0, nDummy, aRect.Left(), fScale ); + lclGetColFromX( rDoc, mnScTab, mnRCol, mnRX, mnLCol, nDummy, aRect.Right(), fScale ); + nDummy = 0; + lclGetRowFromY( rDoc, mnScTab, mnTRow, mnTY, 0, nDummy, aRect.Top(), fScale ); + lclGetRowFromY( rDoc, mnScTab, mnBRow, mnBY, mnTRow, nDummy, aRect.Bottom(), fScale ); +} + +void NoteAnchor::UpdateRect( const ScAddress& rSrc, const ScAddress& rDest) +{ + sal_Int16 nDiffCol = static_cast(rDest.Col() - rSrc.Col()); + sal_Int32 nDiffRow = static_cast(rDest.Row() - rSrc.Row()); + // do a sanity check + if(mnLCol + nDiffCol < 0 ) + mnLCol = 0; + else if(mnLCol + nDiffCol > MAXCOL ) + mnLCol = MAXCOL - 1; + else + mnLCol += nDiffCol; + + if(mnRCol + nDiffCol < 0 ) + mnRCol = 0; + else if(mnRCol + nDiffCol > MAXCOL ) + mnRCol = MAXCOL - 1; + else + mnRCol += nDiffCol; + + if(mnTRow + nDiffRow < 0) + mnTRow = 0; + else if(mnTRow + nDiffRow > MAXROW) + mnTRow = MAXROW - 1; + else + mnTRow += static_cast(nDiffRow); + + if(mnBRow + nDiffRow < 0) + mnBRow = 0; + else if(mnBRow + nDiffRow > MAXROW) + mnBRow = MAXROW - 1; + else + mnBRow += static_cast(nDiffRow); + + mnScTab = rDest.Tab() ; +} //======================================================================== // class ScPostIt //======================================================================== Index: source/core/data/column3.cxx =================================================================== RCS file: /cvs/sc/sc/source/core/data/column3.cxx,v retrieving revision 1.16 diff -u -r1.16 column3.cxx --- source/core/data/column3.cxx 11 Jan 2005 12:38:02 -0000 1.16 +++ source/core/data/column3.cxx 18 Feb 2005 16:43:48 -0000 @@ -794,9 +794,18 @@ ScPostIt aCellNote(pDocument); if(pNew->GetNote(aCellNote)) { - Rectangle aRect = aCellNote.DefaultRectangle(ScAddress(nCol,nDestRow,nTab)); + Rectangle aOldRect(aCellNote.GetRectangle()); + NoteAnchor aAnchor; + aAnchor.SetRect(*pDocument,aOldRect,nTab); + aAnchor.UpdateRect(ScAddress(rColumn.nCol,nDestRow-nDy,nTab), ScAddress(nCol,nDestRow, nTab)); + Rectangle aRect(aAnchor.GetRect(*pDocument)); aCellNote.SetRectangle(aRect); pNew->SetNote(aCellNote); + if(aCellNote.IsShown()) + { + pDocument->SetNote(nCol, nDestRow, nTab, aCellNote); + ScDetectiveFunc( pDocument, nTab ).ShowComment( nCol, nDestRow, FALSE ); + } } } }