1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <oox/token/properties.hxx>
21 #include <oox/token/tokens.hxx>
23 #include <commentsbuffer.hxx>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/beans/XMultiPropertySet.hpp>
27 #include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
28 #include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
29 #include <com/sun/star/sheet/XSheetAnnotations.hpp>
30 #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
31 #include <com/sun/star/text/XText.hpp>
32 #include <osl/diagnose.h>
33 #include <oox/helper/attributelist.hxx>
34 #include <oox/vml/vmlshape.hxx>
35 #include <addressconverter.hxx>
36 #include <drawingfragment.hxx>
37 #include <svx/sdtaitm.hxx>
38 #include <svx/svdocapt.hxx>
39 #include <svx/unoshape.hxx>
40 #include <tools/diagnose_ex.h>
41 #include <document.hxx>
42 #include <drwlayer.hxx>
43 #include <cellsuno.hxx>
44 #include <docfunc.hxx>
52 using namespace ::com::sun::star::drawing
;
53 using namespace ::com::sun::star::sheet
;
54 using namespace ::com::sun::star::table
;
55 using namespace ::com::sun::star::text
;
56 using namespace ::com::sun::star::uno
;
58 static sal_Int32
lcl_ToHorizAlign( sal_Int32 nAlign
)
63 return SDRTEXTHORZADJUST_LEFT
;
65 return SDRTEXTHORZADJUST_RIGHT
;
67 return SDRTEXTHORZADJUST_CENTER
;
69 return SDRTEXTHORZADJUST_BLOCK
;
73 static sal_Int32
lcl_ToVertAlign( sal_Int32 nAlign
)
79 return SDRTEXTVERTADJUST_TOP
;
82 return SDRTEXTVERTADJUST_CENTER
;
85 return SDRTEXTVERTADJUST_BOTTOM
;
87 return SDRTEXTVERTADJUST_BLOCK
;
91 static sal_Int16
lcl_ToParaAlign(sal_Int32 nAlign
)
96 return sal_Int16(css::style::ParagraphAdjust_LEFT
);
98 return sal_Int16(css::style::ParagraphAdjust_RIGHT
);
100 return sal_Int16(css::style::ParagraphAdjust_CENTER
);
102 return sal_Int16(css::style::ParagraphAdjust_BLOCK
);
106 CommentModel::CommentModel()
118 Comment::Comment( const WorksheetHelper
& rHelper
) :
119 WorksheetHelper( rHelper
)
123 void Comment::importComment( const AttributeList
& rAttribs
)
125 maModel
.mnAuthorId
= rAttribs
.getInteger( XML_authorId
, -1 );
126 // cell range will be checked while inserting the comment into the document
127 AddressConverter::convertToCellRangeUnchecked( maModel
.maRange
, rAttribs
.getString( XML_ref
, OUString() ), getSheetIndex() );
130 void Comment::importCommentPr( const AttributeList
& rAttribs
)
132 maModel
.mbAutoFill
= rAttribs
.getBool( XML_autoFill
, true );
133 maModel
.mbAutoScale
= rAttribs
.getBool( XML_autoScale
, false );
134 maModel
.mbColHidden
= rAttribs
.getBool( XML_colHidden
, false );
135 maModel
.mbLocked
= rAttribs
.getBool( XML_locked
, false );
136 maModel
.mbRowHidden
= rAttribs
.getBool( XML_rowHidden
, false );
137 maModel
.mnTHA
= rAttribs
.getToken( XML_textHAlign
, XML_left
);
138 maModel
.mnTVA
= rAttribs
.getToken( XML_textVAlign
, XML_top
);
141 void Comment::importComment( SequenceInputStream
& rStrm
)
144 maModel
.mnAuthorId
= rStrm
.readInt32();
146 // cell range will be checked while inserting the comment into the document
147 AddressConverter::convertToCellRangeUnchecked( maModel
.maRange
, aBinRange
, getSheetIndex() );
150 RichStringRef
const & Comment::createText()
152 maModel
.mxText
.reset( new RichString( *this ) );
153 return maModel
.mxText
;
156 void Comment::finalizeImport()
158 // BIFF12 stores cell range instead of cell address, use first cell of this range
159 OSL_ENSURE( maModel
.maRange
.aStart
== maModel
.maRange
.aEnd
,
160 "Comment::finalizeImport - comment anchor should be a single cell" );
161 if( !getAddressConverter().checkCellAddress( maModel
.maRange
.aStart
, true ) || !maModel
.mxText
.get() )
166 ScTableSheetObj
* pAnnosSupp
= static_cast<ScTableSheetObj
*>(getSheet().get());
167 rtl::Reference
<ScAnnotationsObj
> xAnnos
= static_cast<ScAnnotationsObj
*>(pAnnosSupp
->getAnnotations().get());
168 ScDocShell
* pDocShell
= xAnnos
->GetDocShell();
169 // non-empty string required by note implementation (real text will be added below)
170 ScPostIt
* pPostIt
= pDocShell
->GetDocFunc().ImportNote( maModel
.maRange
.aStart
, OUString( ' ' ), nullptr, nullptr );
171 SdrCaptionObj
* pCaption
= pPostIt
->GetOrCreateCaption( maModel
.maRange
.aStart
);
173 Reference
< XShape
> xAnnoShape( pCaption
->getUnoShape(), UNO_QUERY_THROW
); // SvxShapeText
174 // setting a property triggers expensive process, so set them all at once
175 Reference
< css::beans::XMultiPropertySet
> xAnnoShapeMultiPropSet(xAnnoShape
, UNO_QUERY_THROW
);
177 // Add shape formatting properties (autoFill, colHidden and rowHidden are dropped)
178 xAnnoShapeMultiPropSet
->setPropertyValues(
179 Sequence
<OUString
> { "TextFitToSize", "MoveProtect", "TextHorizontalAdjust", "TextVerticalAdjust" },
180 Sequence
<Any
> { Any(maModel
.mbAutoScale
), Any(maModel
.mbLocked
),
181 Any(lcl_ToHorizAlign( maModel
.mnTHA
)), Any(lcl_ToVertAlign( maModel
.mnTVA
)) });
182 if( maModel
.maAnchor
.Width
> 0 && maModel
.maAnchor
.Height
> 0 )
184 xAnnoShape
->setPosition( css::awt::Point( maModel
.maAnchor
.X
, maModel
.maAnchor
.Y
) );
185 xAnnoShape
->setSize( css::awt::Size( maModel
.maAnchor
.Width
, maModel
.maAnchor
.Height
) );
188 // convert shape formatting and visibility
189 bool bVisible
= true;
190 if( const ::oox::vml::ShapeBase
* pVmlNoteShape
= getVmlDrawing().getNoteShape( maModel
.maRange
.aStart
) )
192 // position and formatting
193 pVmlNoteShape
->convertFormatting( xAnnoShape
);
195 bVisible
= pVmlNoteShape
->getTypeModel().mbVisible
;
197 // Setting comment text alignment
198 const ::oox::vml::ClientData
* xClientData
= pVmlNoteShape
->getClientData();
199 xAnnoShapeMultiPropSet
->setPropertyValues(
200 Sequence
<OUString
> { "TextVerticalAdjust", "ParaAdjust" },
201 Sequence
<Any
> { Any(lcl_ToVertAlign( xClientData
->mnTextVAlign
)), Any(lcl_ToParaAlign( xClientData
->mnTextHAlign
)) });
204 pDocShell
->GetDocFunc().ShowNote( maModel
.maRange
.aStart
, bVisible
);
206 // insert text and convert text formatting
207 maModel
.mxText
->finalizeImport();
208 Reference
< XText
> xAnnoText( xAnnoShape
, UNO_QUERY_THROW
);
209 maModel
.mxText
->convert( xAnnoText
);
213 DBG_UNHANDLED_EXCEPTION("sc");
217 // private --------------------------------------------------------------------
219 CommentsBuffer::CommentsBuffer( const WorksheetHelper
& rHelper
) :
220 WorksheetHelper( rHelper
)
224 void CommentsBuffer::appendAuthor( const OUString
& rAuthor
)
226 maAuthors
.push_back( rAuthor
);
229 CommentRef
CommentsBuffer::createComment()
231 CommentRef
xComment( new Comment( *this ) );
232 maComments
.push_back( xComment
);
236 void CommentsBuffer::finalizeImport()
238 // keep the model locked to avoid repeated reformatting in the model
239 auto pModel
= getScDocument().GetDrawLayer();
240 bool bWasLocked
= pModel
->isLocked();
241 pModel
->setLock(true);
242 maComments
.forEachMem( &Comment::finalizeImport
);
243 pModel
->setLock(bWasLocked
);
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */