diff options
Diffstat (limited to 'oox/source/xls/commentsbuffer.cxx')
-rw-r--r-- | oox/source/xls/commentsbuffer.cxx | 146 |
1 files changed, 124 insertions, 22 deletions
diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 78d5fe044fe8..f11aa89bca53 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -34,7 +34,9 @@ #include "oox/helper/attributelist.hxx" #include "oox/vml/vmlshape.hxx" #include "oox/xls/addressconverter.hxx" +#include "oox/xls/biffinputstream.hxx" #include "oox/xls/drawingfragment.hxx" +#include "oox/xls/drawingmanager.hxx" namespace oox { namespace xls { @@ -44,14 +46,25 @@ namespace xls { using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::sheet; using namespace ::com::sun::star::table; +using namespace ::com::sun::star::text; using namespace ::com::sun::star::uno; using ::rtl::OUString; // ============================================================================ +namespace { + +const sal_uInt16 BIFF_NOTE_VISIBLE = 0x0002; + +} // namespace + +// ============================================================================ + CommentModel::CommentModel() : - mnAuthorId( -1 ) + mnAuthorId( -1 ), + mnObjId( BIFF_OBJ_INVALID_ID ), + mbVisible( false ) { } @@ -77,6 +90,35 @@ void Comment::importComment( SequenceInputStream& rStrm ) getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, aBinRange, getSheetIndex() ); } +void Comment::importNote( BiffInputStream& rStrm ) +{ + BinAddress aBinAddr; + rStrm >> aBinAddr; + // cell range will be checked while inserting the comment into the document + getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, BinRange( aBinAddr ), getSheetIndex() ); + + // remaining record data is BIFF dependent + switch( getBiff() ) + { + case BIFF2: + case BIFF3: + importNoteBiff2( rStrm ); + break; + case BIFF4: + case BIFF5: + importNoteBiff2( rStrm ); + // in BIFF4 and BIFF5, comments can have an associated sound + if( (rStrm.getNextRecId() == BIFF_ID_NOTESOUND) && rStrm.startNextRecord() ) + importNoteSound( rStrm ); + break; + case BIFF8: + importNoteBiff8( rStrm ); + break; + case BIFF_UNKNOWN: + break; + } +} + RichStringRef Comment::createText() { maModel.mxText.reset( new RichString( *this ) ); @@ -92,35 +134,95 @@ void Comment::finalizeImport() CellAddress aNotePos( maModel.maRange.Sheet, maModel.maRange.StartColumn, maModel.maRange.StartRow ); if( getAddressConverter().checkCellAddress( aNotePos, true ) && maModel.mxText.get() ) try { - maModel.mxText->finalizeImport(); - OUString aNoteText = maModel.mxText->getPlainText(); - // non-empty string required by note implementation - if( aNoteText.getLength() > 0 ) + Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); + Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); + // non-empty string required by note implementation (real text will be added below) + xAnnos->insertNew( aNotePos, OUString( sal_Unicode( ' ' ) ) ); + + // receive created note from cell (insertNew does not return the note) + Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); + Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); + Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); + Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); + + // convert shape formatting and visibility + sal_Bool bVisible = sal_True; + switch( getFilterType() ) { - Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); - Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); - xAnnos->insertNew( aNotePos, aNoteText ); - // receive craeted note from cell (insertNew does not return the note) - Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); - Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); - Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); - Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); - // convert shape formatting - if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) - { - // position and formatting - pNoteShape->convertFormatting( xAnnoShape ); - // visibility - const ::oox::vml::ClientData* pClientData = pNoteShape->getClientData(); - xAnno->setIsVisible( pClientData && pClientData->mbVisible ); - } + case FILTER_OOXML: + if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) + { + // position and formatting + pNoteShape->convertFormatting( xAnnoShape ); + // visibility + const ::oox::vml::ClientData* pClientData = pNoteShape->getClientData(); + bVisible = pClientData && pClientData->mbVisible; + } + break; + case FILTER_BIFF: + bVisible = maModel.mbVisible; + break; + case FILTER_UNKNOWN: + break; } + xAnno->setIsVisible( bVisible ); + + // insert text and convert text formatting + maModel.mxText->finalizeImport(); + Reference< XText > xAnnoText( xAnnoShape, UNO_QUERY_THROW ); + maModel.mxText->convert( xAnnoText ); } catch( Exception& ) { } } +// private -------------------------------------------------------------------- + +void Comment::importNoteBiff2( BiffInputStream& rStrm ) +{ + sal_uInt16 nTotalLen; + rStrm >> nTotalLen; + sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.getRemaining() ) ); + RichStringRef xNoteText = createText(); + xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); + + nTotalLen = nTotalLen - nPartLen; // operator-=() gives compiler warning + while( (nTotalLen > 0) && (rStrm.getNextRecId() == BIFF_ID_NOTE) && rStrm.startNextRecord() ) + { + sal_uInt16 nMarker; + rStrm >> nMarker; + rStrm.skip( 2 ); + rStrm >> nPartLen; + OSL_ENSURE( nMarker == 0xFFFF, "Comment::importNoteBiff2 - missing continuation NOTE record" ); + if( nMarker == 0xFFFF ) + { + OSL_ENSURE( nPartLen <= nTotalLen, "Comment::importNoteBiff2 - string too long" ); + // call to RichString::importCharArray() appends new text portion + xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); + nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen ); + } + else + { + // seems to be a new note, rewind record, so worksheet fragment loop will find it + rStrm.rewindRecord(); + nTotalLen = 0; + } + } +} + +void Comment::importNoteBiff8( BiffInputStream& rStrm ) +{ + sal_uInt16 nFlags; + rStrm >> nFlags >> maModel.mnObjId; + maModel.maAuthor = rStrm.readUniString(); + maModel.mbVisible = getFlag( nFlags, BIFF_NOTE_VISIBLE ); +} + +void Comment::importNoteSound( BiffInputStream& /*rStrm*/ ) +{ +} + // ============================================================================ CommentsBuffer::CommentsBuffer( const WorksheetHelper& rHelper ) : |