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>
51 using namespace ::com::sun::star::drawing
;
52 using namespace ::com::sun::star::sheet
;
53 using namespace ::com::sun::star::table
;
54 using namespace ::com::sun::star::text
;
55 using namespace ::com::sun::star::uno
;
57 static sal_Int32
lcl_ToHorizAlign( sal_Int32 nAlign
)
62 return SDRTEXTHORZADJUST_LEFT
;
64 return SDRTEXTHORZADJUST_RIGHT
;
66 return SDRTEXTHORZADJUST_CENTER
;
68 return SDRTEXTHORZADJUST_BLOCK
;
72 static sal_Int32
lcl_ToVertAlign( sal_Int32 nAlign
)
78 return SDRTEXTVERTADJUST_TOP
;
81 return SDRTEXTVERTADJUST_CENTER
;
84 return SDRTEXTVERTADJUST_BOTTOM
;
86 return SDRTEXTVERTADJUST_BLOCK
;
90 static sal_Int16
lcl_ToParaAlign(sal_Int32 nAlign
)
95 return sal_Int16(css::style::ParagraphAdjust_LEFT
);
97 return sal_Int16(css::style::ParagraphAdjust_RIGHT
);
99 return sal_Int16(css::style::ParagraphAdjust_CENTER
);
101 return sal_Int16(css::style::ParagraphAdjust_BLOCK
);
105 CommentModel::CommentModel()
117 Comment::Comment( const WorksheetHelper
& rHelper
) :
118 WorksheetHelper( rHelper
)
122 void Comment::importComment( const AttributeList
& rAttribs
)
124 maModel
.mnAuthorId
= rAttribs
.getInteger( XML_authorId
, -1 );
125 // cell range will be checked while inserting the comment into the document
126 AddressConverter::convertToCellRangeUnchecked( maModel
.maRange
, rAttribs
.getString( XML_ref
, OUString() ), getSheetIndex() );
129 void Comment::importCommentPr( const AttributeList
& rAttribs
)
131 maModel
.mbAutoFill
= rAttribs
.getBool( XML_autoFill
, true );
132 maModel
.mbAutoScale
= rAttribs
.getBool( XML_autoScale
, false );
133 maModel
.mbColHidden
= rAttribs
.getBool( XML_colHidden
, false );
134 maModel
.mbLocked
= rAttribs
.getBool( XML_locked
, false );
135 maModel
.mbRowHidden
= rAttribs
.getBool( XML_rowHidden
, false );
136 maModel
.mnTHA
= rAttribs
.getToken( XML_textHAlign
, XML_left
);
137 maModel
.mnTVA
= rAttribs
.getToken( XML_textVAlign
, XML_top
);
140 void Comment::importComment( SequenceInputStream
& rStrm
)
143 maModel
.mnAuthorId
= rStrm
.readInt32();
145 // cell range will be checked while inserting the comment into the document
146 AddressConverter::convertToCellRangeUnchecked( maModel
.maRange
, aBinRange
, getSheetIndex() );
149 RichStringRef
const & Comment::createText()
151 maModel
.mxText
= std::make_shared
<RichString
>( *this );
152 return maModel
.mxText
;
155 void Comment::finalizeImport()
157 // BIFF12 stores cell range instead of cell address, use first cell of this range
158 OSL_ENSURE( maModel
.maRange
.aStart
== maModel
.maRange
.aEnd
,
159 "Comment::finalizeImport - comment anchor should be a single cell" );
160 if( !getAddressConverter().checkCellAddress( maModel
.maRange
.aStart
, true ) || !maModel
.mxText
)
165 ScTableSheetObj
* pAnnosSupp
= static_cast<ScTableSheetObj
*>(getSheet().get());
166 rtl::Reference
<ScAnnotationsObj
> xAnnos
= static_cast<ScAnnotationsObj
*>(pAnnosSupp
->getAnnotations().get());
167 ScDocShell
* pDocShell
= xAnnos
->GetDocShell();
168 // non-empty string required by note implementation (real text will be added below)
169 ScPostIt
* pPostIt
= pDocShell
->GetDocFunc().ImportNote( maModel
.maRange
.aStart
, OUString( ' ' ) );
170 SdrCaptionObj
* pCaption
= pPostIt
->GetOrCreateCaption( maModel
.maRange
.aStart
);
172 Reference
< XShape
> xAnnoShape( pCaption
->getUnoShape(), UNO_QUERY_THROW
); // SvxShapeText
173 // setting a property triggers expensive process, so set them all at once
174 Reference
< css::beans::XMultiPropertySet
> xAnnoShapeMultiPropSet(xAnnoShape
, UNO_QUERY_THROW
);
176 // Add shape formatting properties (autoFill, colHidden and rowHidden are dropped)
177 xAnnoShapeMultiPropSet
->setPropertyValues(
178 Sequence
<OUString
> { "TextFitToSize", "MoveProtect", "TextHorizontalAdjust", "TextVerticalAdjust" },
179 Sequence
<Any
> { Any(maModel
.mbAutoScale
), Any(maModel
.mbLocked
),
180 Any(lcl_ToHorizAlign( maModel
.mnTHA
)), Any(lcl_ToVertAlign( maModel
.mnTVA
)) });
181 if( maModel
.maAnchor
.Width
> 0 && maModel
.maAnchor
.Height
> 0 )
183 xAnnoShape
->setPosition( css::awt::Point( maModel
.maAnchor
.X
, maModel
.maAnchor
.Y
) );
184 xAnnoShape
->setSize( css::awt::Size( maModel
.maAnchor
.Width
, maModel
.maAnchor
.Height
) );
187 // convert shape formatting and visibility
188 bool bVisible
= true;
189 if( const ::oox::vml::ShapeBase
* pVmlNoteShape
= getVmlDrawing().getNoteShape( maModel
.maRange
.aStart
) )
191 // position and formatting
192 pVmlNoteShape
->convertFormatting( xAnnoShape
);
194 bVisible
= pVmlNoteShape
->getTypeModel().mbVisible
;
196 // Setting comment text alignment
197 const ::oox::vml::ClientData
* xClientData
= pVmlNoteShape
->getClientData();
198 xAnnoShapeMultiPropSet
->setPropertyValues(
199 Sequence
<OUString
> { "TextVerticalAdjust", "ParaAdjust" },
200 Sequence
<Any
> { Any(lcl_ToVertAlign( xClientData
->mnTextVAlign
)), Any(lcl_ToParaAlign( xClientData
->mnTextHAlign
)) });
203 pDocShell
->GetDocFunc().ShowNote( maModel
.maRange
.aStart
, bVisible
);
205 // insert text and convert text formatting
206 maModel
.mxText
->finalizeImport();
207 Reference
< XText
> xAnnoText( xAnnoShape
, UNO_QUERY_THROW
);
208 maModel
.mxText
->convert( xAnnoText
);
212 DBG_UNHANDLED_EXCEPTION("sc");
216 // private --------------------------------------------------------------------
218 CommentsBuffer::CommentsBuffer( const WorksheetHelper
& rHelper
) :
219 WorksheetHelper( rHelper
)
223 void CommentsBuffer::appendAuthor( const OUString
& rAuthor
)
225 maAuthors
.push_back( rAuthor
);
228 CommentRef
CommentsBuffer::createComment()
230 CommentRef xComment
= std::make_shared
<Comment
>( *this );
231 maComments
.push_back( xComment
);
235 void CommentsBuffer::finalizeImport()
237 // keep the model locked to avoid repeated reformatting in the model
238 auto pModel
= getScDocument().GetDrawLayer();
239 bool bWasLocked
= pModel
->isLocked();
240 pModel
->setLock(true);
241 maComments
.forEachMem( &Comment::finalizeImport
);
242 pModel
->setLock(bWasLocked
);
245 } // namespace oox::xls
247 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */