1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
26 #include <com/sun/star/embed/XEmbeddedObject.hpp>
28 #include <sfx2/objsh.hxx>
29 #include <svl/itempool.hxx>
30 #include <svl/itemset.hxx>
31 #include <svx/svdtypes.hxx>
35 #include <tools/poly.hxx>
37 #include <vcl/graph.hxx>
39 class SwTextFormatColl
;
43 class OutlinerParaObject
;
47 class SwFormatCharFormat
;
58 bool operator()(sal_uInt16 nA
, sal_uInt16 nB
) const;
65 /// STL container of Paragraph Styles (SwTextFormatColl)
66 typedef std::vector
<SwTextFormatColl
*> ParaStyles
;
67 /// STL container of SfxPoolItems (Attributes)
68 typedef std::map
<sal_uInt16
, const SfxPoolItem
*, sw::util::ItemSort
> PoolItems
;
70 /** Make exporting a Writer Frame easy
72 In word all frames are effectively anchored to character or as
73 character. This is nice and simple, writer is massively complex in this
74 area, so this ww8::Frame simplifies matters by providing a single unified
75 view of the multitude of elements in writer and their differing quirks.
77 A ww8::Frame wraps a writer frame and is guaranteed to have a suitable
78 anchor position available from it. It hides much of the needless
79 complexity of the multitude of floating/inline elements in writer, it...
81 Guarantees an anchor position for a frame.
82 Provides a readable way to see if we are anchored inline. (as character)
83 Provides a simple way to flag what type of entity this frame describes.
84 Provides the size of the element as drawn by writer.
89 enum WriterSource
{eTextBox
, eGraphic
, eOle
, eDrawing
, eFormControl
,eBulletGrf
};
91 const SwFrameFormat
* mpFlyFrame
;
94 // #i43447# - Size of the frame in the layout.
95 // Especially needed for graphics, whose layout size can differ from its
96 // size, because it is scaled into its environment.
99 WriterSource meWriterType
;
100 const SwNode
*mpStartFrameContent
;
105 Frame(const SwFrameFormat
&rFlyFrame
, const SwPosition
&rPos
);
106 Frame(const Graphic
&, const SwPosition
&);
108 /** Get the writer SwFrameFormat that this object describes
111 The wrapped SwFrameFormat
113 const SwFrameFormat
&GetFrameFormat() const { return *mpFlyFrame
; }
115 /** Get the position this frame is anchored at
118 The anchor position of this frame
120 const SwPosition
&GetPosition() const { return maPos
; }
121 void SetPosition(SwPosition
const& rPos
) { maPos
= rPos
; }
123 /** Get the node this frame is anchored into
126 The SwTextNode this frame is anchored inside
128 const SwContentNode
*GetContentNode() const
129 { return maPos
.nNode
.GetNode().GetContentNode(); }
131 /** Get the type of frame that this wraps
134 a WriterSource which describes the source type of this wrapper
136 WriterSource
GetWriterType() const { return meWriterType
; }
138 /** Is this frame inline (as character)
141 whether this is inline or not
143 bool IsInline() const { return mbIsInline
; }
145 /** Even if the frame isn't an inline frame, force it to behave as one
147 There are a variety of circumstances where word cannot have
148 anything except inline elements, e.g. inside frames. So its easier
149 to force this ww8::Frame into behaving as one, instead of special
150 casing export code all over the place.
153 void ForceTreatAsInline();
155 /** Get the first node of content in the frame
158 the first node of content in the frame, might not be any at all.
160 const SwNode
*GetContent() const { return mpStartFrameContent
; }
161 const Graphic
&GetGraphic() const { return maGrf
; }
162 bool HasGraphic() const { return mbForBullet
; }
164 /** Does this ww8::Frame refer to the same writer content as another
167 if the two ww8::Frames are handling the same writer frame
169 bool RefersToSameFrameAs(const Frame
&rOther
) const
171 if (mbForBullet
&& rOther
.mbForBullet
)
172 return (maGrf
== rOther
.maGrf
);
173 else if ((!mbForBullet
) && (!rOther
.mbForBullet
))
174 return (mpFlyFrame
== rOther
.mpFlyFrame
);
179 /** The Size of the contained element
182 the best size to use to export to word
184 const Size
& GetSize() const { return maSize
; }
186 /** The layout size of the contained element
188 #i43447# - Needed for graphics, which are scaled into its environment
192 const Size
& GetLayoutSize() const
198 /// STL container of Frames
199 typedef std::vector
<Frame
> Frames
;
200 /// STL iterator for Frames
201 typedef std::vector
<Frame
>::iterator FrameIter
;
208 /** Provide a dynamic_cast style cast for SfxPoolItems
210 A SfxPoolItem generally need to be cast back to its original type
211 to be useful, which is both tedious and error prone. So item_cast is
212 a helper template to aid the process and test if the cast is
216 The SfxPoolItem which is to be casted
219 A SfxPoolItem derived class to cast rItem to
221 @return A rItem upcasted back to a T
223 @exception std::bad_cast Thrown if the rItem was not a T
225 template<class T
> const T
& item_cast(const SfxPoolItem
&rItem
)
227 if (dynamic_cast<const T
*>(&rItem
) == nullptr)
228 throw std::bad_cast();
229 return static_cast<const T
&>(rItem
);
232 /** Provide a dynamic_cast style cast for SfxPoolItems
234 A SfxPoolItem generally need to be cast back to its original type
235 to be useful, which is both tedious and error prone. So item_cast is
236 a helper template to aid the process and test if the cast is
240 The SfxPoolItem which is to be casted
243 A SfxPoolItem derived class to cast pItem to
245 @return A pItem upcasted back to a T or 0 if pItem was not a T
247 template<class T
> const T
* item_cast(const SfxPoolItem
*pItem
)
249 return dynamic_cast<const T
*>(pItem
);
252 /** Extract a SfxPoolItem derived property from a SwContentNode
254 Writer's attributes are retrieved by passing a numeric identifier
255 and receiving a SfxPoolItem reference which must then typically be
256 cast back to its original type which is both tedious and verbose.
258 ItemGet uses item_cast () on the retrieved reference to test that the
259 retrieved property is of the type that the developer thinks it is.
262 The SwContentNode to retrieve the property from
265 The numeric identifier of the property to be retrieved
268 A SfxPoolItem derived class of the retrieved property
270 @exception std::bad_cast Thrown if the property was not a T
272 @return The T requested
274 template<class T
> const T
& ItemGet(const SwContentNode
&rNode
,
277 return item_cast
<T
>(rNode
.GetAttr(eType
));
280 /** Extract a SfxPoolItem derived property from a SwFormat
282 Writer's attributes are retrieved by passing a numeric identifier
283 and receiving a SfxPoolItem reference which must then typically be
284 cast back to its original type which is both tedious and verbose.
286 ItemGet uses item_cast () on the retrieved reference to test that the
287 retrieved property is of the type that the developer thinks it is.
290 The SwFormat to retrieve the property from
293 The numeric identifier of the property to be retrieved
296 A SfxPoolItem derived class of the retrieved property
298 @exception std::bad_cast Thrown if the property was not a T
300 template<class T
> const T
& ItemGet(const SwFormat
&rFormat
,
303 return item_cast
<T
>(rFormat
.GetFormatAttr(eType
));
306 /** Extract a SfxPoolItem derived property from a SfxItemSet
308 Writer's attributes are retrieved by passing a numeric identifier
309 and receiving a SfxPoolItem reference which must then typically be
310 cast back to its original type which is both tedious and verbose.
312 ItemGet uses item_cast () on the retrieved reference to test that the
313 retrieved property is of the type that the developer thinks it is.
316 The SfxItemSet to retrieve the property from
319 The numeric identifier of the property to be retrieved
322 A SfxPoolItem derived class of the retrieved property
324 @exception std::bad_cast Thrown if the property was not a T
326 @return The T requested
328 template<class T
> const T
& ItemGet(const SfxItemSet
&rSet
,
331 return item_cast
<T
>(rSet
.Get(eType
));
334 /** Extract a default SfxPoolItem derived property from a SfxItemPool
336 Writer's attributes are retrieved by passing a numeric identifier
337 and receiving a SfxPoolItem reference which must then typically be
338 cast back to its original type which is both tedious and verbose.
340 DefaultItemGet returns a reference to the default property of a
341 given SfxItemPool for a given property id, e.g. default fontsize
343 DefaultItemGet uses item_cast () on the retrieved reference to test
344 that the retrieved property is of the type that the developer thinks
348 The SfxItemPool whose default property we want
351 The numeric identifier of the default property to be retrieved
354 A SfxPoolItem derived class of the retrieved property
356 @exception std::bad_cast Thrown if the property was not a T
358 @return The T requested
360 template<class T
> const T
& DefaultItemGet(const SfxItemPool
&rPool
,
363 return item_cast
<T
>(rPool
.GetDefaultItem(eType
));
366 /** Extract a default SfxPoolItem derived property from a SwDoc
368 Writer's attributes are retrieved by passing a numeric identifier
369 and receiving a SfxPoolItem reference which must then typically be
370 cast back to its original type which is both tedious and verbose.
372 DefaultItemGet returns a reference to the default property of a
373 given SwDoc (Writer Document) for a given property id, e.g default
376 DefaultItemGet uses item_cast () on the retrieved reference to test
377 that the retrieved property is of the type that the developer thinks
381 The SfxItemPool whose default property we want
384 The numeric identifier of the default property to be retrieved
387 A SfxPoolItem derived class of the retrieved property
389 @exception std::bad_cast Thrown if the property was not a T
391 @return The T requested
393 template<class T
> const T
& DefaultItemGet(const SwDoc
&rDoc
,
396 return DefaultItemGet
<T
>(rDoc
.GetAttrPool(), eType
);
399 /** Get the Paragraph Styles of a SwDoc
401 Writer's styles are in one of those dreaded macro based pre-STL
402 containers. Give me an STL container of the paragraph styles
406 The SwDoc document to get the styles from
408 @return A ParaStyles containing the SwDoc's Paragraph Styles
410 ww8::ParaStyles
GetParaStyles(const SwDoc
&rDoc
);
412 /** Get a Paragraph Style which fits a given name
414 Its surprisingly tricky to get a style when all you have is a name,
415 but that's what this does
418 The SwDoc document to search in
421 The name of the style to search for
423 @return A Paragraph Style if one exists which matches the name
425 SwTextFormatColl
* GetParaStyle(SwDoc
&rDoc
, const OUString
& rName
);
427 /** Get a Character Style which fits a given name
429 Its surprisingly tricky to get a style when all you have is a name,
430 but that's what this does
433 The SwDoc document to search in
436 The name of the style to search for
438 @return A Character Style if one exists which matches the name
440 SwCharFormat
* GetCharStyle(SwDoc
&rDoc
, const OUString
& rName
);
442 /** Sort sequence of Paragraph Styles by assigned outline style list level
444 Sort ParaStyles in ascending order of assigned outline style list level,
445 e.g. given Normal/Heading1/Heading2/.../Heading10 at their default
446 assigned outline style list levels of body level/level 1/level 2/.../level 10
449 adjust the sorting algorithm due to introduced outline level attribute
452 The ParaStyles to sort
454 void SortByAssignedOutlineStyleListLevel(ww8::ParaStyles
&rStyles
);
456 /** Get the SfxPoolItems of a SfxItemSet
458 Writer's SfxPoolItems (attributes) are in one of those dreaded
459 macro based pre-STL containers. Give me an STL container of the
463 The SfxItemSet to get the items from
466 The sw::PoolItems to put the items into
468 void GetPoolItems(const SfxItemSet
&rSet
, ww8::PoolItems
&rItems
, bool bExportParentItemSet
);
470 const SfxPoolItem
*SearchPoolItems(const ww8::PoolItems
&rItems
,
473 template<class T
> const T
* HasItem(const ww8::PoolItems
&rItems
,
476 return item_cast
<T
>(SearchPoolItems(rItems
, eType
));
479 /** Remove properties from an SfxItemSet which a SwFormatCharFormat overrides
481 Given an SfxItemSet and a SwFormatCharFormat remove from the rSet all the
482 properties which the SwFormatCharFormat would override. An SfxItemSet
483 contains attributes, and a SwFormatCharFormat is a "Character Style",
484 so if the SfxItemSet contains bold and so does the character style
485 then delete bold from the SfxItemSet
488 rFormat the SwFormatCharFormat which describes the Character Style
491 rSet the SfxItemSet from which we want to remove any properties
492 which the rFormat would override
494 @see #i24291# for examples
496 void ClearOverridesFromSet(const SwFormatCharFormat
&rFormat
, SfxItemSet
&rSet
);
498 /** Get the Floating elements in a SwDoc
500 Writer's FrameFormats may or may not be anchored to some text content,
501 e.g. Page Anchored elements will not be. For the winword export we
502 need them to have something to be anchored to. So this method
503 returns all the floating elements in a document as a STL container
504 of ww8::Frames which are guaranteed to have an appropriate anchor.
507 The SwDoc document to get the styles from
510 The SwPam to describe the selection in the document to get the
511 elements from. 0 means the entire document.
513 @return A Frames containing the selections Floating elements
515 ww8::Frames
GetFrames(const SwDoc
&rDoc
, SwPaM
const *pPaM
);
517 /** fix up frame positions, must be called after SetRedlineFlags */
518 void UpdateFramePositions(ww8::Frames
& rFrames
);
520 /** Get the Frames anchored to a given node
522 Given a container of frames, find the ones anchored to a given node
525 The container of frames to search in
528 The SwNode to check for anchors to
530 @return the Frames in rFrames anchored to rNode
532 ww8::Frames
GetFramesInNode(const ww8::Frames
&rFrames
, const SwNode
&rNode
);
534 /** Get the Numbering Format used on a paragraph
536 There are two differing types of numbering formats that may be on a
537 paragraph, normal and outline. The outline is that numbering you
538 see in tools->outline numbering. There's no difference in the
539 numbering itself, just how you get it from the SwTextNode. Needless
540 to say the filter generally couldn't care less what type of
544 The SwTextNode that is the paragraph
546 @return A SwNumFormat pointer that describes the numbering level
547 on this paragraph, or 0 if there is none.
549 const SwNumFormat
* GetNumFormatFromTextNode(const SwTextNode
&rTextNode
);
551 /** Get the Numbering Format for a given level from a numbering rule
559 @return A SwNumFormat pointer that describes the numbering level
560 or 0 if the nLevel is out of range
562 const SwNumFormat
* GetNumFormatFromSwNumRuleLevel(const SwNumRule
&rRule
,
565 const SwNumRule
* GetNumRuleFromTextNode(const SwTextNode
&rTextNd
);
566 const SwNumRule
* GetNormalNumRuleFromTextNode(const SwTextNode
&rTextNd
);
568 /** Get the SwNoTextNode associated with a SwFrameFormat if here is one
570 There are two differing types of numbering formats that may be on a
571 paragraph, normal and outline. The outline is that numbering you
572 see in tools->outline numbering. There's no difference in the
573 numbering itself, just how you get it from the SwTextNode. Needless
574 to say the filter generally couldn't care less what type of
578 The SwFrameFormat that may describe a graphic
580 @return A SwNoTextNode pointer that describes the graphic of this
581 frame if there is one, or 0 if there is none.
583 SwNoTextNode
*GetNoTextNodeFromSwFrameFormat(const SwFrameFormat
&rFormat
);
585 /** Does a node have a "page break before" applied
587 Both text nodes and tables in writer can have "page break before"
588 This function gives a unified view to both entities
591 The SwNode to query the page break of
593 @return true if there is a page break, false otherwise
595 bool HasPageBreak(const SwNode
&rNode
);
597 /** Make a best fit Polygon from a PolyPolygon
599 For custom contours in writer we use a PolyPolygon, while word uses
600 a simple polygon, so we need to try and make the best polygon from
604 The tools::PolyPolygon to try and turn into a Polygon
606 @return best fit Polygon from rPolyPoly
608 tools::Polygon
PolygonFromPolyPolygon(const tools::PolyPolygon
&rPolyPoly
);
610 /// Undo all scaling / move tricks of the wrap polygon done during import.
611 tools::Polygon
CorrectWordWrapPolygonForExport(const tools::PolyPolygon
& rPolyPoly
, const SwNoTextNode
* pNd
, bool bCorrectCrop
);
613 /** Make setting a drawing object's layer in a Writer document easy
615 Word has the simple concept of a drawing object either in the
616 foreground and in the background. We have an additional complexity
617 that form components live in a separate layer, which seems
618 unnecessarily complicated. So in the winword filter we set the
619 object's layer through this class with either SendObjectToHell for
620 the bottom layer and SendObjectToHeaven for the top and we don't
621 worry about the odd form layer design wrinkle.
626 SdrLayerID mnHeavenLayer
, mnHellLayer
, mnFormLayer
;
627 enum Layer
{eHeaven
, eHell
};
628 void SetObjectLayer(SdrObject
&rObject
, Layer eLayer
) const;
631 /** Make Object live in the bottom drawing layer
634 The object to be set to the bottom layer
636 void SendObjectToHell(SdrObject
&rObject
) const;
638 /** Make Object lives in the top layer
641 The object to be set to the top layer
643 void SendObjectToHeaven(SdrObject
&rObject
) const;
645 /** Normal constructor
648 The Writer document whose drawing layers we will be inserting
651 explicit SetLayer(const SwDoc
&rDoc
);
654 const SwCharFormat
* GetSwCharFormat(const SwFormatINetFormat
& rINet
, SwDoc
& rDoc
);
659 /** Map an ID valid in one SfxItemPool to its equivalent in another
661 Given a WhichId (the id that identifies a property e.g. bold) which
662 is correct in a given SfxItemPool, get the equivalent whichId in
665 This arises because the drawing layer uses the same properties as
666 writer e.g. SvxWeight, but for some reason uses different ids
667 for the same properties as writer.
670 The SfxItemPool in whose terms the Id is returned
673 The SfxItemPool in whose terms the Id is passed in
676 The Id to transform from source to dest
678 @return 0 on failure, the correct property Id on success
680 sal_uInt16
TransformWhichBetweenPools(const SfxItemPool
&rDestPool
,
681 const SfxItemPool
&rSrcPool
, sal_uInt16 nWhich
);
683 /** Map a SwDoc WhichId to the equivalent Id for a given SfxItemSet
685 Given a WhichId (the id that identifies a property e.g. bold) which
686 is correct for a Writer document, get the equivalent whichId which
687 for a given SfxItemSet.
689 This arises because the drawing layer uses the same properties as
690 writer e.g. SvxWeight, but for some reason uses different ids
691 for the same properties as writer.
693 This is effectively the same as TransformWhichBetweenPools except
694 at a slightly different layer.
697 The SfxItemSet in whose terms the Id is returned
700 The SwDoc in whose terms the Id is passed in
703 The Id to transform from writer to the SfxItemSet's domain
705 @return 0 on failure, the correct SfxItemSet Id on success
707 sal_uInt16
GetSetWhichFromSwDocWhich(const SfxItemSet
&rSet
,
708 const SwDoc
&rDoc
, sal_uInt16 nWhich
);
710 /** Make inserting an OLE object into a Writer document easy
712 The rest of Office uses SdrOle2Obj for their OLE objects, Writer
713 doesn't, which makes things a bit difficult as this is the type of
714 object that the escher import code shared by the MSOffice filters
715 produces when it imports an OLE object.
717 This utility class takes ownership of the OLE object away from a
718 SdrOle2Obj and can massage it into the condition best suited to
719 insertion into Writer.
721 If the object was not transferred into Writer then it is deleted
724 class DrawingOLEAdaptor
727 css::uno::Reference
< css::embed::XEmbeddedObject
> mxIPRef
;
728 SfxObjectShell
& mrPers
;
729 const Graphic
* mpGraphic
;
731 /** Take ownership of a SdrOle2Objs OLE object
734 The SdrOle2Obj whose OLE object we want to take control of
737 The SvPersist of a SwDoc (SwDoc::GetPersist()) into which we
738 may want to move the object, or remove it from if unwanted.
740 DrawingOLEAdaptor(SdrOle2Obj
&rObj
, SfxObjectShell
&rPers
);
742 /// Destructor will destroy the owned OLE object if not transferred
743 ~DrawingOLEAdaptor();
745 /** Transfer ownership of the OLE object to a document's SvPersist
747 TransferToDoc moves the object into the persist under the name
748 passed in. This name is then suitable to be used as an argument
751 The object is no longer owned by the adaptor after this call,
752 subsequent calls are an error and return false.
755 The name to store the object under in the document.
757 @return On success true is returned, otherwise false. On
758 success rName is then suitable for user with SwDoc::InsertOLE
760 bool TransferToDoc(OUString
&rName
);
762 DrawingOLEAdaptor
& operator=(const DrawingOLEAdaptor
&) = delete;
763 DrawingOLEAdaptor(const DrawingOLEAdaptor
&rDoc
) = delete;
770 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */