Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include "WpsContext.hxx"
11 : #include <drawingml/customshapeproperties.hxx>
12 : #include <drawingml/shapepropertiescontext.hxx>
13 : #include <drawingml/shapestylecontext.hxx>
14 : #include <com/sun/star/beans/XPropertySet.hpp>
15 : #include <com/sun/star/beans/XPropertyState.hpp>
16 :
17 : #include <boost/optional.hpp>
18 :
19 : using namespace com::sun::star;
20 :
21 : namespace oox
22 : {
23 : namespace shape
24 : {
25 :
26 1242 : WpsContext::WpsContext(ContextHandler2Helper& rParent, uno::Reference<drawing::XShape> xShape)
27 : : ContextHandler2(rParent),
28 1242 : mxShape(xShape)
29 : {
30 1242 : mpShape.reset(new oox::drawingml::Shape("com.sun.star.drawing.CustomShape"));
31 1242 : mpShape->setWps(true);
32 1242 : }
33 :
34 2484 : WpsContext::~WpsContext()
35 : {
36 2484 : }
37 :
38 4683 : oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken, const oox::AttributeList& rAttribs)
39 : {
40 4683 : switch (getBaseToken(nElementToken))
41 : {
42 : case XML_wsp:
43 846 : break;
44 : case XML_cNvCnPr:
45 114 : break;
46 : case XML_cNvSpPr:
47 732 : break;
48 : case XML_spPr:
49 846 : return new oox::drawingml::ShapePropertiesContext(*this, *mpShape);
50 : break;
51 : case XML_style:
52 425 : return new oox::drawingml::ShapeStyleContext(*this, *mpShape);
53 : break;
54 : case XML_bodyPr:
55 805 : if (mxShape.is())
56 : {
57 396 : uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
58 792 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
59 792 : OptValue<OUString> oVert = rAttribs.getString(XML_vert);
60 396 : if (oVert.has() && oVert.get() == "vert270")
61 : {
62 8 : if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
63 : {
64 : // No support for this in core, work around by char rotation, as we do so for table cells already.
65 0 : uno::Reference<text::XText> xText(mxShape, uno::UNO_QUERY);
66 0 : uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
67 0 : xTextCursor->gotoStart(false);
68 0 : xTextCursor->gotoEnd(true);
69 0 : uno::Reference<beans::XPropertyState> xPropertyState(xTextCursor, uno::UNO_QUERY);
70 0 : beans::PropertyState aState = xPropertyState->getPropertyState("CharRotation");
71 0 : if (aState == beans::PropertyState_DEFAULT_VALUE)
72 : {
73 0 : uno::Reference<beans::XPropertySet> xTextCursorPropertySet(xTextCursor, uno::UNO_QUERY);
74 0 : xTextCursorPropertySet->setPropertyValue("CharRotation", uno::makeAny(sal_Int16(900)));
75 0 : }
76 : }
77 : else
78 : {
79 8 : comphelper::SequenceAsHashMap aCustomShapeGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry"));
80 8 : aCustomShapeGeometry["TextPreRotateAngle"] = uno::makeAny(sal_Int32(-270));
81 8 : xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
82 : }
83 : }
84 :
85 396 : if (xServiceInfo.is())
86 : {
87 396 : bool bTextFrame = xServiceInfo->supportsService("com.sun.star.text.TextFrame");
88 : // Handle inset attributes for Writer textframes.
89 396 : sal_Int32 aInsets[] = { XML_lIns, XML_tIns, XML_rIns, XML_bIns };
90 1980 : boost::optional<sal_Int32> oInsets[4];
91 1980 : for (size_t i = 0; i < SAL_N_ELEMENTS(aInsets); ++i)
92 : {
93 1584 : OptValue<OUString> oValue = rAttribs.getString(aInsets[i]);
94 1584 : if (oValue.has())
95 967 : oInsets[i] = oox::drawingml::GetCoordinate(oValue.get());
96 : else
97 : // Defaults from the spec: left/right: 91440 EMU, top/bottom: 45720 EMU
98 617 : oInsets[i] = (aInsets[i] == XML_lIns || aInsets[i] == XML_rIns) ? 254 : 127;
99 1584 : }
100 792 : OUString aProps[] = { OUString("LeftBorderDistance"), OUString("TopBorderDistance"), OUString("RightBorderDistance"), OUString("BottomBorderDistance") };
101 792 : OUString aShapeProps[] = { OUString("TextLeftDistance"), OUString("TextUpperDistance"), OUString("TextRightDistance"), OUString("TextLowerDistance") };
102 1980 : for (size_t i = 0; i < SAL_N_ELEMENTS(bTextFrame ? aProps : aShapeProps); ++i)
103 1584 : if (oInsets[i])
104 3564 : xPropertySet->setPropertyValue((bTextFrame ? aProps : aShapeProps)[i], uno::makeAny(*oInsets[i]));
105 : }
106 :
107 : // Handle text vertical adjustment inside a text frame
108 396 : if (rAttribs.hasAttribute(XML_anchor))
109 : {
110 361 : drawing::TextVerticalAdjust eAdjust = drawingml::GetTextVerticalAdjust(rAttribs.getToken(XML_anchor, XML_t));
111 361 : xPropertySet->setPropertyValue("TextVerticalAdjust", uno::makeAny(eAdjust));
112 : }
113 :
114 : // Apply character color of the shape to the shape's textbox.
115 792 : uno::Reference<text::XText> xText(mxShape, uno::UNO_QUERY);
116 792 : uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
117 396 : xTextCursor->gotoStart(false);
118 396 : xTextCursor->gotoEnd(true);
119 792 : const uno::Reference<beans::XPropertyState> xPropertyState(xTextCursor, uno::UNO_QUERY);
120 396 : const beans::PropertyState ePropertyState = xPropertyState->getPropertyState("CharColor");
121 396 : if (ePropertyState == beans::PropertyState_DEFAULT_VALUE)
122 : {
123 238 : uno::Reference<beans::XPropertySet> xTextBoxPropertySet(xTextCursor, uno::UNO_QUERY);
124 238 : xTextBoxPropertySet->setPropertyValue("CharColor", xPropertySet->getPropertyValue("CharColor"));
125 : }
126 792 : return this;
127 : }
128 409 : break;
129 : case XML_noAutofit:
130 : case XML_spAutoFit:
131 : {
132 362 : uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
133 : // We can't use oox::drawingml::TextBodyPropertiesContext here, as this
134 : // is a child context of bodyPr, so the shape is already sent: we need
135 : // to alter the XShape directly.
136 724 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
137 362 : if (xPropertySet.is())
138 : {
139 362 : if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
140 0 : xPropertySet->setPropertyValue("FrameIsAutomaticHeight", uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
141 : else
142 362 : xPropertySet->setPropertyValue("TextAutoGrowHeight", uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
143 362 : }
144 : }
145 362 : break;
146 : case XML_prstTxWarp:
147 101 : if (rAttribs.hasAttribute(XML_prst))
148 : {
149 101 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
150 202 : oox::OptValue<OUString> presetShapeName = rAttribs.getString(XML_prst);
151 202 : OUString preset = presetShapeName.get();
152 202 : comphelper::SequenceAsHashMap aCustomShapeGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry"));
153 101 : aCustomShapeGeometry["PresetTextWarp"] = uno::makeAny(preset);
154 203 : xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
155 : }
156 100 : break;
157 : case XML_txbx:
158 : {
159 434 : mpShape->getCustomShapeProperties()->setShapeTypeOverride(true);
160 434 : mpShape->setTextBox(true);
161 : //in case if the textbox is linked, save the attributes
162 : //for further processing.
163 434 : if (rAttribs.hasAttribute(XML_id))
164 : {
165 3 : OptValue<OUString> id = rAttribs.getString(XML_id);
166 3 : if (id.has())
167 : {
168 3 : oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr ;
169 3 : linkedTxtBoxAttr.id = id.get().toInt32();
170 3 : mpShape->setTxbxHasLinkedTxtBox(true);
171 3 : mpShape->setLinkedTxbxAttributes(linkedTxtBoxAttr);
172 3 : }
173 : }
174 : }
175 434 : break;
176 : case XML_linkedTxbx:
177 : {
178 : //in case if the textbox is linked, save the attributes
179 : //for further processing.
180 3 : mpShape->getCustomShapeProperties()->setShapeTypeOverride(true);
181 3 : mpShape->setTextBox(true);
182 3 : OptValue<OUString> id = rAttribs.getString(XML_id);
183 6 : OptValue<OUString> seq = rAttribs.getString(XML_seq);
184 3 : if (id.has() && seq.has())
185 : {
186 3 : oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr ;
187 3 : linkedTxtBoxAttr.id = id.get().toInt32();
188 3 : linkedTxtBoxAttr.seq = seq.get().toInt32();
189 3 : mpShape->setTxbxHasLinkedTxtBox(true);
190 3 : mpShape->setLinkedTxbxAttributes(linkedTxtBoxAttr);
191 3 : }
192 : }
193 3 : break;
194 : default:
195 : SAL_WARN("oox", "WpsContext::createFastChildContext: unhandled element: " << getBaseToken(nElementToken));
196 15 : break;
197 : }
198 3015 : return 0;
199 : }
200 :
201 : }
202 246 : }
203 :
204 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|