android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / filter / ww8 / writerhelper.hxx
blob27442fceb0b98fe8194e3036c7be245f6759bbae
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SW_SOURCE_FILTER_WW8_WRITERHELPER_HXX
21 #define INCLUDED_SW_SOURCE_FILTER_WW8_WRITERHELPER_HXX
23 #include <vector>
24 #include <map>
25 #include <com/sun/star/embed/XEmbeddedObject.hpp>
27 #include <sfx2/objsh.hxx>
28 #include <svl/itempool.hxx>
29 #include <svl/itemset.hxx>
30 #include <svx/svdtypes.hxx>
31 #include <node.hxx>
32 #include <pam.hxx>
33 #include <tools/poly.hxx>
34 #include <doc.hxx>
35 #include <vcl/graph.hxx>
37 class SwTextFormatColl;
38 class SwCharFormat;
39 class SdrObject;
40 class SdrOle2Obj;
41 class OutlinerParaObject;
42 class SwNumFormat;
43 class SwTextNode;
44 class SwNoTextNode;
45 class SwFormatCharFormat;
46 class SwDoc;
47 class SwNumRule;
49 namespace sw
51 namespace util
53 class ItemSort
55 public:
56 bool operator()(sal_uInt16 nA, sal_uInt16 nB) const;
61 namespace ww8
63 /// STL container of Paragraph Styles (SwTextFormatColl)
64 typedef std::vector<SwTextFormatColl *> ParaStyles;
65 /// STL container of SfxPoolItems (Attributes)
66 typedef std::map<sal_uInt16, const SfxPoolItem *, sw::util::ItemSort> PoolItems;
68 /** Make exporting a Writer Frame easy
70 In word all frames are effectively anchored to character or as
71 character. This is nice and simple, writer is massively complex in this
72 area, so this ww8::Frame simplifies matters by providing a single unified
73 view of the multitude of elements in writer and their differing quirks.
75 A ww8::Frame wraps a writer frame and is guaranteed to have a suitable
76 anchor position available from it. It hides much of the needless
77 complexity of the multitude of floating/inline elements in writer, it...
79 Guarantees an anchor position for a frame.
80 Provides a readable way to see if we are anchored inline. (as character)
81 Provides a simple way to flag what type of entity this frame describes.
82 Provides the size of the element as drawn by writer.
84 class Frame
86 public:
87 enum WriterSource {eTextBox, eGraphic, eOle, eDrawing, eFormControl,eBulletGrf};
88 private:
89 const SwFrameFormat* mpFlyFrame;
90 SwPosition maPos;
91 Size maSize;
92 // #i43447# - Size of the frame in the layout.
93 // Especially needed for graphics, whose layout size can differ from its
94 // size, because it is scaled into its environment.
95 Size maLayoutSize;
97 WriterSource meWriterType;
98 const SwNode *mpStartFrameContent;
99 bool mbIsInline;
100 bool mbForBullet:1;
101 Graphic maGrf;
102 public:
103 Frame(const SwFrameFormat &rFlyFrame, SwPosition aPos);
104 Frame(const Graphic&, SwPosition );
106 /** Get the writer SwFrameFormat that this object describes
108 @return
109 The wrapped SwFrameFormat
111 const SwFrameFormat &GetFrameFormat() const { return *mpFlyFrame; }
113 /** Get the position this frame is anchored at
115 @return
116 The anchor position of this frame
118 const SwPosition &GetPosition() const { return maPos; }
119 void SetPosition(SwPosition const& rPos) { maPos = rPos; }
121 /** Get the node this frame is anchored into
123 @return
124 The SwTextNode this frame is anchored inside
126 const SwContentNode *GetContentNode() const
127 { return maPos.GetNode().GetContentNode(); }
129 /** Get the type of frame that this wraps
131 @return
132 a WriterSource which describes the source type of this wrapper
134 WriterSource GetWriterType() const { return meWriterType; }
136 /** Is this frame inline (as character)
138 @return
139 whether this is inline or not
141 bool IsInline() const { return mbIsInline; }
143 /** Even if the frame isn't an inline frame, force it to behave as one
145 There are a variety of circumstances where word cannot have
146 anything except inline elements, e.g. inside frames. So its easier
147 to force this ww8::Frame into behaving as one, instead of special
148 casing export code all over the place.
151 void ForceTreatAsInline();
153 /** Get the first node of content in the frame
155 @return
156 the first node of content in the frame, might not be any at all.
158 const SwNode *GetContent() const { return mpStartFrameContent; }
159 const Graphic &GetGraphic() const { return maGrf; }
160 bool HasGraphic() const { return mbForBullet; }
162 /** Does this ww8::Frame refer to the same writer content as another
164 @return
165 if the two ww8::Frames are handling the same writer frame
167 bool RefersToSameFrameAs(const Frame &rOther) const
169 if (mbForBullet && rOther.mbForBullet)
170 return (maGrf == rOther.maGrf);
171 else if ((!mbForBullet) && (!rOther.mbForBullet))
172 return (mpFlyFrame == rOther.mpFlyFrame);
174 return false;
177 /** The Size of the contained element
179 @return
180 the best size to use to export to word
182 const Size& GetSize() const { return maSize; }
184 /** The layout size of the contained element
186 #i43447# - Needed for graphics, which are scaled into its environment
188 @return layout size
190 const Size& GetLayoutSize() const
192 return maLayoutSize;
196 /// STL container of Frames
197 typedef std::vector<Frame> Frames;
198 /// STL iterator for Frames
199 typedef std::vector<Frame>::iterator FrameIter;
202 namespace sw
204 namespace util
206 /** Provide a dynamic_cast style cast for SfxPoolItems
208 A SfxPoolItem generally need to be cast back to its original type
209 to be useful, which is both tedious and error prone. So item_cast is
210 a helper template to aid the process and test if the cast is
211 correct.
213 @param rItem
214 The SfxPoolItem which is to be casted
216 @tplparam T
217 A SfxPoolItem derived class to cast rItem to
219 @return A rItem upcasted back to a T
221 @exception std::bad_cast Thrown if the rItem was not a T
223 template<class T> const T & item_cast(const SfxPoolItem &rItem)
225 assert(dynamic_cast<const T *>(&rItem) && "bad type cast");
226 return static_cast<const T &>(rItem);
229 /** Provide a dynamic_cast style cast for SfxPoolItems
231 A SfxPoolItem generally need to be cast back to its original type
232 to be useful, which is both tedious and error prone. So item_cast is
233 a helper template to aid the process and test if the cast is
234 correct.
236 @param pItem
237 The SfxPoolItem which is to be casted
239 @tplparam T
240 A SfxPoolItem derived class to cast pItem to
242 @return A pItem upcasted back to a T or 0 if pItem was not a T
244 template<class T> const T * item_cast(const SfxPoolItem *pItem)
246 return dynamic_cast<const T *>(pItem);
249 /** Get the Paragraph Styles of a SwDoc
251 Writer's styles are in one of those dreaded macro based pre-STL
252 containers. Give me an STL container of the paragraph styles
253 instead.
255 @param rDoc
256 The SwDoc document to get the styles from
258 @return A ParaStyles containing the SwDoc's Paragraph Styles
260 ww8::ParaStyles GetParaStyles(const SwDoc &rDoc);
262 /** Get a Paragraph Style which fits a given name
264 Its surprisingly tricky to get a style when all you have is a name,
265 but that's what this does
267 @param rDoc
268 The SwDoc document to search in
270 @param rName
271 The name of the style to search for
273 @return A Paragraph Style if one exists which matches the name
275 SwTextFormatColl* GetParaStyle(SwDoc &rDoc, const OUString& rName);
277 /** Get a Character Style which fits a given name
279 Its surprisingly tricky to get a style when all you have is a name,
280 but that's what this does
282 @param rDoc
283 The SwDoc document to search in
285 @param rName
286 The name of the style to search for
288 @return A Character Style if one exists which matches the name
290 SwCharFormat* GetCharStyle(SwDoc &rDoc, const OUString& rName);
292 /** Sort sequence of Paragraph Styles by assigned outline style list level
294 Sort ParaStyles in ascending order of assigned outline style list level,
295 e.g. given Normal/Heading1/Heading2/.../Heading10 at their default
296 assigned outline style list levels of body level/level 1/level 2/.../level 10
298 #i98791#
299 adjust the sorting algorithm due to introduced outline level attribute
301 @param rStyles
302 The ParaStyles to sort
304 void SortByAssignedOutlineStyleListLevel(ww8::ParaStyles &rStyles);
306 /** Get the SfxPoolItems of a SfxItemSet
308 Writer's SfxPoolItems (attributes) are in one of those dreaded
309 macro based pre-STL containers. Give me an STL container of the
310 items instead.
312 @param rSet
313 The SfxItemSet to get the items from
315 @param rItems
316 The sw::PoolItems to put the items into
318 void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool bExportParentItemSet );
320 void DeduplicateItems(ww8::PoolItems &rItems);
322 const SfxPoolItem *SearchPoolItems(const ww8::PoolItems &rItems,
323 sal_uInt16 eType);
325 template<class T> const T* HasItem(const ww8::PoolItems &rItems,
326 sal_uInt16 eType)
328 return item_cast<T>(SearchPoolItems(rItems, eType));
331 /** Remove properties from an SfxItemSet which a SwFormatCharFormat overrides
333 Given an SfxItemSet and a SwFormatCharFormat remove from the rSet all the
334 properties which the SwFormatCharFormat would override. An SfxItemSet
335 contains attributes, and a SwFormatCharFormat is a "Character Style",
336 so if the SfxItemSet contains bold and so does the character style
337 then delete bold from the SfxItemSet
339 @param
340 rFormat the SwFormatCharFormat which describes the Character Style
342 @param
343 rSet the SfxItemSet from which we want to remove any properties
344 which the rFormat would override
346 @see #i24291# for examples
348 void ClearOverridesFromSet(const SwFormatCharFormat &rFormat, SfxItemSet &rSet);
350 /** Get the Floating elements in a SwDoc
352 Writer's FrameFormats may or may not be anchored to some text content,
353 e.g. Page Anchored elements will not be. For the winword export we
354 need them to have something to be anchored to. So this method
355 returns all the floating elements in a document as a STL container
356 of ww8::Frames which are guaranteed to have an appropriate anchor.
358 @param rDoc
359 The SwDoc document to get the styles from
361 @param pPaM
362 The SwPam to describe the selection in the document to get the
363 elements from. 0 means the entire document.
365 @return A Frames containing the selections Floating elements
367 ww8::Frames GetFrames(const SwDoc &rDoc, SwPaM const *pPaM);
369 /** fix up frame positions, must be called after SetRedlineFlags */
370 void UpdateFramePositions(ww8::Frames & rFrames);
372 /** Get the Frames anchored to a given node
374 Given a container of frames, find the ones anchored to a given node
376 @param rFrames
377 The container of frames to search in
379 @param rNode
380 The SwNode to check for anchors to
382 @return the Frames in rFrames anchored to rNode
384 ww8::Frames GetFramesInNode(const ww8::Frames &rFrames, const SwNode &rNode);
386 /** Get the Numbering Format used on a paragraph
388 There are two differing types of numbering formats that may be on a
389 paragraph, normal and outline. The outline is that numbering you
390 see in tools->outline numbering. There's no difference in the
391 numbering itself, just how you get it from the SwTextNode. Needless
392 to say the filter generally couldn't care less what type of
393 numbering is in use.
395 @param rTextNode
396 The SwTextNode that is the paragraph
398 @return A SwNumFormat pointer that describes the numbering level
399 on this paragraph, or 0 if there is none.
401 const SwNumFormat* GetNumFormatFromTextNode(const SwTextNode &rTextNode);
403 /** Get the Numbering Format for a given level from a numbering rule
405 @param rRule
406 The numbering rule
408 @param nLevel
409 The numbering level
411 @return A SwNumFormat pointer that describes the numbering level
412 or 0 if the nLevel is out of range
414 const SwNumFormat* GetNumFormatFromSwNumRuleLevel(const SwNumRule &rRule,
415 int nLevel);
417 const SwNumRule* GetNumRuleFromTextNode(const SwTextNode &rTextNd);
418 const SwNumRule* GetNormalNumRuleFromTextNode(const SwTextNode &rTextNd);
420 /** Get the SwNoTextNode associated with a SwFrameFormat if here is one
422 There are two differing types of numbering formats that may be on a
423 paragraph, normal and outline. The outline is that numbering you
424 see in tools->outline numbering. There's no difference in the
425 numbering itself, just how you get it from the SwTextNode. Needless
426 to say the filter generally couldn't care less what type of
427 numbering is in use.
429 @param rFormat
430 The SwFrameFormat that may describe a graphic
432 @return A SwNoTextNode pointer that describes the graphic of this
433 frame if there is one, or 0 if there is none.
435 SwNoTextNode *GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat);
437 /** Does a node have a "page break before" applied
439 Both text nodes and tables in writer can have "page break before"
440 This function gives a unified view to both entities
442 @param rNode
443 The SwNode to query the page break of
445 @return true if there is a page break, false otherwise
447 bool HasPageBreak(const SwNode &rNode);
449 /** Make a best fit Polygon from a PolyPolygon
451 For custom contours in writer we use a PolyPolygon, while word uses
452 a simple polygon, so we need to try and make the best polygon from
453 a PolyPolygon
455 @param rPolyPoly
456 The tools::PolyPolygon to try and turn into a Polygon
458 @return best fit Polygon from rPolyPoly
460 tools::Polygon PolygonFromPolyPolygon(const tools::PolyPolygon &rPolyPoly);
462 /// Undo all scaling / move tricks of the wrap polygon done during import.
463 tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTextNode* pNd, bool bCorrectCrop);
465 /** Make setting a drawing object's layer in a Writer document easy
467 Word has the simple concept of a drawing object either in the
468 foreground and in the background. We have an additional complexity
469 that form components live in a separate layer, which seems
470 unnecessarily complicated. So in the winword filter we set the
471 object's layer through this class with either SendObjectToHell for
472 the bottom layer and SendObjectToHeaven for the top and we don't
473 worry about the odd form layer design wrinkle.
475 class SetLayer
477 private:
478 SdrLayerID mnHeavenLayer, mnHellLayer, mnFormLayer;
479 enum Layer {eHeaven, eHell};
480 void SetObjectLayer(SdrObject &rObject, Layer eLayer) const;
481 public:
483 /** Make Object live in the bottom drawing layer
485 @param rObject
486 The object to be set to the bottom layer
488 void SendObjectToHell(SdrObject &rObject) const;
490 /** Make Object lives in the top layer
492 @param rObject
493 The object to be set to the top layer
495 void SendObjectToHeaven(SdrObject &rObject) const;
497 /** Normal constructor
499 @param rDoc
500 The Writer document whose drawing layers we will be inserting
501 objects into
503 explicit SetLayer(const SwDoc &rDoc);
506 const SwCharFormat* GetSwCharFormat(const SwFormatINetFormat& rINet, SwDoc& rDoc);
509 namespace hack
511 /** Map an ID valid in one SfxItemPool to its equivalent in another
513 Given a WhichId (the id that identifies a property e.g. bold) which
514 is correct in a given SfxItemPool, get the equivalent whichId in
515 another SfxItemPool
517 This arises because the drawing layer uses the same properties as
518 writer e.g. SvxWeight, but for some reason uses different ids
519 for the same properties as writer.
521 @param rDestPool
522 The SfxItemPool in whose terms the Id is returned
524 @param rSrcPool
525 The SfxItemPool in whose terms the Id is passed in
527 @param nWhich
528 The Id to transform from source to dest
530 @return 0 on failure, the correct property Id on success
532 sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
533 const SfxItemPool &rSrcPool, sal_uInt16 nWhich);
535 /** Map a SwDoc WhichId to the equivalent Id for a given SfxItemSet
537 Given a WhichId (the id that identifies a property e.g. bold) which
538 is correct for a Writer document, get the equivalent whichId which
539 for a given SfxItemSet.
541 This arises because the drawing layer uses the same properties as
542 writer e.g. SvxWeight, but for some reason uses different ids
543 for the same properties as writer.
545 This is effectively the same as TransformWhichBetweenPools except
546 at a slightly different layer.
548 @param rSet
549 The SfxItemSet in whose terms the Id is returned
551 @param rDoc
552 The SwDoc in whose terms the Id is passed in
554 @param nWhich
555 The Id to transform from writer to the SfxItemSet's domain
557 @return 0 on failure, the correct SfxItemSet Id on success
559 sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
560 const SwDoc &rDoc, sal_uInt16 nWhich);
562 /** Make inserting an OLE object into a Writer document easy
564 The rest of Office uses SdrOle2Obj for their OLE objects, Writer
565 doesn't, which makes things a bit difficult as this is the type of
566 object that the escher import code shared by the MSOffice filters
567 produces when it imports an OLE object.
569 This utility class takes ownership of the OLE object away from a
570 SdrOle2Obj and can massage it into the condition best suited to
571 insertion into Writer.
573 If the object was not transferred into Writer then it is deleted
574 during destruction.
576 class DrawingOLEAdaptor
578 private:
579 css::uno::Reference < css::embed::XEmbeddedObject > mxIPRef;
580 SfxObjectShell& mrPers;
581 const Graphic* mpGraphic;
582 public:
583 /** Take ownership of a SdrOle2Objs OLE object
585 @param rObj
586 The SdrOle2Obj whose OLE object we want to take control of
588 @param rPers
589 The SvPersist of a SwDoc (SwDoc::GetPersist()) into which we
590 may want to move the object, or remove it from if unwanted.
592 DrawingOLEAdaptor(SdrOle2Obj &rObj, SfxObjectShell &rPers);
594 /// Destructor will destroy the owned OLE object if not transferred
595 ~DrawingOLEAdaptor();
597 /** Transfer ownership of the OLE object to a document's SvPersist
599 TransferToDoc moves the object into the persist under the name
600 passed in. This name is then suitable to be used as an argument
601 to SwDoc::InsertOLE.
603 The object is no longer owned by the adaptor after this call,
604 subsequent calls are an error and return false.
606 @param rName
607 The name to store the object under in the document.
609 @return On success true is returned, otherwise false. On
610 success rName is then suitable for user with SwDoc::InsertOLE
612 bool TransferToDoc(OUString &rName);
613 private:
614 DrawingOLEAdaptor& operator=(const DrawingOLEAdaptor&) = delete;
615 DrawingOLEAdaptor(const DrawingOLEAdaptor &rDoc) = delete;
620 #endif
622 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */