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 .
22 #include <cppuhelper/weak.hxx>
23 #include <svl/stylesheetuser.hxx>
24 #include <vcl/prntypes.hxx>
25 #include <svl/itemset.hxx>
26 #include <svx/sdrpageuser.hxx>
27 #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
28 #include <svx/sdrmasterpagedescriptor.hxx>
29 #include <svx/svxdllapi.h>
30 #include <com/sun/star/container/XIndexAccess.hpp>
31 #include <com/sun/star/drawing/XDrawPage.hpp>
32 #include <svx/svdobj.hxx>
33 #include <unotools/weakref.hxx>
38 #include <tools/UniqueID.hxx>
41 namespace model
{ class Theme
; }
42 namespace reportdesign
{ class OSection
; }
43 namespace sdr::contact
{ class ViewContact
; }
44 namespace sdr::annotation
{ class Annotation
; }
53 class SvxUnoDrawPagesAccess
;
55 ////////////////////////////////////////////////////////////////////////////////////////////////////
59 // SdrPage -> see continuation there
62 class SVXCORE_DLLPUBLIC SdrObjList
64 friend class SdrObjListIter
;
65 friend class SdrEditView
;
68 SdrObjList(const SdrObjList
& rSrcList
) = delete;
69 SdrObjList
&operator=(const SdrObjList
& rSrcList
) = delete;
72 SAL_DLLPRIVATE
void RecalcRects();
75 /// simple ActionChildInserted forwarder to have it on a central place
76 SAL_DLLPRIVATE
static void impChildInserted(SdrObject
const & rChild
);
78 // tdf#116879 Clear SdrObjList, no Undo done. Used from destructor, but also
80 SAL_DLLPRIVATE
void impClearSdrObjList();
83 // protected constructor to make clear that this class should only
84 // be used as base for derivations, not naked. See getSdrModelFromSdrObjList
85 // which is pure virtual to force this, too
86 SAL_DLLPRIVATE
SdrObjList();
87 SAL_DLLPRIVATE
virtual ~SdrObjList();
90 // SdrModel/SdrPage access on SdrObjList level
91 virtual SdrPage
* getSdrPageFromSdrObjList() const;
92 virtual SdrObject
* getSdrObjectFromSdrObjList() const;
94 SAL_DLLPRIVATE
void CopyObjects(const SdrObjList
& rSrcList
);
95 static OString
GetObjectRectangles(const SdrObjList
& rSrcList
);
97 // tdf#116879 clean up everything (without Undo), plus broadcasting
98 // changes. Split to this call and a private one (impClearSdrObjList)
99 // that allows cleanup without broadcasting in the destructor
100 void ClearSdrObjList();
102 /// recalculate order numbers / ZIndex
103 void RecalcObjOrdNums();
104 bool IsObjOrdNumsDirty() const { return mbObjOrdNumsDirty
; }
105 virtual void NbcInsertObject(SdrObject
* pObj
, size_t nPos
=SAL_MAX_SIZE
);
106 virtual void InsertObject(SdrObject
* pObj
, size_t nPos
=SAL_MAX_SIZE
);
107 SAL_DLLPRIVATE
void sort( std::vector
<sal_Int32
>& sortOrder
);
109 void InsertObjectThenMakeNameUnique(SdrObject
* pObj
);
110 void InsertObjectThenMakeNameUnique(SdrObject
* pObj
, std::unordered_set
<rtl::OUString
>& rNameSet
, size_t nPos
=SAL_MAX_SIZE
);
112 /// remove from list without delete
113 virtual rtl::Reference
<SdrObject
> NbcRemoveObject(size_t nObjNum
);
114 virtual rtl::Reference
<SdrObject
> RemoveObject(size_t nObjNum
);
116 /// Replace existing object by different one.
117 /// Same as Remove(old)+Insert(new) but faster because the order numbers
118 /// do not have to be set dirty.
119 virtual rtl::Reference
<SdrObject
> ReplaceObject(SdrObject
* pNewObj
, size_t nObjNum
);
121 /// Modify ZOrder of an SdrObject
122 virtual SdrObject
* SetObjectOrdNum(size_t nOldObjNum
, size_t nNewObjNum
);
124 /// Modify ZOrder of an SdrObject, object must already be in the list
125 SAL_DLLPRIVATE
void SetExistingObjectOrdNum(SdrObject
* pExistingObj
, size_t nNewObjNum
);
127 void SetSdrObjListRectsDirty();
129 SAL_DLLPRIVATE
const tools::Rectangle
& GetAllObjSnapRect() const;
130 const tools::Rectangle
& GetAllObjBoundRect() const;
132 /// reformat all text objects, e.g. when changing printer
133 SAL_DLLPRIVATE
void NbcReformatAllTextObjects();
134 SAL_DLLPRIVATE
void ReformatAllTextObjects();
136 /** #103122# reformats all edge objects that are connected to other objects */
137 SAL_DLLPRIVATE
void ReformatAllEdgeObjects();
139 /// convert attributes of the style to hard formatting
140 SAL_DLLPRIVATE
void BurnInStyleSheetAttributes();
142 size_t GetObjCount() const;
143 SdrObject
* GetObj(size_t nNum
) const;
144 SdrObject
* GetObjByName(std::u16string_view sName
) const;
146 /// linked page or linked group object
147 virtual bool IsReadOnly() const;
149 /** Makes the object list flat, i.e. the object list content are
152 This method travels recursively over all group objects in this
153 list, extracts the content, inserts it flat to the list and
154 removes the group object afterwards.
156 SAL_DLLPRIVATE
void FlattenGroups();
158 /** Ungroup the object at the given index
160 This method ungroups the content of the group object at the
161 given index, i.e. the content is put flat into the object list
162 (if the object at the given index is no group, this method is
163 a no-op). If the group itself contains group objects, the
164 operation is performed recursively, such that the content of
165 the given object contains no groups afterwards.
167 SAL_DLLPRIVATE
void UnGroupObj( size_t nObjNum
);
169 /** Return whether there is an explicit, user defined, object navigation
170 order. When there is one this method returns <TRUE/> and the
171 GetObjectForNavigationPosition() and
172 SdrObject::GetNavigationPosition() methods will return values
173 different from those returned by SdrObject::GetOrdNum() and
176 bool HasObjectNavigationOrder() const;
178 /** Set the navigation position of the given object to the specified
179 value. Note that this changes the navigation position for all
180 objects on or following the old or new position.
182 void SetObjectNavigationPosition (
184 const sal_uInt32 nNewNavigationPosition
);
186 /** Return the object for the given navigation position. When there is
187 a user defined navigation order, i.e. mxNavigationOrder is not NULL,
188 then that is used to look up the object. Otherwise the z-order is
189 used by looking up the object in maList.
190 @param nNavigationPosition
191 Valid values include 0 and are smaller than the number of
192 objects as returned by GetObjCount().
194 The returned pointer is NULL for invalid positions.
196 SAL_DLLPRIVATE SdrObject
* GetObjectForNavigationPosition (const sal_uInt32 nNavigationPosition
) const;
198 /** Restore the navigation order to that defined by the z-order.
200 void ClearObjectNavigationOrder();
202 /** Set the navigation position of all SdrObjects to their position in
203 the mxNavigationOrder list. This method returns immediately when no
206 This method returns <TRUE/> when the navigation positions stored
207 in SdrObjects are up to date.
208 It returns <FALSE/> when the navigation positions are not valid,
209 for example because no explicit navigation order has been
210 defined, i.e. HasObjectNavigationOrder() would return <FALSE/>.
212 SAL_DLLPRIVATE
bool RecalcNavigationPositions();
214 /** Set the navigation order to the one defined by the given list of
217 When this is an empty reference then the navigation order is
218 reset to the z-order. The preferred way to do this, however, is
219 to call ClearObjectNavigationOrder().
220 Otherwise this list is expected to contain all the shapes in the
223 void SetNavigationOrder (const css::uno::Reference
<
224 css::container::XIndexAccess
>& rxOrder
);
226 SAL_DLLPRIVATE
virtual void dumpAsXml(xmlTextWriterPtr pWriter
) const;
228 typedef std::deque
<rtl::Reference
<SdrObject
>> SdrObjectDeque
;
230 SdrObjectDeque::const_iterator
begin() const { return maList
.begin(); }
231 SdrObjectDeque::const_iterator
end() const { return maList
.end(); }
232 SdrObjectDeque::const_reverse_iterator
rbegin() const { return maList
.rbegin(); }
233 SdrObjectDeque::const_reverse_iterator
rend() const { return maList
.rend(); }
236 tools::Rectangle maSdrObjListOutRect
;
237 tools::Rectangle maSdrObjListSnapRect
;
238 SdrObjectDeque maList
;
239 /// This list, if it exists, defines the navigation order. If it does
240 /// not exist then maList defines the navigation order.
241 std::optional
<std::vector
<unotools::WeakReference
<SdrObject
>>> mxNavigationOrder
;
242 bool mbObjOrdNumsDirty
;
244 /// This flag is <TRUE/> when the mpNavigation list has been changed but
245 /// the indices of the referenced SdrObjects still have their old values.
246 bool mbIsNavigationOrderDirty
;
248 /** Insert an SdrObject into maList. Do not modify the maList member
251 The object to insert into the object list.
252 @param nInsertPosition
253 The given object is inserted before the object at this
254 position. Valid values include 0 (the object is inserted at the
255 head of the list) and the number of objects in the list as
256 returned by GetObjCount() (the object is inserted at the end of
259 SAL_DLLPRIVATE
void InsertObjectIntoContainer (
261 const sal_uInt32 nInsertPosition
);
263 /** Replace an object in the object list.
265 The new object that replaces the one in the list at the
267 @param nObjectPosition
268 The object at this position in the object list is replaced by
269 the given object. Valid values include 0 and are smaller than
270 the number of objects in the list.
272 SAL_DLLPRIVATE
void ReplaceObjectInContainer (
274 const sal_uInt32 nObjectPosition
);
276 /** Remove an object from the object list.
277 The object list has to contain at least one element.
278 @param nObjectPosition
279 The object at this position is removed from the object list.
280 Valid values include 0 and are smaller than the number of
283 SAL_DLLPRIVATE
void RemoveObjectFromContainer (
284 const sal_uInt32 nObjectPosition
);
286 SAL_DLLPRIVATE
void ImplReformatAllEdgeObjects(const SdrObjList
& );
289 // Used for all methods which return a page number
290 #define SDRPAGE_NOTFOUND 0xFFFF
292 /// for the snap-to-grid in Writer
293 class SdrPageGridFrame
295 tools::Rectangle m_aPaper
;
296 tools::Rectangle m_aUserArea
;
298 SdrPageGridFrame(const tools::Rectangle
& rPaper
, const tools::Rectangle
& rUser
): m_aPaper(rPaper
), m_aUserArea(rUser
) {}
299 const tools::Rectangle
& GetPaperRect() const { return m_aPaper
; }
300 const tools::Rectangle
& GetUserArea() const { return m_aUserArea
; }
303 class SVXCORE_DLLPUBLIC SdrPageGridFrameList final
305 std::vector
<SdrPageGridFrame
*> m_aList
;
307 SdrPageGridFrameList(const SdrPageGridFrameList
& rSrcList
) = delete;
308 void operator=(const SdrPageGridFrameList
& rSrcList
) = delete;
309 SdrPageGridFrame
* GetObject(sal_uInt16 i
) const { return m_aList
[i
]; }
312 SdrPageGridFrameList() {}
313 ~SdrPageGridFrameList() { Clear(); }
315 sal_uInt16
GetCount() const { return sal_uInt16(m_aList
.size()); }
316 void Insert(const SdrPageGridFrame
& rGF
) { m_aList
.push_back(new SdrPageGridFrame(rGF
)); }
317 SdrPageGridFrame
& operator[](sal_uInt16 nPos
) { return *GetObject(nPos
); }
318 const SdrPageGridFrame
& operator[](sal_uInt16 nPos
) const { return *GetObject(nPos
); }
321 // class SdrPageProperties
322 class SVXCORE_DLLPUBLIC SdrPageProperties final
: public SfxListener
, public svl::StyleSheetUser
327 SfxStyleSheet
* mpStyleSheet
;
328 std::shared_ptr
<model::Theme
> mpTheme
;
329 SfxItemSet maProperties
;
332 void ImpRemoveStyleSheet();
333 void ImpAddStyleSheet(SfxStyleSheet
& rNewStyleSheet
);
335 SdrPageProperties
& operator=(const SdrPageProperties
& rCandidate
) = delete;
337 void sendLOKitThemeChangedCallback();
339 // construct/destruct
340 SdrPageProperties(SdrPage
& rSdrPage
);
341 virtual ~SdrPageProperties() override
;
343 // Notify(...) from baseclass SfxListener
344 virtual void Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
346 virtual bool isUsedByModel() const override
;
349 const SfxItemSet
& GetItemSet() const { return maProperties
;}
350 void PutItemSet(const SfxItemSet
& rSet
);
351 void PutItem(const SfxPoolItem
& rItem
);
352 void ClearItem(const sal_uInt16 nWhich
= 0);
355 void SetStyleSheet(SfxStyleSheet
* pStyleSheet
);
356 SfxStyleSheet
* GetStyleSheet() const { return mpStyleSheet
;}
358 void setTheme(std::shared_ptr
<model::Theme
> const& pTheme
);
359 std::shared_ptr
<model::Theme
> const& getTheme() const;
361 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
366 A SdrPage contains exactly one SdrObjList and a description of the physical
367 page dimensions (size / margins). The latter is required to "catch" objects
368 during drag-and-drop.
369 The SdrPage allows (via SdrObjList) inserting and removing SdrObjects,
370 as well as moving them into the foreground or background.
371 Also it's possible to request and directly set the order number (ZOrder)
375 ////////////////////////////////////////////////////////////////////////////////////////////////////
385 class SVXCORE_DLLPUBLIC SdrPage
: public SdrObjList
, public cppu::OWeakObject
388 friend class SdrModel
;
389 friend class SvxUnoDrawPagesAccess
;
391 // this class uses its own UNO wrapper
392 // and thus has to set mxUnoPage (it also relies on mxUnoPage not being WeakRef)
393 friend class reportdesign::OSection
;
395 SdrPage
& operator=(const SdrPage
&) = delete;
396 SdrPage(const SdrPage
&) = delete;
398 // start PageUser section
400 // #111111# PageUser section
401 sdr::PageUserVector maPageUsers
;
403 std::unique_ptr
<sdr::contact::ViewContact
> mpViewContact
;
406 void AddPageUser(sdr::PageUser
& rNewUser
);
407 void RemovePageUser(sdr::PageUser
& rOldUser
);
408 const sdr::PageUserVector
& GetPageUsers() const { return maPageUsers
; };
410 // SdrModel access on SdrPage level
411 SdrModel
& getSdrModelFromSdrPage() const { return mrSdrModelFromSdrPage
; }
414 std::unique_ptr
<sdr::contact::ViewContact
> CreateObjectSpecificViewContact();
416 const sdr::contact::ViewContact
& GetViewContact() const;
417 sdr::contact::ViewContact
& GetViewContact();
419 // #110094# DrawContact support: Methods for handling Page changes
420 void ActionChanged();
423 // the SdrModel this page was created with, unchanged during SdrPage lifetime
424 SdrModel
& mrSdrModelFromSdrPage
;
427 std::vector
<rtl::Reference
<sdr::annotation::Annotation
>> maAnnotations
;
430 tools::Long mnWidth
; // page size
431 tools::Long mnHeight
; // page size
432 sal_Int32 mnBorderLeft
; // left page margin
433 sal_Int32 mnBorderUpper
; // top page margin
434 sal_Int32 mnBorderRight
; // right page margin
435 sal_Int32 mnBorderLower
; // bottom page margin
437 bool mbBackgroundFullSize
= false; ///< Background object to represent the whole page.
439 std::unique_ptr
<SdrLayerAdmin
> mpLayerAdmin
;
440 std::unique_ptr
<SdrPageProperties
> mpSdrPageProperties
;
441 css::uno::Reference
< css::uno::XInterface
> mxUnoPage
;
444 SdrPageProperties
& getSdrPageProperties();
445 const SdrPageProperties
& getSdrPageProperties() const;
446 const SdrPageProperties
* getCorrectSdrPageProperties() const;
449 // new MasterPageDescriptorVector
450 std::unique_ptr
<sdr::MasterPageDescriptor
> mpMasterPageDescriptor
;
452 sal_uInt16 m_nPageNum
;
454 bool mbMaster
: 1; // flag if this is a MasterPage
456 bool mbObjectsNotPersistent
: 1;
459 bool mbPageBorderOnlyLeftRight
: 1;
461 void SetUnoPage(css::uno::Reference
<css::drawing::XDrawPage
> const&);
462 virtual css::uno::Reference
< css::uno::XInterface
> createUnoPage();
464 // Copying of pages is split into two parts: construction and copying of page objects,
465 // because the copying might need access to fully initialized page. CloneSdrPage() is responsible
466 // to call lateInit() after copy-construction of a new object. Any initialization in derived
467 // classes that needs access to the page objects must be deferred to lateInit. And it must
468 // call lateInit() of its parent class.
469 void lateInit(const SdrPage
& rSrcPage
);
472 explicit SdrPage(SdrModel
& rModel
, bool bMasterPage
=false);
473 virtual ~SdrPage() override
;
475 virtual rtl::Reference
<SdrPage
> CloneSdrPage(SdrModel
& rTargetModel
) const;
476 bool IsMasterPage() const { return mbMaster
; }
477 void SetInserted(bool bNew
= true);
478 bool IsInserted() const { return mbInserted
; }
481 // derived from SdrObjList, returns this
482 virtual SdrPage
* getSdrPageFromSdrObjList() const override
;
484 // #i68775# React on PageNum changes (from Model in most cases)
485 void SetPageNum(sal_uInt16 nNew
);
486 sal_uInt16
GetPageNum() const;
488 // #i93597# Allow page border definition to not be the full rectangle but to
489 // use only the left and right vertical edges (reportdesigner)
490 void setPageBorderOnlyLeftRight(bool bNew
) { mbPageBorderOnlyLeftRight
= bNew
; }
491 bool getPageBorderOnlyLeftRight() const { return mbPageBorderOnlyLeftRight
; }
493 virtual void SetSize(const Size
& aSiz
);
494 Size
GetSize() const;
495 virtual void SetOrientation(Orientation eOri
);
496 virtual Orientation
GetOrientation() const;
497 tools::Long
GetWidth() const;
498 tools::Long
GetHeight() const;
499 virtual void SetBorder(sal_Int32 nLft
, sal_Int32 nUpp
, sal_Int32 nRgt
, sal_Int32 Lwr
);
500 virtual void SetLeftBorder(sal_Int32 nBorder
);
501 virtual void SetUpperBorder(sal_Int32 nBorder
);
502 virtual void SetRightBorder(sal_Int32 nBorder
);
503 virtual void SetLowerBorder(sal_Int32 nBorder
);
504 sal_Int32
GetLeftBorder() const;
505 sal_Int32
GetUpperBorder() const;
506 sal_Int32
GetRightBorder() const;
507 sal_Int32
GetLowerBorder() const;
508 sal_uInt64
GetUniqueID() const { return maUniqueID
.getID(); }
509 void SetBackgroundFullSize(bool bIn
);
510 bool IsBackgroundFullSize() const;
512 // New MasterPage interface
513 bool TRG_HasMasterPage() const { return (nullptr != mpMasterPageDescriptor
); }
514 void TRG_SetMasterPage(SdrPage
& rNew
);
515 void TRG_ClearMasterPage();
516 SdrPage
& TRG_GetMasterPage() const;
517 const SdrLayerIDSet
& TRG_GetMasterPageVisibleLayers() const;
518 void TRG_SetMasterPageVisibleLayers(const SdrLayerIDSet
& rNew
);
519 sdr::contact::ViewContact
& TRG_GetMasterPageDescriptorViewContact() const;
521 void MakePageObjectsNamesUnique();
524 void TRG_ImpMasterPageRemoved(const SdrPage
& rRemovedPage
);
527 /// changing the layers does not set the modified-flag!
528 const SdrLayerAdmin
& GetLayerAdmin() const;
529 SdrLayerAdmin
& GetLayerAdmin();
531 /// for snap-to-grid in Writer, also for AlignObjects if 1 object is marked
532 /// if pRect != null, then the pages that are intersected by this Rect,
533 /// otherwise the visible pages
534 virtual const SdrPageGridFrameList
* GetGridFrameList(const SdrPageView
* pPV
, const tools::Rectangle
* pRect
) const;
536 css::uno::Reference
< css::uno::XInterface
> const & getUnoPage();
538 virtual SfxStyleSheet
* GetTextStyleSheetForObject( SdrObject
* pObj
) const;
540 /** *deprecated* returns an averaged background color of this page */
541 // #i75566# GetBackgroundColor -> GetPageBackgroundColor
542 Color
GetPageBackgroundColor() const;
544 /** *deprecated* returns an averaged background color of this page */
545 // #i75566# GetBackgroundColor -> GetPageBackgroundColor and bScreenDisplay hint value
546 Color
GetPageBackgroundColor( SdrPageView
const * pView
, bool bScreenDisplay
= true) const;
548 /** this method returns true if the object from the ViewObjectContact should
549 be visible on this page while rendering.
550 bEdit selects if visibility test is for an editing view or a final render,
553 virtual bool checkVisibility(
554 const sdr::contact::ViewObjectContact
& rOriginal
,
555 const sdr::contact::DisplayInfo
& rDisplayInfo
,
558 void dumpAsXml(xmlTextWriterPtr pWriter
) const override
;
561 virtual rtl::Reference
<sdr::annotation::Annotation
> createAnnotation();
562 virtual void addAnnotation(rtl::Reference
<sdr::annotation::Annotation
> const& xAnnotation
, int nIndex
= -1);
563 virtual void addAnnotationNoNotify(rtl::Reference
<sdr::annotation::Annotation
> const& xAnnotation
, int nIndex
= -1);
564 virtual void removeAnnotation(rtl::Reference
<sdr::annotation::Annotation
> const& xAnnotation
);
565 virtual void removeAnnotationNoNotify(rtl::Reference
<sdr::annotation::Annotation
> const& xAnnotation
);
567 std::vector
<rtl::Reference
<sdr::annotation::Annotation
>> const& getAnnotations() const;
570 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */