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 2336 : WpsContext::WpsContext(ContextHandler2Helper& rParent, uno::Reference<drawing::XShape> xShape)
27 : : ContextHandler2(rParent),
28 2336 : mxShape(xShape)
29 : {
30 2336 : mpShape.reset(new oox::drawingml::Shape("com.sun.star.drawing.CustomShape"));
31 2336 : mpShape->setWps(true);
32 2336 : }
33 :
34 4672 : WpsContext::~WpsContext()
35 : {
36 4672 : }
37 :
38 8830 : oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken, const oox::AttributeList& rAttribs)
39 : {
40 8830 : switch (getBaseToken(nElementToken))
41 : {
42 : case XML_wsp:
43 1606 : break;
44 : case XML_cNvCnPr:
45 228 : break;
46 : case XML_cNvSpPr:
47 1378 : break;
48 : case XML_spPr:
49 1606 : return new oox::drawingml::ShapePropertiesContext(*this, *mpShape);
50 : break;
51 : case XML_style:
52 796 : return new oox::drawingml::ShapeStyleContext(*this, *mpShape);
53 : break;
54 : case XML_bodyPr:
55 1532 : if (mxShape.is())
56 : {
57 730 : uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
58 1460 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
59 1460 : OptValue<OUString> oVert = rAttribs.getString(XML_vert);
60 730 : if (oVert.has() && oVert.get() == "vert270")
61 : {
62 16 : 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 16 : comphelper::SequenceAsHashMap aCustomShapeGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry"));
80 16 : aCustomShapeGeometry["TextPreRotateAngle"] = uno::makeAny(sal_Int32(-270));
81 16 : xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
82 : }
83 : }
84 :
85 730 : if (xServiceInfo.is())
86 : {
87 730 : bool bTextFrame = xServiceInfo->supportsService("com.sun.star.text.TextFrame");
88 : // Handle inset attributes for Writer textframes.
89 730 : sal_Int32 aInsets[] = { XML_lIns, XML_tIns, XML_rIns, XML_bIns };
90 3650 : boost::optional<sal_Int32> oInsets[4];
91 3650 : for (size_t i = 0; i < SAL_N_ELEMENTS(aInsets); ++i)
92 : {
93 2920 : OptValue<OUString> oValue = rAttribs.getString(aInsets[i]);
94 2920 : if (oValue.has())
95 1758 : oInsets[i] = oox::drawingml::GetCoordinate(oValue.get());
96 : else
97 : // Defaults from the spec: left/right: 91440 EMU, top/bottom: 45720 EMU
98 1162 : oInsets[i] = (aInsets[i] == XML_lIns || aInsets[i] == XML_rIns) ? 254 : 127;
99 2920 : }
100 1460 : OUString aProps[] = { OUString("LeftBorderDistance"), OUString("TopBorderDistance"), OUString("RightBorderDistance"), OUString("BottomBorderDistance") };
101 1460 : OUString aShapeProps[] = { OUString("TextLeftDistance"), OUString("TextUpperDistance"), OUString("TextRightDistance"), OUString("TextLowerDistance") };
102 3650 : for (size_t i = 0; i < SAL_N_ELEMENTS(bTextFrame ? aProps : aShapeProps); ++i)
103 2920 : if (oInsets[i])
104 6570 : xPropertySet->setPropertyValue((bTextFrame ? aProps : aShapeProps)[i], uno::makeAny(*oInsets[i]));
105 : }
106 :
107 : // Handle text vertical adjustment inside a text frame
108 730 : if (rAttribs.hasAttribute(XML_anchor))
109 : {
110 674 : drawing::TextVerticalAdjust eAdjust = drawingml::GetTextVerticalAdjust(rAttribs.getToken(XML_anchor, XML_t));
111 674 : xPropertySet->setPropertyValue("TextVerticalAdjust", uno::makeAny(eAdjust));
112 : }
113 :
114 : // Apply character color of the shape to the shape's textbox.
115 1460 : uno::Reference<text::XText> xText(mxShape, uno::UNO_QUERY);
116 1460 : uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
117 730 : xTextCursor->gotoStart(false);
118 730 : xTextCursor->gotoEnd(true);
119 1460 : const uno::Reference<beans::XPropertyState> xPropertyState(xTextCursor, uno::UNO_QUERY);
120 730 : const beans::PropertyState ePropertyState = xPropertyState->getPropertyState("CharColor");
121 730 : if (ePropertyState == beans::PropertyState_DEFAULT_VALUE)
122 : {
123 432 : uno::Reference<beans::XPropertySet> xTextBoxPropertySet(xTextCursor, uno::UNO_QUERY);
124 432 : xTextBoxPropertySet->setPropertyValue("CharColor", xPropertySet->getPropertyValue("CharColor"));
125 : }
126 1460 : return this;
127 : }
128 802 : break;
129 : case XML_noAutofit:
130 : case XML_spAutoFit:
131 : {
132 666 : 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 1332 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
137 666 : if (xPropertySet.is())
138 : {
139 666 : if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
140 0 : xPropertySet->setPropertyValue("FrameIsAutomaticHeight", uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
141 : else
142 666 : xPropertySet->setPropertyValue("TextAutoGrowHeight", uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
143 666 : }
144 : }
145 666 : break;
146 : case XML_prstTxWarp:
147 190 : if (rAttribs.hasAttribute(XML_prst))
148 : {
149 190 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
150 380 : oox::OptValue<OUString> presetShapeName = rAttribs.getString(XML_prst);
151 380 : OUString preset = presetShapeName.get();
152 380 : comphelper::SequenceAsHashMap aCustomShapeGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry"));
153 190 : aCustomShapeGeometry["PresetTextWarp"] = uno::makeAny(preset);
154 382 : xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
155 : }
156 188 : break;
157 : case XML_txbx:
158 : {
159 798 : mpShape->getCustomShapeProperties()->setShapeTypeOverride(true);
160 798 : mpShape->setTextBox(true);
161 : //in case if the textbox is linked, save the attributes
162 : //for further processing.
163 798 : if (rAttribs.hasAttribute(XML_id))
164 : {
165 6 : OptValue<OUString> id = rAttribs.getString(XML_id);
166 6 : if (id.has())
167 : {
168 6 : oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr ;
169 6 : linkedTxtBoxAttr.id = id.get().toInt32();
170 6 : mpShape->setTxbxHasLinkedTxtBox(true);
171 6 : mpShape->setLinkedTxbxAttributes(linkedTxtBoxAttr);
172 6 : }
173 : }
174 : }
175 798 : break;
176 : case XML_linkedTxbx:
177 : {
178 : //in case if the textbox is linked, save the attributes
179 : //for further processing.
180 6 : mpShape->getCustomShapeProperties()->setShapeTypeOverride(true);
181 6 : mpShape->setTextBox(true);
182 6 : OptValue<OUString> id = rAttribs.getString(XML_id);
183 12 : OptValue<OUString> seq = rAttribs.getString(XML_seq);
184 6 : if (id.has() && seq.has())
185 : {
186 6 : oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr ;
187 6 : linkedTxtBoxAttr.id = id.get().toInt32();
188 6 : linkedTxtBoxAttr.seq = seq.get().toInt32();
189 6 : mpShape->setTxbxHasLinkedTxtBox(true);
190 6 : mpShape->setLinkedTxbxAttributes(linkedTxtBoxAttr);
191 6 : }
192 : }
193 6 : break;
194 : default:
195 : SAL_WARN("oox", "WpsContext::createFastChildContext: unhandled element: " << getBaseToken(nElementToken));
196 24 : break;
197 : }
198 5696 : return 0;
199 : }
200 :
201 : }
202 408 : }
203 :
204 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|