tdf#124754 sw docx import: do not override text color with -1 (auto) color
[LibreOffice.git] / oox / source / shape / WpsContext.cxx
blob0692ea43777d2fcac1f30dfe49d32790151e696d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include "WpsContext.hxx"
11 #include <basegfx/matrix/b2dhommatrix.hxx>
12 #include <comphelper/sequenceashashmap.hxx>
13 #include <drawingml/customshapeproperties.hxx>
14 #include <drawingml/shapepropertiescontext.hxx>
15 #include <drawingml/shapestylecontext.hxx>
16 #include <com/sun/star/beans/XPropertySet.hpp>
17 #include <com/sun/star/beans/XPropertyState.hpp>
18 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
19 #include <com/sun/star/lang/XServiceInfo.hpp>
20 #include <com/sun/star/text/XText.hpp>
21 #include <com/sun/star/text/XTextCursor.hpp>
22 #include <svx/svdtrans.hxx>
23 #include <oox/helper/attributelist.hxx>
24 #include <oox/token/namespaces.hxx>
25 #include <oox/token/tokens.hxx>
26 #include <oox/drawingml/shape.hxx>
27 #include <sal/log.hxx>
29 #include <boost/optional.hpp>
31 using namespace com::sun::star;
33 namespace oox
35 namespace shape
37 WpsContext::WpsContext(ContextHandler2Helper const& rParent, uno::Reference<drawing::XShape> xShape,
38 const drawingml::ShapePtr& pMasterShapePtr,
39 const drawingml::ShapePtr& pShapePtr)
40 : ShapeContext(rParent, pMasterShapePtr, pShapePtr)
41 , mxShape(std::move(xShape))
43 mpShapePtr->setWps(true);
46 WpsContext::~WpsContext() = default;
48 oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken,
49 const oox::AttributeList& rAttribs)
51 switch (getBaseToken(nElementToken))
53 case XML_wsp:
54 break;
55 case XML_cNvCnPr:
56 break;
57 case XML_bodyPr:
58 if (mxShape.is())
60 uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
61 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
62 sal_Int32 nVert = rAttribs.getToken(XML_vert, XML_horz);
63 if (nVert != XML_horz)
65 // Get the existing rotation of the shape.
66 drawing::HomogenMatrix3 aMatrix;
67 xPropertySet->getPropertyValue("Transformation") >>= aMatrix;
68 basegfx::B2DHomMatrix aTransformation;
69 aTransformation.set(0, 0, aMatrix.Line1.Column1);
70 aTransformation.set(0, 1, aMatrix.Line1.Column2);
71 aTransformation.set(0, 2, aMatrix.Line1.Column3);
72 aTransformation.set(1, 0, aMatrix.Line1.Column1);
73 aTransformation.set(1, 1, aMatrix.Line2.Column2);
74 aTransformation.set(1, 2, aMatrix.Line3.Column3);
75 aTransformation.set(2, 0, aMatrix.Line1.Column1);
76 aTransformation.set(2, 1, aMatrix.Line2.Column2);
77 aTransformation.set(2, 2, aMatrix.Line3.Column3);
78 basegfx::B2DTuple aScale;
79 basegfx::B2DTuple aTranslate;
80 double fRotate = 0;
81 double fShearX = 0;
82 aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
84 // If the text is not rotated the way the shape wants it already, set the angle.
85 const sal_Int32 nRotation = nVert == XML_vert270 ? -270 : -90;
86 if (static_cast<long>(basegfx::rad2deg(fRotate))
87 != NormAngle36000(static_cast<long>(nRotation) * 100) / 100)
89 comphelper::SequenceAsHashMap aCustomShapeGeometry(
90 xPropertySet->getPropertyValue("CustomShapeGeometry"));
91 aCustomShapeGeometry["TextPreRotateAngle"] <<= nRotation;
92 xPropertySet->setPropertyValue(
93 "CustomShapeGeometry",
94 uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
98 if (xServiceInfo.is())
100 // Handle inset attributes for Writer textframes.
101 sal_Int32 aInsets[] = { XML_lIns, XML_tIns, XML_rIns, XML_bIns };
102 boost::optional<sal_Int32> oInsets[4];
103 for (std::size_t i = 0; i < SAL_N_ELEMENTS(aInsets); ++i)
105 OptValue<OUString> oValue = rAttribs.getString(aInsets[i]);
106 if (oValue.has())
107 oInsets[i] = oox::drawingml::GetCoordinate(oValue.get());
108 else
109 // Defaults from the spec: left/right: 91440 EMU, top/bottom: 45720 EMU
110 oInsets[i]
111 = (aInsets[i] == XML_lIns || aInsets[i] == XML_rIns) ? 254 : 127;
113 const OUString aShapeProps[]
114 = { OUString("TextLeftDistance"), OUString("TextUpperDistance"),
115 OUString("TextRightDistance"), OUString("TextLowerDistance") };
116 for (std::size_t i = 0; i < SAL_N_ELEMENTS(aShapeProps); ++i)
117 if (oInsets[i])
118 xPropertySet->setPropertyValue(aShapeProps[i],
119 uno::makeAny(*oInsets[i]));
122 // Handle text vertical adjustment inside a text frame
123 if (rAttribs.hasAttribute(XML_anchor))
125 drawing::TextVerticalAdjust eAdjust
126 = drawingml::GetTextVerticalAdjust(rAttribs.getToken(XML_anchor, XML_t));
127 xPropertySet->setPropertyValue("TextVerticalAdjust", uno::makeAny(eAdjust));
130 // Apply character color of the shape to the shape's textbox.
131 uno::Reference<text::XText> xText(mxShape, uno::UNO_QUERY);
132 uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
133 xTextCursor->gotoStart(false);
134 xTextCursor->gotoEnd(true);
135 const uno::Reference<beans::XPropertyState> xPropertyState(xTextCursor,
136 uno::UNO_QUERY);
137 const beans::PropertyState ePropertyState
138 = xPropertyState->getPropertyState("CharColor");
139 if (ePropertyState == beans::PropertyState_DEFAULT_VALUE)
141 uno::Reference<beans::XPropertySet> xTextBoxPropertySet(xTextCursor,
142 uno::UNO_QUERY);
143 uno::Any xCharColor = xPropertySet->getPropertyValue("CharColor");
144 Color aColor = COL_AUTO;
145 if (xCharColor >>= aColor)
147 if (aColor != COL_AUTO)
148 xTextBoxPropertySet->setPropertyValue("CharColor", xCharColor);
151 return this;
153 break;
154 case XML_noAutofit:
155 case XML_spAutoFit:
157 uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
158 // We can't use oox::drawingml::TextBodyPropertiesContext here, as this
159 // is a child context of bodyPr, so the shape is already sent: we need
160 // to alter the XShape directly.
161 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
162 if (xPropertySet.is())
164 if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
165 xPropertySet->setPropertyValue(
166 "FrameIsAutomaticHeight",
167 uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
168 else
169 xPropertySet->setPropertyValue(
170 "TextAutoGrowHeight",
171 uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
174 break;
175 case XML_prstTxWarp:
176 if (rAttribs.hasAttribute(XML_prst))
178 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
179 if (xPropertySet.is())
181 oox::OptValue<OUString> presetShapeName = rAttribs.getString(XML_prst);
182 const OUString& preset = presetShapeName.get();
183 comphelper::SequenceAsHashMap aCustomShapeGeometry(
184 xPropertySet->getPropertyValue("CustomShapeGeometry"));
185 aCustomShapeGeometry["PresetTextWarp"] <<= preset;
186 xPropertySet->setPropertyValue(
187 "CustomShapeGeometry",
188 uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
191 break;
192 case XML_txbx:
194 mpShapePtr->getCustomShapeProperties()->setShapeTypeOverride(true);
195 mpShapePtr->setTextBox(true);
196 //in case if the textbox is linked, save the attributes
197 //for further processing.
198 if (rAttribs.hasAttribute(XML_id))
200 OptValue<OUString> id = rAttribs.getString(XML_id);
201 if (id.has())
203 oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr;
204 linkedTxtBoxAttr.id = id.get().toInt32();
205 mpShapePtr->setTxbxHasLinkedTxtBox(true);
206 mpShapePtr->setLinkedTxbxAttributes(linkedTxtBoxAttr);
209 return this;
211 break;
212 case XML_linkedTxbx:
214 //in case if the textbox is linked, save the attributes
215 //for further processing.
216 mpShapePtr->getCustomShapeProperties()->setShapeTypeOverride(true);
217 mpShapePtr->setTextBox(true);
218 OptValue<OUString> id = rAttribs.getString(XML_id);
219 OptValue<OUString> seq = rAttribs.getString(XML_seq);
220 if (id.has() && seq.has())
222 oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr;
223 linkedTxtBoxAttr.id = id.get().toInt32();
224 linkedTxtBoxAttr.seq = seq.get().toInt32();
225 mpShapePtr->setTxbxHasLinkedTxtBox(true);
226 mpShapePtr->setLinkedTxbxAttributes(linkedTxtBoxAttr);
229 break;
230 default:
231 return ShapeContext::onCreateContext(nElementToken, rAttribs);
233 return nullptr;
238 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */