1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* MWAWImportFilter: Sets up the filter, and calls DocumentCollector
3 * to do the actual filtering
5 * This file is part of the LibreOffice project.
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 #include <osl/diagnose.h>
13 #include <rtl/tencinfo.h>
15 #include <com/sun/star/io/XInputStream.hpp>
16 #include <com/sun/star/xml/sax/XAttributeList.hpp>
17 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
18 #include <com/sun/star/xml/sax/InputSource.hpp>
19 #include <com/sun/star/xml/sax/XParser.hpp>
20 #include <com/sun/star/io/XSeekable.hpp>
21 #include <com/sun/star/uno/Reference.h>
23 #include <comphelper/componentcontext.hxx>
24 #include <xmloff/attrlist.hxx>
25 #include <ucbhelper/content.hxx>
27 #include <libmwaw/libmwaw.hxx>
28 #include <libodfgen/libodfgen.hxx>
30 #include "common/DocumentHandler.hxx"
31 #include "common/WPXSvStream.hxx"
32 #include "MWAWImportFilter.hxx"
36 using namespace ::com::sun::star::uno
;
37 using com::sun::star::uno::Sequence
;
38 using com::sun::star::uno::Reference
;
39 using com::sun::star::uno::Any
;
40 using com::sun::star::uno::UNO_QUERY
;
41 using com::sun::star::uno::XInterface
;
42 using com::sun::star::uno::Exception
;
43 using com::sun::star::uno::RuntimeException
;
44 using com::sun::star::beans::PropertyValue
;
45 using com::sun::star::document::XFilter
;
46 using com::sun::star::document::XExtendedFilterDetection
;
47 using com::sun::star::ucb::XCommandEnvironment
;
49 using com::sun::star::io::XInputStream
;
50 using com::sun::star::document::XImporter
;
51 using com::sun::star::xml::sax::InputSource
;
52 using com::sun::star::xml::sax::XAttributeList
;
53 using com::sun::star::xml::sax::XDocumentHandler
;
54 using com::sun::star::xml::sax::XParser
;
59 //! Internal: creates the string "f pt"
60 static std::string
getStringPt(double f
)
63 s
<< float(f
) << "pt";
67 static double getSizeInPt(WPXProperty
const &prop
)
69 WPXString str
= prop
.getStr();
70 if (!str
.len()) return 0.0;
72 // we have a string, so we can not use getDouble
73 std::istringstream
iss(str
.cstr());
77 // try to guess the type
78 // point->pt, twip->*, inch -> in
79 char c
= str
.len() ? str
.cstr()[str
.len()-1] : ' ';
80 if (c
== '*') res
/= 1440.;
81 else if (c
== 't') res
/= 72.;
85 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::getSizeInPoint: called with a percent property");
90 static std::string
getStringSizeInPt(WPXProperty
const &prop
)
92 return getStringPt(getSizeInPt(prop
));
95 static std::string
getStyleName(int id
)
103 } // anonymous namespace
105 namespace MWAWObjectHandlerInternal
110 Shape() : m_type(BAD
), m_styleId(-1), m_w(0), m_h(0), m_rw(0), m_rh(0),
111 m_x(), m_y(), m_angle(), m_path("")
114 bool read(const char *psName
, WPXPropertyList
const &xPropList
, int styleId
);
115 bool write(OdfDocumentHandler
*output
) const;
118 return m_type
!= BAD
;
122 bool drawLine(OdfDocumentHandler
*output
) const;
123 bool drawRectangle(OdfDocumentHandler
*output
) const;
124 bool drawCircle(OdfDocumentHandler
*output
) const;
125 bool drawArc(OdfDocumentHandler
*output
) const;
126 bool drawPath(OdfDocumentHandler
*output
) const;
127 bool drawPolygon(OdfDocumentHandler
*output
, bool is2D
) const;
129 enum Type
{ LINE
, RECTANGLE
, CIRCLE
, ARC
, PATH
, POLYLINE
, POLYGON
, BAD
} m_type
;
132 double m_w
,m_h
, m_rw
, m_rh
;
133 std::vector
<double> m_x
,m_y
;
134 std::vector
<double> m_angle
;
141 Document() : styles(), shapes(), m_w(0.0), m_h(0.0) {}
142 bool open(const char *psName
, WPXPropertyList
const &xPropList
);
143 bool close(const char *psName
);
145 void characters(WPXString
const &sCharacters
);
147 void write(OdfDocumentHandler
*output
);
150 static void writeStyle(OdfDocumentHandler
*output
,
151 WPXPropertyList
const &style
, int styleId
);
153 std::vector
<WPXPropertyList
> styles
;
154 std::vector
<Shape
> shapes
;
162 class MWAWObjectHandler
: public MWAWPropertyHandler
165 MWAWObjectHandler(OdfDocumentHandler
*output
) : MWAWPropertyHandler(), m_document(), m_output(output
) { }
166 ~MWAWObjectHandler() {};
170 m_document
= MWAWObjectHandlerInternal::Document();
174 if (m_output
) m_document
.write(m_output
);
177 void startElement(const char *psName
, const WPXPropertyList
&xPropList
)
179 m_document
.open(psName
, xPropList
);
181 void endElement(const char *psName
)
183 m_document
.close(psName
);
185 void characters(const WPXString
&sCharacters
)
187 m_document
.characters(sCharacters
);
191 MWAWObjectHandler(MWAWObjectHandler
const &);
192 MWAWObjectHandler
operator=(MWAWObjectHandler
const &);
194 MWAWObjectHandlerInternal::Document m_document
;
195 OdfDocumentHandler
*m_output
;
199 static bool handleEmbeddedMWAWObject(const WPXBinaryData
&data
, OdfDocumentHandler
*pHandler
, const OdfStreamType
)
201 MWAWObjectHandler
tmpHandler(pHandler
);
202 tmpHandler
.startDocument();
203 if (!tmpHandler
.checkData(data
) || !tmpHandler
.readData(data
)) return false;
204 tmpHandler
.endDocument();
208 bool MWAWObjectHandlerInternal::Shape::read(const char *psName
, WPXPropertyList
const &xPropList
, int stylId
)
212 if (strcmp(psName
,"drawLine")==0) m_type
= LINE
;
213 else if (strcmp(psName
,"drawRectangle")==0) m_type
= RECTANGLE
;
214 else if (strcmp(psName
,"drawCircle")==0) m_type
= CIRCLE
;
215 else if (strcmp(psName
,"drawArc")==0) m_type
= ARC
;
216 else if (strcmp(psName
,"drawPath")==0) m_type
= PATH
;
217 else if (strcmp(psName
,"drawPolyline")==0) m_type
= POLYLINE
;
218 else if (strcmp(psName
,"drawPolygon")==0) m_type
= POLYGON
;
221 WPXPropertyList::Iter
i(xPropList
);
222 for (i
.rewind(); i
.next(); )
224 if (strcmp(i
.key(), "w") == 0) m_w
= getSizeInPt(*i());
225 else if (strcmp(i
.key(), "h") == 0) m_h
= getSizeInPt(*i());
226 else if (strcmp(i
.key(), "rw") == 0) m_rw
= getSizeInPt(*i());
227 else if (strcmp(i
.key(), "rh") == 0) m_rh
= getSizeInPt(*i());
228 else if (strcmp(i
.key(), "path") == 0)
230 if (i()->getStr().len())
231 m_path
= i()->getStr().cstr();
235 char const *key
= i
.key();
236 int len
= (int) strlen(key
);
237 bool readOk
= len
> 1, generic
= false;
238 std::vector
<double> *which
= 0L;
239 if (readOk
&& strncmp(i
.key(),"x",1)==0)
244 else if (readOk
&& strncmp(i
.key(),"y",1)==0)
249 else if (readOk
&& strncmp(i
.key(),"angle",5)==0)
262 w
= strtol(key
, &res
, 10);
263 readOk
= (*res
=='\0') && (w
>= 0);
267 if (int(which
->size()) < w
+1) which
->resize(size_t(w
)+1,0.0);
268 double unit
= generic
? 1./72.0 : 1.0;
269 (*which
)[size_t(w
)] = getSizeInPt(*i()) * unit
;
273 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::read: find an unknown key '" << i
.key() << "'");
281 bool MWAWObjectHandlerInternal::Shape::write(OdfDocumentHandler
*output
) const
283 if (!output
) return true;
284 if (m_type
== LINE
) return drawLine(output
);
285 else if (m_type
== RECTANGLE
) return drawRectangle(output
);
286 else if (m_type
== CIRCLE
) return drawCircle(output
);
287 else if (m_type
== ARC
) return drawArc(output
);
288 else if (m_type
== PATH
) return drawPath(output
);
289 else if (m_type
== POLYLINE
) return drawPolygon(output
, false);
290 else if (m_type
== POLYGON
) return drawPolygon(output
, true);
295 bool MWAWObjectHandlerInternal::Shape::drawLine(OdfDocumentHandler
*output
) const
297 if (m_x
.size() < 2 || m_y
.size() < 2)
299 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawLine: PB");
303 WPXPropertyList list
;
304 list
.insert("draw:text-style-name","P1");
305 list
.insert("draw:layer","layout");
306 list
.insert("draw:style-name",getStyleName(m_styleId
).c_str());
307 list
.insert("svg:x1",getStringPt(m_x
[0]).c_str());
308 list
.insert("svg:y1",getStringPt(m_y
[0]).c_str());
309 list
.insert("svg:x2",getStringPt(m_x
[1]).c_str());
310 list
.insert("svg:y2",getStringPt(m_y
[1]).c_str());
311 output
->startElement("draw:line", list
);
312 output
->endElement("draw:line");
316 bool MWAWObjectHandlerInternal::Shape::drawRectangle(OdfDocumentHandler
*output
) const
318 if (m_x
.size() < 1 || m_y
.size() < 1)
320 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawRectangle: PB");
324 WPXPropertyList list
;
325 list
.insert("draw:text-style-name","P1");
326 list
.insert("draw:layer","layout");
327 list
.insert("draw:style-name",getStyleName(m_styleId
).c_str());
328 list
.insert("svg:x",getStringPt(m_x
[0]).c_str());
329 list
.insert("svg:y",getStringPt(m_y
[0]).c_str());
330 list
.insert("svg:width",getStringPt(m_w
).c_str());
331 list
.insert("svg:height",getStringPt(m_h
).c_str());
333 if (m_rw
<= 0.0 || m_rh
<= 0.0 || m_w
< 2*m_rw
|| m_h
< 2*m_rh
)
335 if (m_rw
> 0.0 || m_rh
> 0.0)
337 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawRectangle:: can only create a rectangle");
339 output
->startElement("draw:rect", list
);
340 output
->endElement("draw:rect");
344 // ok, we draw a rond rect
346 float const unit
= 1.0;//35.3;
349 double const minPt
[] = { m_x
[0] *unit
, m_y
[0] *unit
};
350 double const maxPt
[] = { (m_w
+m_x
[0]) *unit
, (m_h
+m_y
[0]) *unit
};
352 s
<< "0 0 " << int(maxPt
[0]) << " " << int(maxPt
[1]);
353 list
.insert("svg:viewBox", s
.str().c_str());
355 double const W
[] = { m_rw
*unit
, m_rh
*unit
};
356 double const xPt
[] = { minPt
[0]+W
[0], maxPt
[0]-W
[0], maxPt
[0],
357 maxPt
[0], maxPt
[0], maxPt
[0],
358 maxPt
[0]-W
[0], minPt
[0]+W
[0], minPt
[0],
359 minPt
[0], minPt
[0], minPt
[0],
362 double const yPt
[] = { minPt
[1], minPt
[1], minPt
[1],
363 minPt
[1]+W
[1], maxPt
[1]-W
[1], maxPt
[1],
364 maxPt
[1], maxPt
[1], maxPt
[1],
365 maxPt
[1]-W
[1], minPt
[1]+W
[1], minPt
[1],
369 for (int i
= 0; i
< 13; i
++)
373 if (i
== 0) s
<< "M";
374 else if ((i
%3) == 2) s
<< "Q";
375 else if ((i
%3) == 0);
377 s
<< int(xPt
[i
]) << " " << int(yPt
[i
]);
380 list
.insert("svg:d", s
.str().c_str());
382 output
->startElement("draw:path", list
);
383 output
->endElement("draw:path");
387 bool MWAWObjectHandlerInternal::Shape::drawCircle(OdfDocumentHandler
*output
) const
389 if (m_x
.size() < 1 || m_y
.size() < 1)
391 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawCircle: PB");
395 WPXPropertyList list
;
396 list
.insert("draw:text-style-name","P1");
397 list
.insert("draw:layer","layout");
398 list
.insert("draw:style-name",getStyleName(m_styleId
).c_str());
399 list
.insert("svg:x",getStringPt(m_x
[0]).c_str());
400 list
.insert("svg:y",getStringPt(m_y
[0]).c_str());
401 list
.insert("svg:width",getStringPt(m_w
).c_str());
402 list
.insert("svg:height",getStringPt(m_h
).c_str());
403 if (m_w
< m_h
|| m_w
> m_h
)
405 output
->startElement("draw:ellipse", list
);
406 output
->endElement("draw:ellipse");
410 output
->startElement("draw:circle", list
);
411 output
->endElement("draw:circle");
416 bool MWAWObjectHandlerInternal::Shape::drawArc(OdfDocumentHandler
*output
) const
418 if (m_angle
.size() < 2)
420 SAL_INFO("writerperfect", "MWAWObjectHandlerInternal::Shape::drawArc: angle are filled, call draw Circle");
421 return drawCircle(output
);
423 if (m_x
.size() < 1 || m_y
.size() < 1)
425 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawArc: PB");
429 WPXPropertyList list
;
430 list
.insert("draw:text-style-name","P1");
431 list
.insert("draw:layer","layout");
432 list
.insert("draw:style-name",getStyleName(m_styleId
).c_str());
433 list
.insert("svg:x",getStringPt(m_x
[0]).c_str());
434 list
.insert("svg:y",getStringPt(m_y
[0]).c_str());
435 list
.insert("svg:width",getStringPt(m_w
).c_str());
436 list
.insert("svg:height",getStringPt(m_h
).c_str());
437 list
.insert("draw:kind","arc");
440 // odg prefers angle between -360 and +360, ...
441 int minAngl
= int(m_angle
[0]), maxAngl
= int(m_angle
[1]);
442 if (minAngl
>= 360 || maxAngl
>= 360)
449 list
.insert("draw:start-angle", s
.str().c_str());
452 list
.insert("draw:end-angle", s
.str().c_str());
454 if (m_w
< m_h
|| m_w
> m_h
)
456 output
->startElement("draw:ellipse", list
);
457 output
->endElement("draw:ellipse");
461 output
->startElement("draw:circle", list
);
462 output
->endElement("draw:circle");
467 bool MWAWObjectHandlerInternal::Shape::drawPolygon(OdfDocumentHandler
*output
, bool is2D
) const
469 if (m_x
.size() < 1 || m_y
.size() != m_x
.size())
471 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawPolygon: PB");
475 WPXPropertyList list
;
476 list
.insert("draw:text-style-name","P1");
477 list
.insert("draw:layer","layout");
478 list
.insert("draw:style-name","bd1");
479 list
.insert("svg:x","0pt");
480 list
.insert("svg:y","0pt");
481 list
.insert("svg:width",getStringPt(m_w
).c_str());
482 list
.insert("svg:height",getStringPt(m_h
).c_str());
484 size_t numPt
= m_x
.size();
486 float const unit
= 1; //35.2777; // convert in centimeters
488 s
<< "0 0 " << int(m_w
*unit
) << " " << int(m_h
*unit
);
489 list
.insert("svg:viewBox", s
.str().c_str());
492 for (size_t i
= 0; i
< numPt
; i
++)
495 s
<< int(m_x
[i
]*unit
) << "," << int(m_y
[i
]*unit
);
497 list
.insert("draw:points", s
.str().c_str());
500 output
->startElement("draw:polyline", list
);
501 output
->endElement("draw:polyline");
505 output
->startElement("draw:polygon", list
);
506 output
->endElement("draw:polygon");
511 bool MWAWObjectHandlerInternal::Shape::drawPath(OdfDocumentHandler
*output
) const
513 if (m_path
.length()==0 || m_w
<= 0 || m_h
<= 0)
515 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Shape::drawPath: PB");
519 WPXPropertyList list
;
520 list
.insert("draw:text-style-name","P1");
521 list
.insert("draw:layer","layout");
522 list
.insert("draw:style-name",getStyleName(m_styleId
).c_str());
523 list
.insert("svg:x","0pt");
524 list
.insert("svg:y","0pt");
525 list
.insert("svg:width",getStringPt(m_w
).c_str());
526 list
.insert("svg:height",getStringPt(m_h
).c_str());
528 s
<< "0 0 " << int(m_w
) << " " << int(m_h
);
529 list
.insert("svg:viewBox", s
.str().c_str());
530 list
.insert("svg:d",m_path
.c_str());
532 output
->startElement("draw:path", list
);
533 output
->endElement("draw:path");
538 bool MWAWObjectHandlerInternal::Document::open(const char *psName
, WPXPropertyList
const &xPropList
)
540 if (strncmp(psName
,"libmwaw:", 8) == 0)
544 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Document::open Unknown tag '" << psName
<< "'.." );
547 if (strcmp(psName
, "document") == 0)
550 WPXPropertyList::Iter
i(xPropList
);
551 for (i
.rewind(); i
.next(); )
553 if (strcmp(i
.key(), "w") == 0) m_w
= getSizeInPt(*i());
554 else if (strcmp(i
.key(), "h") == 0) m_h
= getSizeInPt(*i());
557 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Document::open: find an unknown key '" << i
.key() << "'");
562 else if (strcmp(psName
, "graphicStyle") == 0)
564 styles
.push_back(xPropList
);
569 int id
= int(styles
.size());
571 if (shape
.read(psName
, xPropList
, id
? id
-1 : 0))
575 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Document::open shape created without style..");
576 styles
.push_back(WPXPropertyList());
578 shapes
.push_back(shape
);
582 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Document::open Unknown tag '" << psName
<< "'..");
586 bool MWAWObjectHandlerInternal::Document::close(const char *)
591 void MWAWObjectHandlerInternal::Document::characters(WPXString
const &)
593 SAL_WARN("writerperfect", "Document::characters must NOT be called..");
596 void MWAWObjectHandlerInternal::Document::write(OdfDocumentHandler
*output
)
599 WPXPropertyList list
;
603 list
.insert("office:mimetype","application/vnd.oasis.opendocument.graphics");
604 list
.insert("office:version", "1.0");
606 list
.insert("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
607 list
.insert("xmlns:dc", "http://purl.org/dc/elements/1.1/");
608 list
.insert("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
609 list
.insert("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
610 list
.insert("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
611 list
.insert("xmlns:ooo", "http://openoffice.org/2004/office");
612 list
.insert("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
613 list
.insert("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
614 list
.insert("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
616 output
->startElement("office:document", list
);
621 output
->startElement("office:settings", list
);
623 list
.insert("config:name","ooo:view-settings");
624 output
->startElement("config:config-item-set", list
);
628 list
.insert("config:name","VisibleAreaTop");
629 list
.insert("config:type","int");
630 output
->startElement("config:config-item", list
);
631 output
->characters("0");
633 output
->endElement("config:config-item");
636 list
.insert("config:name","VisibleAreaLeft");
637 list
.insert("config:type","int");
638 output
->startElement("config:config-item", list
);
639 output
->characters("0");
640 output
->endElement("config:config-item");
643 list
.insert("config:name","VisibleAreaWidth");
644 list
.insert("config:type","int");
646 s
<< int(m_w
*35.2777); // *2540/72. why ?
647 output
->startElement("config:config-item", list
);
648 output
->characters(s
.str().c_str());
649 output
->endElement("config:config-item");
652 list
.insert("config:name","VisibleAreaHeight");
653 list
.insert("config:type","int");
655 s
<< int(m_h
*35.2777); // *2540/72. why ?
656 output
->startElement("config:config-item", list
);
657 output
->characters(s
.str().c_str());
658 output
->endElement("config:config-item");
660 output
->endElement("config:config-item-set");
661 output
->endElement("office:settings");
667 output
->startElement("office:styles", list
);
670 list
.insert("draw:angle","0");
671 list
.insert("draw:border","0%");
672 list
.insert("draw:end-color","#000000");
673 list
.insert("draw:end-intensity","100%");
674 list
.insert("draw:name","Gradient_1");
675 list
.insert("draw:start-color","#000000");
676 list
.insert("draw:start-intensity","100%");
677 list
.insert("draw:style","linear");
678 output
->startElement("draw:gradient", list
);
679 output
->endElement("draw:gradient");
682 list
.insert("draw:name","Arrow");
683 list
.insert("svg:viewBox","0 0 20 30");
684 list
.insert("svg:d","m10 0-10 30h20z");
685 output
->startElement("draw:marker", list
);
686 output
->endElement("draw:marker");
688 output
->endElement("office:styles");
694 output
->startElement("office:automatic-styles", list
);
699 list
.insert("style:name","PM0");
700 output
->startElement("style:page-layout", list
);
702 list
.insert("fo:margin-bottom","0in");
703 list
.insert("fo:margin-left","0in");
704 list
.insert("fo:margin-right","0in");
705 list
.insert("fo:margin-top","0in");
706 list
.insert("fo:page-height",getStringPt(m_h
).c_str());
707 list
.insert("fo:page-width",getStringPt(m_w
).c_str());
708 list
.insert("style:print-orientation","portrait");
709 output
->startElement("style:page-layout-properties", list
);
710 output
->endElement("style:page-layout-properties");
711 output
->endElement("style:page-layout");
717 list
.insert("style:family","drawing-page");
718 list
.insert("style:name","dp1");
719 output
->startElement("style:style", list
);
721 list
.insert("draw:fill","none");
722 output
->startElement("style:drawing-page-properties", list
);
723 output
->endElement("style:drawing-page-properties");
724 output
->endElement("style:style");
728 for (size_t i
= 0; i
< styles
.size() ; i
++)
729 writeStyle(output
, styles
[i
], int(i
));
731 output
->endElement("office:automatic-styles");
737 output
->startElement("office:master-styles", list
);
739 list
.insert("draw:style-name","dp1");
740 list
.insert("style:name","Default");
741 list
.insert("style:page-layout-name","PM0");
742 output
->startElement("style:master-page", list
);
743 output
->endElement("style:master-page");
744 output
->endElement("office:master-styles");
750 output
->startElement("office:body", list
);
751 output
->startElement("office:drawing", list
);
754 list
.insert("draw:master-page-name","Default");
755 list
.insert("draw:name","page1");
756 list
.insert("draw:style-name","dp1");
758 output
->startElement("draw:page", list
);
760 for (size_t i
= 0; i
< shapes
.size() ; i
++)
761 shapes
[i
].write(output
);
763 output
->endElement("draw:page");
765 output
->endElement("office:drawing");
766 output
->endElement("office:body");
768 output
->endElement("office:document");
771 void MWAWObjectHandlerInternal::Document::writeStyle (OdfDocumentHandler
*output
, WPXPropertyList
const &style
, int styleId
)
775 WPXPropertyList list
;
777 list
.insert("style:family","graphic");
778 list
.insert("style:name",getStyleName(styleId
).c_str());
779 list
.insert("style:parent-style-name","standard");
780 output
->startElement("style:style", list
);
784 WPXPropertyList::Iter
i(style
);
785 for (i
.rewind(); i
.next(); )
787 if (strcmp(i
.key(), "lineColor") == 0)
788 list
.insert("svg:stroke-color", i()->getStr().cstr());
789 else if (strcmp(i
.key(), "lineWidth") == 0)
790 list
.insert("svg:stroke-width", getStringSizeInPt(*i()).c_str());
791 else if (strcmp(i
.key(), "lineFill") == 0)
792 list
.insert("draw:stroke", i()->getStr().cstr());
793 else if (strcmp(i
.key(), "surfaceColor") == 0)
794 list
.insert("draw:fill-color", i()->getStr().cstr());
795 else if (strcmp(i
.key(), "surfaceFill") == 0)
796 list
.insert("draw:fill", i()->getStr().cstr());
797 else if (strcmp(i
.key(), "startArrow") == 0)
799 if (strcmp(i()->getStr().cstr(), "true") == 0)
801 list
.insert("draw:marker-start", "Arrow");
802 list
.insert("draw:marker-start-center", "false");
805 else if (strcmp(i
.key(), "startArrowWidth") == 0)
806 list
.insert("draw:marker-start-width", getStringSizeInPt(*i()).c_str());
807 else if (strcmp(i
.key(), "endArrow") == 0)
809 if (strcmp(i()->getStr().cstr(), "true") == 0)
811 list
.insert("draw:marker-end", "Arrow");
812 list
.insert("draw:marker-end-center", "false");
815 else if (strcmp(i
.key(), "endArrowWidth") == 0)
816 list
.insert("draw:marker-end-width", getStringSizeInPt(*i()).c_str());
819 SAL_WARN("writerperfect", "MWAWObjectHandlerInternal::Document::writeStyle: find an unknown key '" << i
.key() << "'");
823 output
->startElement("style:graphic-properties", list
);
824 output
->endElement("style:graphic-properties");
826 output
->endElement("style:style");
830 sal_Bool SAL_CALL
MWAWImportFilter::importImpl( const Sequence
< ::com::sun::star::beans::PropertyValue
> &aDescriptor
)
831 throw (RuntimeException
)
833 SAL_INFO("writerperfect", "MWAWImportFilter::importImpl");
835 sal_Int32 nLength
= aDescriptor
.getLength();
836 const PropertyValue
*pValue
= aDescriptor
.getConstArray();
837 Reference
< XInputStream
> xInputStream
;
838 for ( sal_Int32 i
= 0 ; i
< nLength
; i
++)
840 if ( pValue
[i
].Name
== "InputStream" )
841 pValue
[i
].Value
>>= xInputStream
;
843 if ( !xInputStream
.is() )
849 // An XML import service: what we push sax messages to..
850 OUString
sXMLImportService ( "com.sun.star.comp.Writer.XMLOasisImporter" );
851 Reference
< XDocumentHandler
> xInternalHandler( comphelper::ComponentContext( mxContext
).createComponent( sXMLImportService
), UNO_QUERY
);
853 // The XImporter sets up an empty target document for XDocumentHandler to write to..
854 Reference
< XImporter
> xImporter(xInternalHandler
, UNO_QUERY
);
855 xImporter
->setTargetDocument(mxDoc
);
857 // OO Document Handler: abstract class to handle document SAX messages, concrete implementation here
858 // writes to in-memory target doc
859 DocumentHandler
xHandler(xInternalHandler
);
861 WPXSvInputStream
input( xInputStream
);
863 OdtGenerator
collector(&xHandler
, ODF_FLAT_XML
);
864 collector
.registerEmbeddedObjectHandler("image/mwaw-odg", &handleEmbeddedMWAWObject
);
865 if (MWAW_OK
== MWAWDocument::parse(&input
, &collector
))
870 sal_Bool SAL_CALL
MWAWImportFilter::filter( const Sequence
< ::com::sun::star::beans::PropertyValue
> &aDescriptor
)
871 throw (RuntimeException
)
873 SAL_INFO("writerperfect", "MWAWImportFilter::filter");
874 return importImpl ( aDescriptor
);
876 void SAL_CALL
MWAWImportFilter::cancel( )
877 throw (RuntimeException
)
879 SAL_INFO("writerperfect", "MWAWImportFilter::cancel");
883 void SAL_CALL
MWAWImportFilter::setTargetDocument( const Reference
< ::com::sun::star::lang::XComponent
> &xDoc
)
884 throw (::com::sun::star::lang::IllegalArgumentException
, RuntimeException
)
886 SAL_INFO("writerperfect", "MWAWImportFilter::getTargetDocument");
890 // XExtendedFilterDetection
891 OUString SAL_CALL
MWAWImportFilter::detect( com::sun::star::uno::Sequence
< PropertyValue
> &Descriptor
)
892 throw( com::sun::star::uno::RuntimeException
)
894 SAL_INFO("writerperfect", "MWAWImportFilter::detect");
896 MWAWConfidence confidence
= MWAW_CONFIDENCE_NONE
;
897 MWAWDocument::DocumentType docType
= MWAWDocument::UNKNOWN
;
898 MWAWDocument::DocumentKind docKind
= MWAWDocument::K_UNKNOWN
;
900 sal_Int32 nLength
= Descriptor
.getLength();
901 sal_Int32 location
= nLength
;
902 const PropertyValue
*pValue
= Descriptor
.getConstArray();
903 Reference
< XInputStream
> xInputStream
;
904 for ( sal_Int32 i
= 0 ; i
< nLength
; i
++)
906 if ( pValue
[i
].Name
== "TypeName" )
908 else if ( pValue
[i
].Name
== "InputStream" )
909 pValue
[i
].Value
>>= xInputStream
;
912 if (!xInputStream
.is())
915 WPXSvInputStream
input( xInputStream
);
917 confidence
= MWAWDocument::isFileFormatSupported(&input
, docType
, docKind
);
919 if ((confidence
== MWAW_CONFIDENCE_EXCELLENT
) || (confidence
== MWAW_CONFIDENCE_GOOD
))
921 if ( docKind
== MWAWDocument::K_TEXT
)
925 case MWAWDocument::ACT
: // Acta (nothing done )
927 case MWAWDocument::CW
: // ClarisWorks/AppleWorks document (basic)
928 sTypeName
= "writer_ClarisWorks";
930 case MWAWDocument::DM
: // DocMaker (v4)
931 sTypeName
= "writer_DocMaker";
933 case MWAWDocument::ED
: // eDOC (v2)
934 sTypeName
= "writer_eDoc_Document";
936 case MWAWDocument::FULLW
: // FullWrite Professional (basic)
937 sTypeName
= "writer_FullWrite_Professional";
939 case MWAWDocument::HMAC
: // HanMac Word-K (basic done)
940 sTypeName
= "writer_HanMac_Word_K";
942 case MWAWDocument::HMACJ
: // HanMac Word-J ( almost nothing done for J document)
943 // sTypeName = "writer_HanMac_Word_J";
945 case MWAWDocument::LWTEXT
: // LightWayText ( only v4.5 Mac format )
946 sTypeName
= "writer_LightWayText";
948 case MWAWDocument::MARIW
: // Mariner Write ( only v1.6-v3.5 Mac Classic)
949 sTypeName
= "writer_Mariner_Write";
951 case MWAWDocument::MINDW
: // MindWrite
952 sTypeName
= "writer_MindWrite";
954 case MWAWDocument::MW
: // MacWrite document
955 sTypeName
= "writer_MacWrite";
957 case MWAWDocument::MWPRO
: // MacWriteII or MacWritePro document
958 sTypeName
= "writer_MacWritePro";
960 case MWAWDocument::MSWORD
: // MSWord document (v4 v5: basic done)
961 sTypeName
= "writer_Mac_Word";
963 case MWAWDocument::MSWORKS
: // MSWorks document (v1 v2)
964 sTypeName
= "writer_Mac_Works";
966 case MWAWDocument::NISUSW
: // Nisus Writer document: v3.4-v6.5
967 sTypeName
= "writer_Nisus_Writer";
969 case MWAWDocument::TEACH
: // TeachText or SimpleText: v1
970 sTypeName
= "writer_TeachText";
972 case MWAWDocument::TEDIT
: // Tex-Edit v2
973 sTypeName
= "writer_TexEdit";
975 case MWAWDocument::WNOW
: // WriteNow
976 sTypeName
= "writer_WriteNow";
978 case MWAWDocument::WPLUS
: // writerplus document
979 sTypeName
= "writer_WriterPlus";
981 case MWAWDocument::ZWRT
: // Z-Write : v1.3
982 sTypeName
= "writer_ZWrite";
990 if (!sTypeName
.isEmpty())
992 if ( location
== nLength
)
994 Descriptor
.realloc(nLength
+1);
995 Descriptor
[location
].Name
= "TypeName";
998 Descriptor
[location
].Value
<<=sTypeName
;
1006 void SAL_CALL
MWAWImportFilter::initialize( const Sequence
< Any
> &aArguments
)
1007 throw (Exception
, RuntimeException
)
1009 SAL_INFO("writerperfect", "MWAWImportFilter::initialize");
1010 Sequence
< PropertyValue
> aAnySeq
;
1011 sal_Int32 nLength
= aArguments
.getLength();
1012 if ( nLength
&& ( aArguments
[0] >>= aAnySeq
) )
1014 const PropertyValue
*pValue
= aAnySeq
.getConstArray();
1015 nLength
= aAnySeq
.getLength();
1016 for ( sal_Int32 i
= 0 ; i
< nLength
; i
++)
1018 if ( pValue
[i
].Name
== "Type" )
1020 pValue
[i
].Value
>>= msFilterName
;
1026 OUString
MWAWImportFilter_getImplementationName ()
1027 throw (RuntimeException
)
1029 return OUString ( "com.sun.star.comp.Writer.MWAWImportFilter" );
1032 #define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
1033 #define SERVICE_NAME2 "com.sun.star.document.ExtendedTypeDetection"
1034 sal_Bool SAL_CALL
MWAWImportFilter_supportsService( const OUString
&ServiceName
)
1035 throw (RuntimeException
)
1037 return ( ServiceName
== SERVICE_NAME1
|| ServiceName
== SERVICE_NAME2
);
1039 Sequence
< OUString
> SAL_CALL
MWAWImportFilter_getSupportedServiceNames( )
1040 throw (RuntimeException
)
1042 Sequence
< OUString
> aRet(2);
1043 OUString
*pArray
= aRet
.getArray();
1044 pArray
[0] = OUString ( SERVICE_NAME1
);
1045 pArray
[1] = OUString ( SERVICE_NAME2
);
1048 #undef SERVICE_NAME2
1049 #undef SERVICE_NAME1
1051 Reference
< XInterface
> SAL_CALL
MWAWImportFilter_createInstance( const Reference
< XComponentContext
> &rContext
)
1054 return (cppu::OWeakObject
*) new MWAWImportFilter( rContext
);
1058 OUString SAL_CALL
MWAWImportFilter::getImplementationName( )
1059 throw (RuntimeException
)
1061 return MWAWImportFilter_getImplementationName();
1063 sal_Bool SAL_CALL
MWAWImportFilter::supportsService( const OUString
&rServiceName
)
1064 throw (RuntimeException
)
1066 return MWAWImportFilter_supportsService( rServiceName
);
1068 Sequence
< OUString
> SAL_CALL
MWAWImportFilter::getSupportedServiceNames( )
1069 throw (RuntimeException
)
1071 return MWAWImportFilter_getSupportedServiceNames();
1074 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */