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
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>
33 #include <tools/poly.hxx>
35 #include <vcl/graph.hxx>
37 class SwTextFormatColl
;
41 class OutlinerParaObject
;
45 class SwFormatCharFormat
;
56 bool operator()(sal_uInt16 nA
, sal_uInt16 nB
) const;
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.
87 enum WriterSource
{eTextBox
, eGraphic
, eOle
, eDrawing
, eFormControl
,eBulletGrf
};
89 const SwFrameFormat
* mpFlyFrame
;
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.
97 WriterSource meWriterType
;
98 const SwNode
*mpStartFrameContent
;
103 Frame(const SwFrameFormat
&rFlyFrame
, SwPosition aPos
);
104 Frame(const Graphic
&, SwPosition
);
106 /** Get the writer SwFrameFormat that this object describes
109 The wrapped SwFrameFormat
111 const SwFrameFormat
&GetFrameFormat() const { return *mpFlyFrame
; }
113 /** Get the position this frame is anchored at
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
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
132 a WriterSource which describes the source type of this wrapper
134 WriterSource
GetWriterType() const { return meWriterType
; }
136 /** Is this frame inline (as character)
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
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
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
);
177 /** The Size of the contained element
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
190 const Size
& GetLayoutSize() const
196 /// STL container of Frames
197 typedef std::vector
<Frame
> Frames
;
198 /// STL iterator for Frames
199 typedef std::vector
<Frame
>::iterator FrameIter
;
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
214 The SfxPoolItem which is to be casted
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
237 The SfxPoolItem which is to be casted
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
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
268 The SwDoc document to search in
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
283 The SwDoc document to search in
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
299 adjust the sorting algorithm due to introduced outline level attribute
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
313 The SfxItemSet to get the items from
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
,
325 template<class T
> const T
* HasItem(const ww8::PoolItems
&rItems
,
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
340 rFormat the SwFormatCharFormat which describes the Character Style
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.
359 The SwDoc document to get the styles from
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
377 The container of frames to search in
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
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
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
,
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
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
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
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.
478 SdrLayerID mnHeavenLayer
, mnHellLayer
, mnFormLayer
;
479 enum Layer
{eHeaven
, eHell
};
480 void SetObjectLayer(SdrObject
&rObject
, Layer eLayer
) const;
483 /** Make Object live in the bottom drawing layer
486 The object to be set to the bottom layer
488 void SendObjectToHell(SdrObject
&rObject
) const;
490 /** Make Object lives in the top layer
493 The object to be set to the top layer
495 void SendObjectToHeaven(SdrObject
&rObject
) const;
497 /** Normal constructor
500 The Writer document whose drawing layers we will be inserting
503 explicit SetLayer(const SwDoc
&rDoc
);
506 const SwCharFormat
* GetSwCharFormat(const SwFormatINetFormat
& rINet
, SwDoc
& rDoc
);
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
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.
522 The SfxItemPool in whose terms the Id is returned
525 The SfxItemPool in whose terms the Id is passed in
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.
549 The SfxItemSet in whose terms the Id is returned
552 The SwDoc in whose terms the Id is passed in
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
576 class DrawingOLEAdaptor
579 css::uno::Reference
< css::embed::XEmbeddedObject
> mxIPRef
;
580 SfxObjectShell
& mrPers
;
581 const Graphic
* mpGraphic
;
583 /** Take ownership of a SdrOle2Objs OLE object
586 The SdrOle2Obj whose OLE object we want to take control of
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
603 The object is no longer owned by the adaptor after this call,
604 subsequent calls are an error and return false.
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
);
614 DrawingOLEAdaptor
& operator=(const DrawingOLEAdaptor
&) = delete;
615 DrawingOLEAdaptor(const DrawingOLEAdaptor
&rDoc
) = delete;
622 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */