LibreOffice Module oox (master)  1
DMLPresetShapeExport.cxx
Go to the documentation of this file.
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 
11 #include <oox/token/tokens.hxx>
12 
13 #include <com/sun/star/beans/XPropertySet.hpp>
14 #include <com/sun/star/beans/PropertyValue.hpp>
15 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
16 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
17 #include <com/sun/star/drawing/XShape.hpp>
18 
19 #include <osl/diagnose.h>
20 #include <filter/msfilter/util.hxx>
21 
22 #include <string_view>
23 
24 using namespace ::css;
25 using namespace ::css::drawing;
26 
27 namespace oox::drawingml
28 {
29 // DMLPresetShapeExporter class
30 
31 // ctor
33  css::uno::Reference<css::drawing::XShape> xShape)
34  : m_pDMLexporter(pDMLExporter)
35 {
36  // This class only work with custom shapes!
37  OSL_ASSERT(xShape->getShapeType() == "com.sun.star.drawing.CustomShape");
38 
39  m_xShape = xShape;
40  m_bHasHandleValues = false;
41  uno::Reference<beans::XPropertySet> xShapeProps(m_xShape, uno::UNO_QUERY);
42  css::uno::Sequence<css::beans::PropertyValue> aCustomShapeGeometry
43  = xShapeProps->getPropertyValue("CustomShapeGeometry")
44  .get<uno::Sequence<beans::PropertyValue>>();
45 
46  for (sal_uInt32 i = 0; i < aCustomShapeGeometry.size(); i++)
47  {
48  if (aCustomShapeGeometry[i].Name == "Type")
49  {
50  m_sPresetShapeType = aCustomShapeGeometry[i].Value.get<OUString>();
51  }
52  if (aCustomShapeGeometry[i].Name == "Handles")
53  {
54  m_bHasHandleValues = true;
56  = aCustomShapeGeometry[i]
57  .Value
58  .get<css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>>>();
59  }
60  if (aCustomShapeGeometry[i].Name == "AdjustmentValues")
61  {
63  = aCustomShapeGeometry[i]
64  .Value
65  .get<css::uno::Sequence<css::drawing::EnhancedCustomShapeAdjustmentValue>>();
66  }
67  if (aCustomShapeGeometry[i].Name == "MirroredX")
68  {
69  m_bIsFlipped.first = aCustomShapeGeometry[i].Value.get<bool>();
70  }
71  if (aCustomShapeGeometry[i].Name == "MirroredY")
72  {
73  m_bIsFlipped.second = aCustomShapeGeometry[i].Value.get<bool>();
74  }
75  //if (aCustomShapeGeometry[i].Name == "Equations")
76  //{
77  // m_Equations = aCustomShapeGeometry[i].Value.get<css::uno::Sequence<OUString>>();
78  //}
79  //if (aCustomShapeGeometry[i].Name == "Path")
80  //{
81  // m_Path = aCustomShapeGeometry[i]
82  // .Value.get<css::uno::Sequence<css::beans::PropertyValue>>();
83  //}
84  //if (aCustomShapeGeometry[i].Name == "ViewBox")
85  //{
86  // m_ViewBox = aCustomShapeGeometry[i].Value.get<css::awt::Rectangle>();
87  //}
88  }
89 };
90 
91 // dtor
93  // Do nothing
94 };
95 
97 
98 const OUString& DMLPresetShapeExporter::GetShapeType() const { return m_sPresetShapeType; }
99 
100 const css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>>&
102 {
103  return m_HandleValues;
104 };
105 
106 const css::uno::Sequence<css::drawing::EnhancedCustomShapeAdjustmentValue>&
108 {
109  return m_AdjustmentValues;
110 };
111 
113  std::u16string_view sType)
114 {
115  uno::Any aRet;
116  if (GetHandleValues().getLength() > nPoint)
117  {
118  for (sal_Int32 i = 0; i < GetHandleValues()[nPoint].getLength(); i++)
119  {
120  if (GetHandleValues()[nPoint][i].Name == sType)
121  {
122  aRet = GetHandleValues()[nPoint][i].Value;
123  break;
124  }
125  }
126  }
127  return aRet;
128 };
129 
132 {
134  try
135  {
136  auto aValPos = GetHandleValueOfModificationPoint(nPoint, u"Position")
137  .get<EnhancedCustomShapeParameterPair>();
138  aRet.nMinVal = GetHandleValueOfModificationPoint(nPoint, u"RadiusRangeMinimum")
139  .get<EnhancedCustomShapeParameter>()
140  .Value.get<double>();
141  aRet.nMaxVal = GetHandleValueOfModificationPoint(nPoint, u"RadiusRangeMaximum")
142  .get<EnhancedCustomShapeParameter>()
143  .Value.get<double>();
144  aRet.nCurrVal = GetAdjustmentValues()[aValPos.First.Value.get<long>()].Value.get<double>();
145  }
146  catch (...)
147  {
148  // Do nothing.
149  }
150  return aRet;
151 };
152 
155 {
157  try
158  {
159  auto aValPos = GetHandleValueOfModificationPoint(nPoint, u"Position")
160  .get<EnhancedCustomShapeParameterPair>();
161  aRet.nMinVal = 0;
162  aRet.nMaxVal = 360;
163  aRet.nCurrVal = GetAdjustmentValues()[aValPos.Second.Value.get<long>()].Value.get<double>();
164  }
165  catch (...)
166  {
167  // Do nothing.
168  }
169  return aRet;
170 };
171 
174 {
175  XAdjustmentValue aRet;
176  try
177  {
178  auto aValPos = GetHandleValueOfModificationPoint(nPoint, u"Position")
179  .get<EnhancedCustomShapeParameterPair>();
180  aRet.nMinVal = GetHandleValueOfModificationPoint(nPoint, u"RangeXMinimum")
181  .get<EnhancedCustomShapeParameter>()
182  .Value.get<double>();
183  aRet.nMaxVal = GetHandleValueOfModificationPoint(nPoint, u"RangeXMaximum")
184  .get<EnhancedCustomShapeParameter>()
185  .Value.get<double>();
186  aRet.nCurrVal = GetAdjustmentValues()[aValPos.First.Value.get<long>()].Value.get<double>();
187  }
188  catch (...)
189  {
190  // Do nothing.
191  }
192  return aRet;
193 };
194 
197 {
198  YAdjustmentValue aRet;
199  try
200  {
201  auto aValPos = GetHandleValueOfModificationPoint(nPoint, u"Position")
202  .get<EnhancedCustomShapeParameterPair>();
203  aRet.nMinVal = GetHandleValueOfModificationPoint(nPoint, u"RangeYMinimum")
204  .get<EnhancedCustomShapeParameter>()
205  .Value.get<double>();
206  aRet.nMaxVal = GetHandleValueOfModificationPoint(nPoint, u"RangeYMaximum")
207  .get<EnhancedCustomShapeParameter>()
208  .Value.get<double>();
209  aRet.nCurrVal = GetAdjustmentValues()[aValPos.Second.Value.get<long>()].Value.get<double>();
210  }
211  catch (...)
212  {
213  // Do nothing.
214  }
215  return aRet;
216 };
217 
219 {
220  if (m_pDMLexporter && m_xShape)
221  {
222  // Case 1: We do not have adjustment points of the shape: just export it as preset
223  if (!m_bHasHandleValues)
224  {
225  OUString sShapeType = GetShapeType();
226  const char* sPresetShape
227  = msfilter::util::GetOOXMLPresetGeometry(sShapeType.toUtf8().getStr());
229  false, false);
230  m_pDMLexporter->WritePresetShape(sPresetShape);
231  return true;
232  }
233  else // Case2: There are adjustment points what have to be converted and exported.
234  {
235  return WriteShapeWithAVlist();
236  }
237  }
238  return false;
239 };
240 
241 bool DMLPresetShapeExporter::WriteAV(const OUString& sValName, const OUString& sVal)
242 {
243  try
244  {
245  m_pDMLexporter->GetFS()->singleElementNS(XML_a, XML_gd, XML_name, sValName, XML_fmla, sVal);
246  return true;
247  }
248  catch (...)
249  {
250  return false;
251  }
252 };
253 
255 {
256  try
257  {
258  const char* pShape
260  m_pDMLexporter->GetFS()->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
261  m_pDMLexporter->GetFS()->startElementNS(XML_a, XML_avLst);
262  return true;
263  }
264  catch (...)
265  {
266  return false;
267  }
268 };
270 {
271  try
272  {
273  m_pDMLexporter->GetFS()->endElementNS(XML_a, XML_avLst);
274  m_pDMLexporter->GetFS()->endElementNS(XML_a, XML_prstGeom);
275  return true;
276  }
277  catch (...)
278  {
279  return false;
280  }
281 };
282 
284 {
285  // Remark: This method is under development. If a shape type is implemented, the corresponding,
286  // return must be set to true. False means nothing done true, export done. There are many
287  // types which do not have pairs in LO, they are do not have to be mapped, because import
288  // filter it does with GrabBag, this method only maps the SDR ones to OOXML shapes.
289 
290  OString sShapeType(msfilter::util::GetOOXMLPresetGeometry(GetShapeType().toUtf8().getStr()));
291 
292  // OOXML uses 60th of degree, so 360 degree is 21 600 000 60thdeg
293  const tools::Long nConstOfMaxDegreeOf60th = 21600000;
294  try
295  {
296  if (sShapeType == "accentBorderCallout1")
297  {
298  // LO does not have this type, so it does not necessary to be mapped.
299  return false;
300  }
301  if (sShapeType == "accentBorderCallout2")
302  {
303  // LO does not have this type, so it does not necessary to be mapped.
304  return false;
305  }
306  if (sShapeType == "accentBorderCallout3")
307  {
308  // LO does not have this type, so it does not necessary to be mapped.
309  return false;
310  }
311  if (sShapeType == "accentCallout1")
312  {
313  // LO does not have this type, so it does not necessary to be mapped.
314  return false;
315  }
316  if (sShapeType == "accentCallout2")
317  {
318  // LO does not have this type, so it does not necessary to be mapped.
319  return false;
320  }
321  if (sShapeType == "accentCallout3")
322  {
323  // LO does not have this type, so it does not necessary to be mapped.
324  return false;
325  }
326  if (sShapeType == "actionButtonBackPrevious")
327  {
328  // LO does not have this type, so it does not necessary to be mapped.
329  return false;
330  }
331  if (sShapeType == "actionButtonBeginning")
332  {
333  // LO does not have this type, so it does not necessary to be mapped.
334  return false;
335  }
336  if (sShapeType == "actionButtonBlank")
337  {
338  // LO does not have this type, so it does not necessary to be mapped.
339  return false;
340  }
341  if (sShapeType == "actionButtonDocument")
342  {
343  // LO does not have this type, so it does not necessary to be mapped.
344  return false;
345  }
346  if (sShapeType == "actionButtonEnd")
347  {
348  // LO does not have this type, so it does not necessary to be mapped.
349  return false;
350  }
351  if (sShapeType == "actionButtonForwardNext")
352  {
353  // LO does not have this type, so it does not necessary to be mapped.
354  return false;
355  }
356  if (sShapeType == "actionButtonHelp")
357  {
358  // LO does not have this type, so it does not necessary to be mapped.
359  return false;
360  }
361  if (sShapeType == "actionButtonHome")
362  {
363  // LO does not have this type, so it does not necessary to be mapped.
364  return false;
365  }
366  if (sShapeType == "actionButtonInformation")
367  {
368  // LO does not have this type, so it does not necessary to be mapped.
369  return false;
370  }
371  if (sShapeType == "actionButtonMovie")
372  {
373  // LO does not have this type, so it does not necessary to be mapped.
374  return false;
375  }
376  if (sShapeType == "actionButtonReturn")
377  {
378  // LO does not have this type, so it does not necessary to be mapped.
379  return false;
380  }
381  if (sShapeType == "actionButtonSound")
382  {
383  // LO does not have this type, so it does not necessary to be mapped.
384  return false;
385  }
386  if (sShapeType == "arc")
387  {
388  // LO does not have handle points for this, so CustGeom is enough.
389  return false;
390  }
391  if (sShapeType == "bentArrow")
392  {
393  // LO has only one type, which have to be rotated, without handling points
394  // So CustGeom enough.
395  return false;
396  }
397  if (sShapeType == "bentConnector2")
398  {
399  // CustGeom Enough
400  return false;
401  }
402  if (sShapeType == "bentConnector3")
403  {
404  // CustGeom Enough
405  return false;
406  }
407  if (sShapeType == "bentConnector4")
408  {
409  // CustGeom Enough
410  return false;
411  }
412  if (sShapeType == "bentConnector5")
413  {
414  // CustGeom Enough
415  return false;
416  }
417  if (sShapeType == "bentUpArrow")
418  {
419  // CustGeom Enough, no handle points
420  return false;
421  }
422  if (sShapeType == "bevel")
423  {
424  auto aPoint1 = GetAdjustmentPointXValue(0);
425  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
426  || !aPoint1.nMinVal.has_value())
427  return false;
429  false, false);
430 
431  tools::Long nVal1
432  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * 50000);
433  return StartAVListWriting()
434  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
435  && EndAVListWriting();
436  }
437  if (sShapeType == "blockArc")
438  {
439  auto aPointR = GetAdjustmentPointRadiusValue(0);
440  auto aPointA = GetAdjustmentPointAngleValue(0);
441  if (!aPointA.nCurrVal.has_value() || !aPointA.nMaxVal.has_value()
442  || !aPointA.nMinVal.has_value() || !aPointR.nCurrVal.has_value()
443  || !aPointR.nMaxVal.has_value() || !aPointR.nMinVal.has_value())
444  return false;
446  false, false);
447  tools::Long nVal1
448  = std::lround((*aPointA.nCurrVal < 0 ? 360 + *aPointA.nCurrVal : *aPointA.nCurrVal)
449  / (*aPointA.nMaxVal - *aPointA.nMinVal) * nConstOfMaxDegreeOf60th);
450  tools::Long nVal2 = std::lround(
451  (*aPointA.nCurrVal > 180 ? 360 - *aPointA.nCurrVal : 180 - *aPointA.nCurrVal)
452  / (*aPointA.nMaxVal - *aPointA.nMinVal) * nConstOfMaxDegreeOf60th);
453  tools::Long nVal3 = std::lround(
454  50000 - (*aPointR.nCurrVal / (*aPointR.nMaxVal - *aPointR.nMinVal) * 50000));
455  return StartAVListWriting()
456  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
457  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
458  && WriteAV(u"adj3", OUString(u"val " + OUString::number(nVal3)))
459  && EndAVListWriting();
460  }
461  if (sShapeType == "borderCallout1")
462  {
463  // LO does not have this type, so it does not necessary to be mapped.
464  return false;
465  }
466  if (sShapeType == "borderCallout2")
467  {
468  // LO does not have this type, so it does not necessary to be mapped.
469  return false;
470  }
471  if (sShapeType == "borderCallout3")
472  {
473  // LO does not have this type, so it does not necessary to be mapped.
474  return false;
475  }
476  if (sShapeType == "bracePair")
477  {
478  auto aPoint1 = GetAdjustmentPointYValue(0);
479  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
480  || !aPoint1.nMinVal.has_value())
481  return false;
482 
484  false, false);
485  tools::Long nVal1
486  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * 25000);
487  return StartAVListWriting()
488  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
489  && EndAVListWriting();
490  }
491  if (sShapeType == "bracketPair")
492  {
493  auto aPoint1 = GetAdjustmentPointYValue(0);
494  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
495  || !aPoint1.nMinVal.has_value())
496  return false;
497 
499  false, false);
500  tools::Long nVal1
501  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * 50000);
502  return StartAVListWriting()
503  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
504  && EndAVListWriting();
505  }
506  if (sShapeType == "callout1")
507  {
508  // LO does not have this type, so it does not necessary to be mapped.
509  return false;
510  }
511  if (sShapeType == "callout2")
512  {
513  // LO does not have this type, so it does not necessary to be mapped.
514  return false;
515  }
516  if (sShapeType == "callout3")
517  {
518  // LO does not have this type, so it does not necessary to be mapped.
519  return false;
520  }
521  if (sShapeType == "can")
522  {
523  return false;
524  // Do the export as before.
525  }
526  if (sShapeType == "chartPlus")
527  {
528  // LO does not have this type, so it does not necessary to be mapped.
529  return false;
530  }
531  if (sShapeType == "chartStar")
532  {
533  // LO does not have this type, so it does not necessary to be mapped.
534  return false;
535  }
536  if (sShapeType == "chartX")
537  {
538  // LO does not have this type, so it does not necessary to be mapped.
539  return false;
540  }
541  if (sShapeType == "chord")
542  {
543  // CustGeom, because LO does not have handle points
544  return false;
545  }
546  if (sShapeType == "circularArrow")
547  {
548  // LO does not have this type, so it does not necessary to be mapped.
549  return false;
550  }
551  if (sShapeType == "cloud")
552  {
553  // CustGeom enough
554  return false;
555  }
556  if (sShapeType == "cloudCallout")
557  {
558  return false;
559  // Works fine without this, so export it like before.
560  }
561  if (sShapeType == "cornerTabs")
562  {
563  // LO does not have this type, so it does not necessary to be mapped.
564  return false;
565  }
566  if (sShapeType == "cube")
567  {
568  // Works fine without this, so export it like before.
569  return false;
570  }
571  if (sShapeType == "curvedConnector2")
572  {
573  // Not necessary to be mapped
574  return false;
575  }
576  if (sShapeType == "curvedConnector3")
577  {
578  // Not necessary to be mapped
579  return false;
580  }
581  if (sShapeType == "curvedConnector4")
582  {
583  // Not necessary to be mapped
584  return false;
585  }
586  if (sShapeType == "curvedConnector5")
587  {
588  // Not necessary to be mapped
589  return false;
590  }
591  if (sShapeType == "curvedDownArrow")
592  {
593  // LO does not have this type, so it does not necessary to be mapped.
594  return false;
595  }
596  if (sShapeType == "curvedLeftArrow")
597  {
598  // LO does not have this type, so it does not necessary to be mapped.
599  return false;
600  }
601  if (sShapeType == "curvedRightArrow")
602  {
603  // LO does not have this type, so it does not necessary to be mapped.
604  return false;
605  }
606  if (sShapeType == "curvedUpArrow")
607  {
608  // LO does not have this type, so it does not necessary to be mapped.
609  return false;
610  }
611  if (sShapeType == "decagon")
612  {
613  // LO does not have this type, so it does not necessary to be mapped.
614  return false;
615  }
616  if (sShapeType == "diagStripe")
617  {
618  // LO does not have this type, so it does not necessary to be mapped.
619  return false;
620  }
621  if (sShapeType == "diamond")
622  {
623  // It does not have handle points so it do not have to be mapped.
624  return false;
625  }
626  if (sShapeType == "dodecagon")
627  {
628  // LO does not have this type, so it does not necessary to be mapped.
629  return false;
630  }
631  if (sShapeType == "donut")
632  {
633  // TODO
634  return false;
635  }
636  if (sShapeType == "doubleWave")
637  {
638  // LO does not have this type, so it does not necessary to be mapped.
639  return false;
640  }
641  if (sShapeType == "downArrow")
642  {
643  auto aPointX = GetAdjustmentPointXValue(0);
644  auto aPointY = GetAdjustmentPointYValue(0);
645  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
646  || !aPointX.nMinVal.has_value() || !aPointY.nCurrVal.has_value()
647  || !aPointY.nMaxVal.has_value() || !aPointY.nMinVal.has_value())
648  return false;
649 
651  false, false);
652  tools::Long nMaxVal1 = 100000;
653  tools::Long nMaxVal2
654  = 100000 * m_xShape->getSize().Height
655  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
656  tools::Long nVal1 = std::lround((*aPointX.nMaxVal - *aPointX.nCurrVal)
657  / (*aPointX.nMaxVal - *aPointX.nMinVal) * nMaxVal1);
658  tools::Long nVal2 = std::lround((*aPointY.nMaxVal - *aPointY.nCurrVal)
659  / (*aPointY.nMaxVal - *aPointY.nMinVal) * nMaxVal2);
660  return StartAVListWriting()
661  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
662  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
663  && EndAVListWriting();
664  }
665  if (sShapeType == "downArrowCallout")
666  {
667  auto aNeckFromBox = GetAdjustmentPointXValue(1);
668  auto aHeadFromNeck = GetAdjustmentPointXValue(2);
669  auto aHeadHeight = GetAdjustmentPointYValue(1);
670  auto aBoxHeight = GetAdjustmentPointYValue(0);
671  if (!aNeckFromBox.nCurrVal.has_value() || !aNeckFromBox.nMaxVal.has_value()
672  || !aNeckFromBox.nMinVal.has_value() || !aHeadFromNeck.nCurrVal.has_value()
673  || !aHeadFromNeck.nMaxVal.has_value() || !aHeadFromNeck.nMinVal.has_value()
674  || !aHeadHeight.nCurrVal.has_value() || !aHeadHeight.nMaxVal.has_value()
675  || !aHeadHeight.nMinVal.has_value() || !aBoxHeight.nCurrVal.has_value()
676  || !aBoxHeight.nMaxVal.has_value() || !aBoxHeight.nMinVal.has_value())
677  return false;
678 
680  false, false);
681  tools::Long nMaxVal1
682  = 100000 * m_xShape->getSize().Width
683  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
684  tools::Long nMaxVal2
685  = 50000 * m_xShape->getSize().Width
686  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
687  tools::Long nMaxVal3
688  = 100000 * m_xShape->getSize().Height
689  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
690  tools::Long nVal1
691  = std::lround((*aNeckFromBox.nMaxVal - *aNeckFromBox.nCurrVal)
692  / (*aNeckFromBox.nMaxVal - *aNeckFromBox.nMinVal) * nMaxVal1);
693  tools::Long nVal2 = std::lround((10800 - *aHeadFromNeck.nCurrVal)
694  / (10800 - *aHeadFromNeck.nMinVal) * nMaxVal2);
695  tools::Long nVal3
696  = std::lround((*aHeadHeight.nMaxVal - *aHeadHeight.nCurrVal)
697  / (*aHeadHeight.nMaxVal - *aHeadHeight.nMinVal) * nMaxVal3);
698  tools::Long nVal4 = std::lround((*aBoxHeight.nCurrVal - *aBoxHeight.nMinVal)
699  / (21600 - *aBoxHeight.nMinVal) * 100000);
700  return StartAVListWriting()
701  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
702  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
703  && WriteAV(u"adj3", OUString(u"val " + OUString::number(nVal3)))
704  && WriteAV(u"adj4", OUString(u"val " + OUString::number(nVal4)))
705  && EndAVListWriting();
706  }
707  if (sShapeType == "ellipse")
708  {
709  // Does not have handle points, so preset enough.
710  return false;
711  }
712  if (sShapeType == "ellipseRibbon")
713  {
714  // LO does not have this type, so it does not necessary to be mapped.
715  return false;
716  }
717  if (sShapeType == "ellipseRibbon2")
718  {
719  // LO does not have this type, so it does not necessary to be mapped.
720  return false;
721  }
722  if (sShapeType == "flowChartAlternateProcess")
723  {
724  // Does not have handle points, so preset enough.
725  return false;
726  }
727  if (sShapeType == "flowChartCollate")
728  {
729  // Does not have handle points, so preset enough.
730  return false;
731  }
732  if (sShapeType == "flowChartConnector")
733  {
734  // Does not have handle points, so preset enough.
735  return false;
736  }
737  if (sShapeType == "flowChartDecision")
738  {
739  // Does not have handle points, so preset enough.
740  return false;
741  }
742  if (sShapeType == "flowChartDecision")
743  {
744  // Does not have handle points, so preset enough.
745  return false;
746  }
747  if (sShapeType == "flowChartDelay")
748  {
749  // Does not have handle points, so preset enough.
750  return false;
751  }
752  if (sShapeType == "flowChartDisplay")
753  {
754  // Does not have handle points, so preset enough.
755  return false;
756  }
757  if (sShapeType == "flowChartDocument")
758  {
759  // Does not have handle points, so preset enough.
760  return false;
761  }
762  if (sShapeType == "flowChartExtract")
763  {
764  // Does not have handle points, so preset enough.
765  return false;
766  }
767  if (sShapeType == "flowChartInputOutput")
768  {
769  // Does not have handle points, so preset enough.
770  return false;
771  }
772  if (sShapeType == "flowChartInternalStorage")
773  {
774  // Does not have handle points, so preset enough.
775  return false;
776  }
777  if (sShapeType == "flowChartMagneticDisk")
778  {
779  // Does not have handle points, so preset enough.
780  return false;
781  }
782  if (sShapeType == "flowChartMagneticDrum")
783  {
784  // Does not have handle points, so preset enough.
785  return false;
786  }
787  if (sShapeType == "flowChartMagneticTape")
788  {
789  // Does not have handle points, so preset enough.
790  return false;
791  }
792  if (sShapeType == "flowChartManualInput")
793  {
794  // Does not have handle points, so preset enough.
795  return false;
796  }
797  if (sShapeType == "flowChartManualOperation")
798  {
799  // Does not have handle points, so preset enough.
800  return false;
801  }
802  if (sShapeType == "flowChartMerge")
803  {
804  // Does not have handle points, so preset enough.
805  return false;
806  }
807  if (sShapeType == "flowChartMultidocument")
808  {
809  // Does not have handle points, so preset enough.
810  return false;
811  }
812  if (sShapeType == "flowChartOfflineStorage")
813  {
814  // Does not have handle points, so preset enough.
815  return false;
816  }
817  if (sShapeType == "flowChartOffpageConnector")
818  {
819  // Does not have handle points, so preset enough.
820  return false;
821  }
822  if (sShapeType == "flowChartOnlineStorage")
823  {
824  // Does not have handle points, so preset enough.
825  return false;
826  }
827  if (sShapeType == "flowChartOr")
828  {
829  // Does not have handle points, so preset enough.
830  return false;
831  }
832  if (sShapeType == "flowChartDecision")
833  {
834  // Does not have handle points, so preset enough.
835  return false;
836  }
837  if (sShapeType == "flowChartPredefinedProcess")
838  {
839  // Does not have handle points, so preset enough.
840  return false;
841  }
842  if (sShapeType == "flowChartPreparation")
843  {
844  // Does not have handle points, so preset enough.
845  return false;
846  }
847  if (sShapeType == "flowChartPunchedCard")
848  {
849  // Does not have handle points, so preset enough.
850  return false;
851  }
852  if (sShapeType == "flowChartPunchedTape")
853  {
854  // Does not have handle points, so preset enough.
855  return false;
856  }
857  if (sShapeType == "flowChartSort")
858  {
859  // Does not have handle points, so preset enough.
860  return false;
861  }
862  if (sShapeType == "flowChartSummingJunction")
863  {
864  // Does not have handle points, so preset enough.
865  return false;
866  }
867  if (sShapeType == "flowChartTerminator")
868  {
869  // Does not have handle points, so preset enough.
870  return false;
871  }
872  if (sShapeType == "foldedCorner")
873  {
874  // TODO
875  return false;
876  }
877  if (sShapeType == "frame")
878  {
879  // TODO
880  return false;
881  }
882  if (sShapeType == "funnel")
883  {
884  // Not found in word
885  return false;
886  }
887  if (sShapeType == "gear6")
888  {
889  // Not found in word
890  return false;
891  }
892  if (sShapeType == "gear9")
893  {
894  // Not found in word
895  return false;
896  }
897  if (sShapeType == "halfFrame")
898  {
899  // LO does not have this type, not necessary to map
900  return false;
901  }
902  if (sShapeType == "heart")
903  {
904  // TODO
905  return false;
906  }
907  if (sShapeType == "heptagon")
908  {
909  // LO does not have this type, not necessary to map
910  return false;
911  }
912  if (sShapeType == "hexagon")
913  {
914  auto aPoint1 = GetAdjustmentPointXValue(0);
915  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
916  || !aPoint1.nMinVal.has_value())
917  return false;
918 
920  false, false);
921  tools::Long nMaxVal = 50000 * m_xShape->getSize().Width
922  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
923  tools::Long nVal1
924  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * nMaxVal);
925  return StartAVListWriting()
926  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
927  && WriteAV(u"vf", OUString(u"val " + OUString::number(115470)))
928  && EndAVListWriting();
929  }
930  if (sShapeType == "homePlate")
931  {
932  // Not found in word
933  return false;
934  }
935  if (sShapeType == "horizontalScroll")
936  {
937  // TODO
938  return false;
939  }
940  if (sShapeType == "irregularSeal1")
941  {
942  // Not found in word
943  return false;
944  }
945  if (sShapeType == "irregularSeal2")
946  {
947  // Not found in word
948  return false;
949  }
950  if (sShapeType == "leftArrow")
951  {
952  auto aPointX = GetAdjustmentPointXValue(0);
953  auto aPointY = GetAdjustmentPointYValue(0);
954  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
955  || !aPointX.nMinVal.has_value() || !aPointY.nCurrVal.has_value()
956  || !aPointY.nMaxVal.has_value() || !aPointY.nMinVal.has_value())
957  return false;
958 
960  false, false);
961  tools::Long nMaxVal1 = 100000;
962  tools::Long nMaxVal2
963  = 100000
964  * (double(m_xShape->getSize().Width)
965  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height));
966  tools::Long nVal1 = std::lround((*aPointY.nMaxVal - *aPointY.nCurrVal)
967  / (*aPointY.nMaxVal - *aPointY.nMinVal) * nMaxVal1);
968  tools::Long nVal2 = std::lround((*aPointX.nCurrVal - *aPointX.nMinVal)
969  / (*aPointX.nMaxVal - *aPointX.nMinVal) * nMaxVal2);
970  return StartAVListWriting()
971  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
972  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
973  && EndAVListWriting();
974  }
975  if (sShapeType == "leftArrowCallout")
976  {
977  auto aBoxWidth = GetAdjustmentPointXValue(0);
978  auto aNeckLength = GetAdjustmentPointXValue(1);
979  auto aNeckFromBox = GetAdjustmentPointYValue(1);
980  auto aHeadFromNeck = GetAdjustmentPointYValue(2);
981  if (!aBoxWidth.nCurrVal.has_value() || !aBoxWidth.nMaxVal.has_value()
982  || !aBoxWidth.nMinVal.has_value() || !aNeckLength.nCurrVal.has_value()
983  || !aNeckLength.nMaxVal.has_value() || !aNeckLength.nMinVal.has_value()
984  || !aNeckFromBox.nCurrVal.has_value() || !aNeckFromBox.nMaxVal.has_value()
985  || !aNeckFromBox.nMinVal.has_value() || !aHeadFromNeck.nCurrVal.has_value()
986  || !aHeadFromNeck.nMaxVal.has_value() || !aHeadFromNeck.nMinVal.has_value())
987  return false;
988 
990  false, false);
991  tools::Long nMaxVal1
992  = 100000 * m_xShape->getSize().Height
993  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
994  tools::Long nMaxVal2
995  = 50000 * m_xShape->getSize().Height
996  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
997  tools::Long nMaxVal3
998  = 100000 * m_xShape->getSize().Width
999  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1000  tools::Long nVal1
1001  = std::lround((*aNeckFromBox.nMaxVal - *aNeckFromBox.nCurrVal)
1002  / (*aNeckFromBox.nMaxVal - *aNeckFromBox.nMinVal) * nMaxVal1);
1003  tools::Long nVal2 = std::lround((10800 - *aHeadFromNeck.nCurrVal)
1004  / (10800 - *aHeadFromNeck.nMinVal) * nMaxVal2);
1005  tools::Long nVal3 = std::lround((*aNeckLength.nCurrVal - *aNeckLength.nMinVal)
1006  / (21600 - *aNeckLength.nMinVal) * nMaxVal3);
1007  tools::Long nVal4 = std::lround((*aBoxWidth.nMaxVal - *aBoxWidth.nCurrVal)
1008  / (*aBoxWidth.nMaxVal - *aBoxWidth.nMinVal) * 100000);
1009  return StartAVListWriting()
1010  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1011  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1012  && WriteAV(u"adj3", OUString(u"val " + OUString::number(nVal3)))
1013  && WriteAV(u"adj4", OUString(u"val " + OUString::number(nVal4)))
1014  && EndAVListWriting();
1015  }
1016  if (sShapeType == "leftBrace")
1017  {
1018  // TODO
1019  return false;
1020  }
1021  if (sShapeType == "leftBracket")
1022  {
1023  // TODO
1024  return false;
1025  }
1026  if (sShapeType == "leftCircularArrow")
1027  {
1028  // LO does not have this type, not necessary to map
1029  return false;
1030  }
1031  if (sShapeType == "leftRightArrow")
1032  {
1033  auto aPointX = GetAdjustmentPointXValue(0);
1034  auto aPointY = GetAdjustmentPointYValue(0);
1035  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
1036  || !aPointX.nMinVal.has_value() || !aPointY.nCurrVal.has_value()
1037  || !aPointY.nMaxVal.has_value() || !aPointY.nMinVal.has_value())
1038  return false;
1039 
1041  false, false);
1042  tools::Long nMaxVal1 = 100000;
1043  tools::Long nMaxVal2
1044  = 50000
1045  * (double(m_xShape->getSize().Width)
1046  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height));
1047  tools::Long nVal1 = std::lround((*aPointY.nMaxVal - *aPointY.nCurrVal)
1048  / (*aPointY.nMaxVal - *aPointY.nMinVal) * nMaxVal1);
1049  tools::Long nVal2 = std::lround((*aPointX.nCurrVal - *aPointX.nMinVal)
1050  / (*aPointX.nMaxVal - *aPointX.nMinVal) * nMaxVal2);
1051  return StartAVListWriting()
1052  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1053  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1054  && EndAVListWriting();
1055  }
1056  if (sShapeType == "leftRightArrowCallout")
1057  {
1058  auto aNeckFromBox = GetAdjustmentPointXValue(1);
1059  auto aHeadFromNeck = GetAdjustmentPointXValue(2);
1060  auto aHeadHeight = GetAdjustmentPointYValue(1);
1061  auto aBoxHeight = GetAdjustmentPointYValue(0);
1062  if (!aNeckFromBox.nCurrVal.has_value() || !aNeckFromBox.nMaxVal.has_value()
1063  || !aNeckFromBox.nMinVal.has_value() || !aHeadFromNeck.nCurrVal.has_value()
1064  || !aHeadFromNeck.nMaxVal.has_value() || !aHeadFromNeck.nMinVal.has_value()
1065  || !aHeadHeight.nCurrVal.has_value() || !aHeadHeight.nMaxVal.has_value()
1066  || !aHeadHeight.nMinVal.has_value() || !aBoxHeight.nCurrVal.has_value()
1067  || !aBoxHeight.nMaxVal.has_value() || !aBoxHeight.nMinVal.has_value())
1068  return false;
1069 
1071  false, false);
1072  tools::Long nMaxVal1
1073  = 100000 * m_xShape->getSize().Width
1074  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1075  tools::Long nMaxVal2
1076  = 50000 * m_xShape->getSize().Width
1077  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1078  tools::Long nMaxVal3
1079  = 100000 * m_xShape->getSize().Height
1080  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1081  tools::Long nVal1
1082  = std::lround((*aNeckFromBox.nMaxVal - *aNeckFromBox.nCurrVal)
1083  / (*aNeckFromBox.nMaxVal - *aNeckFromBox.nMinVal) * nMaxVal1);
1084  tools::Long nVal2 = std::lround((10800 - *aHeadFromNeck.nCurrVal)
1085  / (10800 - *aHeadFromNeck.nMinVal) * nMaxVal2);
1086  tools::Long nVal3 = std::lround((*aHeadHeight.nCurrVal - *aHeadHeight.nMinVal)
1087  / (21600 - *aHeadHeight.nMinVal) * nMaxVal3);
1088  tools::Long nVal4 = std::lround((*aBoxHeight.nCurrVal - *aBoxHeight.nMinVal)
1089  / (10800 - *aBoxHeight.nMinVal) * 100000);
1090  return StartAVListWriting()
1091  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1092  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1093  && WriteAV(u"adj3", OUString(u"val " + OUString::number(nVal3)))
1094  && WriteAV(u"adj4", OUString(u"val " + OUString::number(nVal4)))
1095  && EndAVListWriting();
1096  }
1097  if (sShapeType == "leftRightCircularArrow")
1098  {
1099  // Not found in word
1100  return false;
1101  }
1102  if (sShapeType == "leftRightRibbon")
1103  {
1104  // LO does not have this type so mapping not necessary
1105  return false;
1106  }
1107  if (sShapeType == "leftRightUpArrow")
1108  {
1109  // TODO?
1110  // MS Word stretches the arrow to fit the bounding box; LO doesn't
1111  return false;
1112  }
1113  if (sShapeType == "leftUpArrow")
1114  {
1115  // MS Word's and LO's interpretations of what a leftUpArrow should look like
1116  // are too different to find a compromise :(
1117  }
1118  if (sShapeType == "lightningBolt")
1119  {
1120  // Difference between the SDR and OOXML variants, custgeom?
1121  return false;
1122  }
1123  if (sShapeType == "line")
1124  {
1125  // Not necessary
1126  return false;
1127  }
1128  if (sShapeType == "lineInv")
1129  {
1130  // Not necessary
1131  return false;
1132  }
1133  if (sShapeType == "mathDivide")
1134  {
1135  // LO does not have this type so mapping not necessary
1136  return false;
1137  }
1138  if (sShapeType == "mathEqual")
1139  {
1140  // LO does not have this type so mapping not necessary
1141  return false;
1142  }
1143  if (sShapeType == "mathMinus")
1144  {
1145  // LO does not have this type so mapping not necessary
1146  return false;
1147  }
1148  if (sShapeType == "mathMultiply")
1149  {
1150  // LO does not have this type so mapping not necessary
1151  return false;
1152  }
1153  if (sShapeType == "mathNotEqual")
1154  {
1155  // LO does not have this type so mapping not necessary
1156  return false;
1157  }
1158  if (sShapeType == "mathPlus")
1159  {
1160  // LO does not have this type so mapping not necessary
1161  return false;
1162  }
1163  if (sShapeType == "nonIsoscelesTrapezoid")
1164  {
1165  // TODO
1166  return false;
1167  }
1168  if (sShapeType == "noSmoking")
1169  {
1170  // TODO
1171  return false;
1172  }
1173  if (sShapeType == "notchedRightArrow")
1174  {
1175  // TODO
1176  return false;
1177  }
1178  if (sShapeType == "octagon")
1179  {
1180  auto aPoint1 = GetAdjustmentPointXValue(0);
1181  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
1182  || !aPoint1.nMinVal.has_value())
1183  return false;
1184 
1186  false, false);
1187  tools::Long nVal1
1188  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * 50000);
1189  return StartAVListWriting()
1190  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
1191  && EndAVListWriting();
1192  }
1193  if (sShapeType == "parallelogram")
1194  {
1195  auto aPoint1 = GetAdjustmentPointXValue(0);
1196  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
1197  || !aPoint1.nMinVal.has_value())
1198  return false;
1199 
1201  false, false);
1202  tools::Long nMaxVal = 100000 * m_xShape->getSize().Width
1203  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1204  tools::Long nVal1
1205  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * nMaxVal);
1206  return StartAVListWriting()
1207  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
1208  && EndAVListWriting();
1209  }
1210  if (sShapeType == "pentagon")
1211  {
1212  // TODO
1213  return false;
1214  }
1215  if (sShapeType == "pie")
1216  {
1217  // TODO
1218  return false;
1219  }
1220  if (sShapeType == "pieWedge")
1221  {
1222  // Not found in word.
1223  return false;
1224  }
1225  if (sShapeType == "plaque")
1226  {
1227  // TODO
1228  return false;
1229  }
1230  if (sShapeType == "plaqueTabs")
1231  {
1232  // LO does not have this, so not necessary to map.
1233  return false;
1234  }
1235  if (sShapeType == "plus")
1236  {
1237  auto aPoint1 = GetAdjustmentPointXValue(0);
1238  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
1239  || !aPoint1.nMinVal.has_value())
1240  return false;
1241 
1243  false, false);
1244  tools::Long nVal1
1245  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * 50000);
1246  return StartAVListWriting()
1247  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
1248  && EndAVListWriting();
1249  }
1250  if (sShapeType == "quadArrow")
1251  {
1252  // TODO
1253  return false;
1254  }
1255  if (sShapeType == "quadArrowCallout")
1256  {
1257  // TODO
1258  return false;
1259  }
1260  if (sShapeType == "rect")
1261  {
1262  // preset enough without AV points.
1263  return false;
1264  }
1265  if (sShapeType == "ribbon")
1266  {
1267  // LO does not have this, so not necessary to map.
1268  return false;
1269  }
1270  if (sShapeType == "ribbon2")
1271  {
1272  // LO does not have this, so not necessary to map.
1273  return false;
1274  }
1275  if (sShapeType == "rightArrow")
1276  {
1277  auto aPointX = GetAdjustmentPointXValue(0);
1278  auto aPointY = GetAdjustmentPointYValue(0);
1279  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
1280  || !aPointX.nMinVal.has_value() || !aPointY.nCurrVal.has_value()
1281  || !aPointY.nMaxVal.has_value() || !aPointY.nMinVal.has_value())
1282  return false;
1283 
1285  false, false);
1286  tools::Long nMaxVal1 = 100000;
1287  tools::Long nMaxVal2
1288  = 100000
1289  * (double(m_xShape->getSize().Width)
1290  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height));
1291  tools::Long nVal1 = std::lround((*aPointY.nMaxVal - *aPointY.nCurrVal)
1292  / (*aPointY.nMaxVal - *aPointY.nMinVal) * nMaxVal1);
1293  tools::Long nVal2 = std::lround((*aPointX.nMaxVal - *aPointX.nCurrVal)
1294  / (*aPointX.nMaxVal - *aPointX.nMinVal) * nMaxVal2);
1295  return StartAVListWriting()
1296  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1297  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1298  && EndAVListWriting();
1299  }
1300  if (sShapeType == "rightArrowCallout")
1301  {
1302  auto aBoxWidth = GetAdjustmentPointXValue(0);
1303  auto aNeckLength = GetAdjustmentPointXValue(1);
1304  auto aNeckFromBox = GetAdjustmentPointYValue(1);
1305  auto aHeadFromNeck = GetAdjustmentPointYValue(2);
1306  if (!aBoxWidth.nCurrVal.has_value() || !aBoxWidth.nMaxVal.has_value()
1307  || !aBoxWidth.nMinVal.has_value() || !aNeckLength.nCurrVal.has_value()
1308  || !aNeckLength.nMaxVal.has_value() || !aNeckLength.nMinVal.has_value()
1309  || !aNeckFromBox.nCurrVal.has_value() || !aNeckFromBox.nMaxVal.has_value()
1310  || !aNeckFromBox.nMinVal.has_value() || !aHeadFromNeck.nCurrVal.has_value()
1311  || !aHeadFromNeck.nMaxVal.has_value() || !aHeadFromNeck.nMinVal.has_value())
1312  return false;
1313 
1315  false, false);
1316  tools::Long nMaxVal1
1317  = 100000 * m_xShape->getSize().Height
1318  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1319  tools::Long nMaxVal2
1320  = 50000 * m_xShape->getSize().Height
1321  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1322  tools::Long nMaxVal3
1323  = 100000 * m_xShape->getSize().Width
1324  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1325  tools::Long nVal1
1326  = std::lround((*aNeckFromBox.nMaxVal - *aNeckFromBox.nCurrVal)
1327  / (*aNeckFromBox.nMaxVal - *aNeckFromBox.nMinVal) * nMaxVal1);
1328  tools::Long nVal2 = std::lround((10800 - *aHeadFromNeck.nCurrVal)
1329  / (10800 - *aHeadFromNeck.nMinVal) * nMaxVal2);
1330  tools::Long nVal3
1331  = std::lround((*aNeckLength.nMaxVal - *aNeckLength.nCurrVal)
1332  / (*aNeckLength.nMaxVal - *aNeckLength.nMinVal) * nMaxVal3);
1333  tools::Long nVal4 = std::lround((*aBoxWidth.nCurrVal - *aBoxWidth.nMinVal)
1334  / (21600 - *aBoxWidth.nMinVal) * 100000);
1335  return StartAVListWriting()
1336  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1337  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1338  && WriteAV(u"adj3", OUString(u"val " + OUString::number(nVal3)))
1339  && WriteAV(u"adj4", OUString(u"val " + OUString::number(nVal4)))
1340  && EndAVListWriting();
1341  }
1342  if (sShapeType == "rightBrace")
1343  {
1344  // TODO
1345  return false;
1346  }
1347  if (sShapeType == "rightBracket")
1348  {
1349  // TODO
1350  return false;
1351  }
1352  if (sShapeType == "round1Rect")
1353  {
1354  // LO does not have this, so not necessary to map.
1355  return false;
1356  }
1357  if (sShapeType == "round2DiagRect")
1358  {
1359  // LO does not have this, so not necessary to map.
1360  return false;
1361  }
1362  if (sShapeType == "round2SameRect")
1363  {
1364  // LO does not have this, so not necessary to map.
1365  return false;
1366  }
1367  if (sShapeType == "roundRect")
1368  {
1369  tools::Long nVal1 = 0;
1370  if (m_xShape->getSize().Width >= m_xShape->getSize().Height)
1371  {
1372  auto aPointX = GetAdjustmentPointXValue(0);
1373  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
1374  || !aPointX.nMinVal.has_value())
1375  return false;
1376  nVal1 = std::lround(*aPointX.nCurrVal / (*aPointX.nMaxVal - *aPointX.nMinVal)
1377  * 50000);
1378  }
1379  else
1380  {
1381  auto aPointY = GetAdjustmentPointYValue(0);
1382  if (!aPointY.nCurrVal.has_value() || !aPointY.nMaxVal.has_value()
1383  || !aPointY.nMinVal.has_value())
1384  return false;
1385  nVal1 = std::lround(*aPointY.nCurrVal / (*aPointY.nMaxVal - *aPointY.nMinVal)
1386  * 50000);
1387  }
1388 
1390  false, false);
1391  return StartAVListWriting()
1392  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
1393  && EndAVListWriting();
1394  }
1395  if (sShapeType == "rtTriangle")
1396  {
1397  // Does not have AV points not necessary to map
1398  return false;
1399  }
1400  if (sShapeType == "smileyFace")
1401  {
1402  // TODO
1403  return false;
1404  }
1405  if (sShapeType == "snip1Rect")
1406  {
1407  // LO does not have this, so not necessary to map.
1408  return false;
1409  }
1410  if (sShapeType == "snip2DiagRect")
1411  {
1412  // LO does not have this, so not necessary to map.
1413  return false;
1414  }
1415  if (sShapeType == "snip2SameRect")
1416  {
1417  // LO does not have this, so not necessary to map.
1418  return false;
1419  }
1420  if (sShapeType == "snipRoundRect")
1421  {
1422  // LO does not have this, so not necessary to map.
1423  return false;
1424  }
1425  if (sShapeType == "squareTabs")
1426  {
1427  // LO does not have this, so not necessary to map.
1428  return false;
1429  }
1430  if (sShapeType == "star10")
1431  {
1432  // LO does not have this, so not necessary to map.
1433  return false;
1434  }
1435  if (sShapeType == "star12")
1436  {
1437  // TODO
1438  return false;
1439  }
1440  if (sShapeType == "star16")
1441  {
1442  // LO does not have this, so not necessary to map.
1443  return false;
1444  }
1445  if (sShapeType == "star24")
1446  {
1447  // TODO
1448  return false;
1449  }
1450  if (sShapeType == "star32")
1451  {
1452  // LO does not have this, so not necessary to map.
1453  return false;
1454  }
1455  if (sShapeType == "star4")
1456  {
1457  // TODO
1458  return false;
1459  }
1460  if (sShapeType == "star5")
1461  {
1462  // TODO
1463  return false;
1464  }
1465  if (sShapeType == "star6")
1466  {
1467  // TODO
1468  return false;
1469  }
1470  if (sShapeType == "star7")
1471  {
1472  // LO does not have this, so not necessary to map.
1473  return false;
1474  }
1475  if (sShapeType == "star8")
1476  {
1477  // TODO
1478  return false;
1479  }
1480  if (sShapeType == "straightConnector1")
1481  {
1482  // Not necessary to map.
1483  return false;
1484  }
1485  if (sShapeType == "stripedRightArrow")
1486  {
1487  // TODO
1488  return false;
1489  }
1490  if (sShapeType == "sun")
1491  {
1492  // TODO
1493  return false;
1494  }
1495  if (sShapeType == "swooshArrow")
1496  {
1497  // Not found in word.
1498  return false;
1499  }
1500  if (sShapeType == "teardrop")
1501  {
1502  // TODO
1503  return false;
1504  }
1505  if (sShapeType == "trapezoid")
1506  {
1507  // Preset enough.
1508  return false;
1509  }
1510  if (sShapeType == "triangle")
1511  {
1512  auto aPoint1 = GetAdjustmentPointXValue(0);
1513  if (!aPoint1.nCurrVal.has_value() || !aPoint1.nMaxVal.has_value()
1514  || !aPoint1.nMinVal.has_value())
1515  return false;
1516 
1518  false, false);
1519  tools::Long nMaxVal = 100000;
1520  tools::Long nVal1
1521  = std::lround(*aPoint1.nCurrVal / (*aPoint1.nMaxVal - *aPoint1.nMinVal) * nMaxVal);
1522  return StartAVListWriting()
1523  && WriteAV(u"adj", OUString(u"val " + OUString::number(nVal1)))
1524  && EndAVListWriting();
1525  }
1526  if (sShapeType == "upArrowCallout")
1527  {
1528  auto aNeckFromBox = GetAdjustmentPointXValue(1);
1529  auto aHeadFromNeck = GetAdjustmentPointXValue(2);
1530  auto aHeadHeight = GetAdjustmentPointYValue(1);
1531  auto aBoxHeight = GetAdjustmentPointYValue(0);
1532  if (!aNeckFromBox.nCurrVal.has_value() || !aNeckFromBox.nMaxVal.has_value()
1533  || !aNeckFromBox.nMinVal.has_value() || !aHeadFromNeck.nCurrVal.has_value()
1534  || !aHeadFromNeck.nMaxVal.has_value() || !aHeadFromNeck.nMinVal.has_value()
1535  || !aHeadHeight.nCurrVal.has_value() || !aHeadHeight.nMaxVal.has_value()
1536  || !aHeadHeight.nMinVal.has_value() || !aBoxHeight.nCurrVal.has_value()
1537  || !aBoxHeight.nMaxVal.has_value() || !aBoxHeight.nMinVal.has_value())
1538  return false;
1539 
1541  false, false);
1542  tools::Long nMaxVal1
1543  = 100000 * m_xShape->getSize().Width
1544  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1545  tools::Long nMaxVal2
1546  = 50000 * m_xShape->getSize().Width
1547  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1548  tools::Long nMaxVal3
1549  = 100000 * m_xShape->getSize().Height
1550  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1551  tools::Long nVal1
1552  = std::lround((*aNeckFromBox.nMaxVal - *aNeckFromBox.nCurrVal)
1553  / (*aNeckFromBox.nMaxVal - *aNeckFromBox.nMinVal) * nMaxVal1);
1554  tools::Long nVal2 = std::lround((10800 - *aHeadFromNeck.nCurrVal)
1555  / (10800 - *aHeadFromNeck.nMinVal) * nMaxVal2);
1556  tools::Long nVal3 = std::lround((*aHeadHeight.nCurrVal - *aHeadHeight.nMinVal)
1557  / (21600 - *aHeadHeight.nMinVal) * nMaxVal3);
1558  tools::Long nVal4 = std::lround((*aBoxHeight.nCurrVal - *aBoxHeight.nMinVal)
1559  / (10800 - *aBoxHeight.nMinVal) * 100000);
1560  return StartAVListWriting()
1561  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1562  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1563  && WriteAV(u"adj3", OUString(u"val " + OUString::number(nVal3)))
1564  && WriteAV(u"adj4", OUString(u"val " + OUString::number(nVal4)))
1565  && EndAVListWriting();
1566  }
1567  if (sShapeType == "upDownArrow")
1568  {
1569  auto aPointX = GetAdjustmentPointXValue(0);
1570  auto aPointY = GetAdjustmentPointYValue(0);
1571  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
1572  || !aPointX.nMinVal.has_value() || !aPointY.nCurrVal.has_value()
1573  || !aPointY.nMaxVal.has_value() || !aPointY.nMinVal.has_value())
1574  return false;
1575 
1577  false, false);
1578  tools::Long nMaxVal1 = 100000;
1579  tools::Long nMaxVal2
1580  = 50000 * m_xShape->getSize().Height
1581  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1582  tools::Long nVal1 = std::lround((*aPointX.nMaxVal - *aPointX.nCurrVal)
1583  / (*aPointX.nMaxVal - *aPointX.nMinVal) * nMaxVal1);
1584  tools::Long nVal2 = std::lround((*aPointY.nCurrVal - *aPointY.nMinVal)
1585  / (*aPointY.nMaxVal - *aPointY.nMinVal) * nMaxVal2);
1586  return StartAVListWriting()
1587  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1588  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1589  && EndAVListWriting();
1590  }
1591  if (sShapeType == "upArrow")
1592  {
1593  auto aPointX = GetAdjustmentPointXValue(0);
1594  auto aPointY = GetAdjustmentPointYValue(0);
1595  if (!aPointX.nCurrVal.has_value() || !aPointX.nMaxVal.has_value()
1596  || !aPointX.nMinVal.has_value() || !aPointY.nCurrVal.has_value()
1597  || !aPointY.nMaxVal.has_value() || !aPointY.nMinVal.has_value())
1598  return false;
1599 
1601  false, false);
1602  tools::Long nMaxVal1 = 100000;
1603  tools::Long nMaxVal2
1604  = 100000 * m_xShape->getSize().Height
1605  / std::min(m_xShape->getSize().Width, m_xShape->getSize().Height);
1606  tools::Long nVal1 = std::lround((*aPointX.nMaxVal - *aPointX.nCurrVal)
1607  / (*aPointX.nMaxVal - *aPointX.nMinVal) * nMaxVal1);
1608  tools::Long nVal2 = std::lround((*aPointY.nCurrVal - *aPointY.nMinVal)
1609  / (*aPointY.nMaxVal - *aPointY.nMinVal) * nMaxVal2);
1610  return StartAVListWriting()
1611  && WriteAV(u"adj1", OUString(u"val " + OUString::number(nVal1)))
1612  && WriteAV(u"adj2", OUString(u"val " + OUString::number(nVal2)))
1613  && EndAVListWriting();
1614  }
1615  if (sShapeType == "upDownArrowCallout")
1616  {
1617  // TODO
1618  return false;
1619  }
1620  if (sShapeType == "uturnArrow")
1621  {
1622  // LO does not have like this.
1623  return false;
1624  }
1625  if (sShapeType == "verticalScroll")
1626  {
1627  // TODO
1628  return false;
1629  }
1630  if (sShapeType == "wave")
1631  {
1632  // LO does not have.
1633  return false;
1634  }
1635  if (sShapeType == "wedgeEllipseCallout")
1636  {
1637  // TODO
1638  return false;
1639  }
1640  if (sShapeType == "wedgeRectCallout")
1641  {
1642  // TODO
1643  return false;
1644  }
1645  if (sShapeType == "wedgeRoundRectCallout")
1646  {
1647  // TODO
1648  return false;
1649  }
1650  }
1651  catch (...)
1652  {
1653  // Problem detected with the writing, aborting and trying to find another way.
1654  return false;
1655  }
1656 
1657  // Default, nothing happened return.
1658  return false;
1659 };
1660 }
css::uno::Sequence< css::drawing::EnhancedCustomShapeAdjustmentValue > m_AdjustmentValues
css::uno::Reference< css::drawing::XShape > m_xShape
const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > & GetHandleValues() const
css::uno::Any GetHandleValueOfModificationPoint(sal_Int32 nPoint, std::u16string_view sType)
const css::uno::Sequence< css::drawing::EnhancedCustomShapeAdjustmentValue > & GetAdjustmentValues() const
void WriteShapeTransformation(const css::uno::Reference< css::drawing::XShape > &rXShape, sal_Int32 nXmlNamespace, bool bFlipH=false, bool bFlipV=false, bool bSuppressRotation=false, bool bSuppressFlipping=false, bool bFlippedBeforeRotation=false)
Definition: drawingml.cxx:1771
long Long
OUString Name
Value
const ::sax_fastparser::FSHelperPtr & GetFS() const
Definition: drawingml.hxx:207
XAdjustmentValue GetAdjustmentPointXValue(sal_Int32 nPoint)
YAdjustmentValue GetAdjustmentPointYValue(sal_Int32 nPoint)
const char * GetOOXMLPresetGeometry(const char *sShapeType)
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > m_HandleValues
float u
RadiusAdjustmentValue GetAdjustmentPointRadiusValue(sal_Int32 nPoint)
double getLength(const B2DPolygon &rCandidate)
AngleAdjustmentValue GetAdjustmentPointAngleValue(sal_Int32 nPoint)
bool WriteAV(const OUString &sValName, const OUString &sVal)
void WritePresetShape(const char *pShape, std::vector< std::pair< sal_Int32, sal_Int32 >> &rAvList)
Definition: drawingml.cxx:3502