1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19 #ifndef INCLUDED_SW_INC_DCONTACT_HXX
20 #define INCLUDED_SW_INC_DCONTACT_HXX
21
22 #include <svx/svdobj.hxx>
23 #include <svx/svdovirt.hxx>
24 #include "fmtanchr.hxx"
25 #include "frmfmt.hxx"
26 #include <list>
27 #include <vector>
28 #include <memory>
29
30 #include "calbck.hxx"
31 #include "anchoreddrawobject.hxx"
32
33 class SwFlyFrame;
34 class SwFrame;
35 class SwPageFrame;
36 class SwVirtFlyDrawObj;
37 class SwFlyDrawObj;
38 class SwRect;
39 class SwDrawContact;
40 struct SwPosition;
41 class SdrTextObj;
42 class SwContact;
43
44 /** The other way round: Search format for given object.
45 If object is a SwVirtFlyDrawObj the format will be obtained from it.
46 If not it is a simple DrawObject. It has a UserCall which
47 is client of the format we are looking for.
48 Implementation in dcontact.cxx. */
49 SW_DLLPUBLIC SwFrameFormat *FindFrameFormat( SdrObject *pObj );
FindFrameFormat(const SdrObject * pObj)50 inline const SwFrameFormat *FindFrameFormat( const SdrObject *pObj )
51 { return ::FindFrameFormat( const_cast<SdrObject*>(pObj) ); }
52 bool HasWrap( const SdrObject* pObj );
53
54 void setContextWritingMode( SdrObject* pObj, SwFrame const * pAnchor );
55
56 /// @return BoundRect plus distance.
57 SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj );
58
59 /// @return UserCall of goup object (if applicable).
60 SwContact* GetUserCall( const SdrObject* );
61
62 /// @return TRUE if the SrdObject is a Marquee object.
63 bool IsMarqueeTextObj( const SdrObject& rObj );
64
65 /// Base class for the following contact objects (frame + draw objects).
66 class SAL_DLLPUBLIC_RTTI SwContact : public SdrObjUserCall, public SwClient
67 {
68 /** boolean, indicating destruction of contact object
69 important note: boolean has to be set at the beginning of each destructor
70 in the subclasses using method <SetInDTOR()>. */
71 bool mbInDTOR;
72
73 /** method to move object to visible/invisible layer
74
75 Implementation for the public method <MoveObjToVisibleLayer(..)>
76 and <MoveObjToInvisibleLayer(..)>
77 If object is in invisible respectively visible layer, it's moved to
78 the corresponding visible respectively invisible layers.
79 For group object the members are individually moved to the corresponding
80 layer, because <SdrObjGroup::GetLayer()> does return 0, if members
81 aren't on the same layer as the group object, and
82 <SdrObjGroup::SetLayer(..)|NbcSetLayer(..)> sets also the layer of
83 the members.
84
85 @param _bToVisible
86 input parameter - boolean indicating, if object has to be moved to
87 visible (== true) or invisible (== false) layer.
88
89 @param _pDrawObj
90 input parameter, which will be changed - drawing object, which will
91 change its layer.
92 */
93 void MoveObjToLayer( const bool _bToVisible,
94 SdrObject* _pDrawObj );
95
96 protected:
97 void SetInDTOR();
98 virtual void SwClientNotify(const SwModify&, const SfxHint& rHint) override;
99
100 public:
101
102 /// For reader. Only the connection is created.
103 SwContact( SwFrameFormat *pToRegisterIn );
104 virtual ~SwContact() override;
105
106 virtual const SwAnchoredObject* GetAnchoredObj( const SdrObject* _pSdrObj ) const = 0;
107 virtual SwAnchoredObject* GetAnchoredObj( SdrObject* _pSdrObj ) = 0;
108
109 virtual const SdrObject *GetMaster() const = 0;
110 virtual SdrObject *GetMaster() = 0;
111
GetFormat()112 SwFrameFormat *GetFormat() { return static_cast<SwFrameFormat*>(GetRegisteredIn()); }
GetFormat() const113 const SwFrameFormat *GetFormat() const
114 { return static_cast<const SwFrameFormat*>(GetRegisteredIn()); }
115
IsInDTOR() const116 bool IsInDTOR() const { return mbInDTOR;}
117
118 /** method to move drawing object to corresponding visible layer
119
120 uses method <MoveObjToLayer(..)>
121
122 @param _pDrawObj
123 drawing object, which will be moved to the visible layer
124 */
125 virtual void MoveObjToVisibleLayer( SdrObject* _pDrawObj );
126
127 /** method to move drawing object to corresponding invisible layer
128
129 uses method <MoveObjToLayer(..)>
130
131 @param _pDrawObj
132 drawing object, which will be moved to the visible layer
133 */
134 virtual void MoveObjToInvisibleLayer( SdrObject* _pDrawObj );
135
136 /** some virtual helper methods for information
137 about the object (Writer fly frame resp. drawing object) */
GetAnchorFormat() const138 const SwFormatAnchor& GetAnchorFormat() const
139 {
140 assert( GetFormat() );
141
142 return GetFormat()->GetAnchor();
143 }
144
GetAnchorId() const145 RndStdIds GetAnchorId() const { return GetAnchorFormat().GetAnchorId(); }
ObjAnchoredAtPage() const146 bool ObjAnchoredAtPage() const { return GetAnchorId() == RndStdIds::FLY_AT_PAGE; }
ObjAnchoredAtFly() const147 bool ObjAnchoredAtFly() const { return GetAnchorId() == RndStdIds::FLY_AT_FLY; }
ObjAnchoredAtPara() const148 bool ObjAnchoredAtPara() const { return GetAnchorId() == RndStdIds::FLY_AT_PARA; }
ObjAnchoredAtChar() const149 bool ObjAnchoredAtChar() const { return GetAnchorId() == RndStdIds::FLY_AT_CHAR; }
ObjAnchoredAsChar() const150 bool ObjAnchoredAsChar() const { return GetAnchorId() == RndStdIds::FLY_AS_CHAR; }
151
GetContentAnchor() const152 const SwPosition& GetContentAnchor() const
153 {
154 assert( GetAnchorFormat().GetContentAnchor() );
155 return *(GetAnchorFormat().GetContentAnchor());
156 }
157
158 /** get data collection of anchored objects, handled by with contact */
159 virtual void GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const = 0;
160
161 /** get minimum order number of anchored objects handled by with contact
162
163 */
164 sal_uInt32 GetMinOrdNum() const;
165
166 /** get maximum order number of anchored objects handled by with contact
167
168 */
169 sal_uInt32 GetMaxOrdNum() const;
170 };
171
172 /** ContactObject for connection between frames (or their formats respectively)
173 in SwClient and the drawobjects of Drawing (DsrObjUserCall). */
174
175 class SW_DLLPUBLIC SwFlyDrawContact final : public SwContact
176 {
177 private:
178 typedef std::unique_ptr< SwFlyDrawObj, SdrObjectFreeOp > SwFlyDrawObjPtr;
179
180 SwFlyDrawObjPtr mpMasterObj;
181 void SwClientNotify(const SwModify&, const SfxHint& rHint) override;
182 sal_uInt32 GetOrdNumForNewRef(const SwFlyFrame* pFly);
183
184 public:
185
186 /// Creates DrawObject and registers it with the Model.
187 SwFlyDrawContact(SwFlyFrameFormat* pToRegisterIn, SdrModel& rTargetModel);
188 static SwVirtFlyDrawObj* CreateNewRef(SwFlyFrame* pFly, SwFlyFrameFormat* pFormat);
189 virtual ~SwFlyDrawContact() override;
190
191 virtual const SwAnchoredObject* GetAnchoredObj( const SdrObject* _pSdrObj ) const override;
192 virtual SwAnchoredObject* GetAnchoredObj( SdrObject* _pSdrObj ) override;
193
GetMaster() const194 virtual const SdrObject* GetMaster() const override
195 { return const_cast<SwFlyDrawContact*>(this)->GetMaster(); };
196 virtual SdrObject* GetMaster() override;
197
198 /** override methods to control Writer fly frames,
199 which are linked, and to assure that all objects anchored at/inside the
200 Writer fly frame are also made visible/invisible. */
201 virtual void MoveObjToVisibleLayer( SdrObject* _pDrawObj ) override;
202 virtual void MoveObjToInvisibleLayer( SdrObject* _pDrawObj ) override;
203
204 /** get data collection of anchored objects handled by with contact */
205 virtual void GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const override;
206 };
207
208 /** new class for re-direct methods calls at a 'virtual'
209 drawing object to its referenced object. */
210 class SwDrawVirtObj final : public SdrVirtObj
211 {
212 private:
213 // data for connection to writer layout
214 /** anchored drawing object instance for the
215 'virtual' drawing object */
216 SwAnchoredDrawObject maAnchoredDrawObj;
217
218 /** writer-drawing contact object the 'virtual' drawing object is controlled by.
219 This object is also the <UserCall> of the drawing object, if it's
220 inserted into the drawing layer. */
221 SwDrawContact& mrDrawContact;
222
223 /** AW: Need own sdr::contact::ViewContact since AnchorPos from parent is
224 not used but something own (top left of new SnapRect minus top left
225 of original SnapRect) */
226 virtual std::unique_ptr<sdr::contact::ViewContact> CreateObjectSpecificViewContact() override;
227
228 // protected destructor
229 virtual ~SwDrawVirtObj() override;
230
231 public:
232 SwDrawVirtObj(
233 SdrModel& rSdrModel,
234 SdrObject& _rNewObj,
235 SwDrawContact& _rDrawContact);
236
237 /// access to offset
238 virtual Point GetOffset() const override;
239
240 virtual SwDrawVirtObj* CloneSdrObject(SdrModel& rTargetModel) const override;
241 SwDrawVirtObj& operator= (const SwDrawVirtObj& rObj);
242
243 /// connection to writer layout
GetAnchoredObj() const244 const SwAnchoredObject& GetAnchoredObj() const { return maAnchoredDrawObj; }
AnchoredObj()245 SwAnchoredObject& AnchoredObj() { return maAnchoredDrawObj; }
246 const SwFrame* GetAnchorFrame() const;
247 SwFrame* AnchorFrame();
248 void RemoveFromWriterLayout();
249
250 /// connection to drawing layer
251 void AddToDrawingPage();
252 void RemoveFromDrawingPage();
253
254 /** is 'virtual' drawing object connected to writer layout and
255 / to drawing layer. */
256 bool IsConnected() const;
257
258 virtual void NbcSetAnchorPos(const Point& rPnt) override;
259
260 /// All overridden methods which need to use the offset
261 virtual void RecalcBoundRect() override;
262 virtual ::basegfx::B2DPolyPolygon TakeXorPoly() const override;
263 virtual ::basegfx::B2DPolyPolygon TakeContour() const override;
264 virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
265 virtual void NbcMove(const Size& rSiz) override;
266 virtual void NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) override;
267 virtual void NbcRotate(const Point& rRef, long nAngle, double sn, double cs) override;
268 virtual void NbcMirror(const Point& rRef1, const Point& rRef2) override;
269 virtual void NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear) override;
270 virtual void Move(const Size& rSiz) override;
271 virtual void Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative = true) override;
272 virtual void Rotate(const Point& rRef, long nAngle, double sn, double cs) override;
273 virtual void Mirror(const Point& rRef1, const Point& rRef2) override;
274 virtual void Shear(const Point& rRef, long nAngle, double tn, bool bVShear) override;
275 virtual void RecalcSnapRect() override;
276 virtual const tools::Rectangle& GetSnapRect() const override;
277 virtual void SetSnapRect(const tools::Rectangle& rRect) override;
278 virtual void NbcSetSnapRect(const tools::Rectangle& rRect) override;
279 virtual const tools::Rectangle& GetLogicRect() const override;
280 virtual void SetLogicRect(const tools::Rectangle& rRect) override;
281 virtual void NbcSetLogicRect(const tools::Rectangle& rRect) override;
282 virtual Point GetSnapPoint(sal_uInt32 i) const override;
283 virtual Point GetPoint(sal_uInt32 i) const override;
284 virtual void NbcSetPoint(const Point& rPnt, sal_uInt32 i) override;
285
286 virtual bool HasTextEdit() const override;
287
288 virtual SdrLayerID GetLayer() const override;
289 virtual void NbcSetLayer(SdrLayerID nLayer) override;
290 virtual void SetLayer(SdrLayerID nLayer) override;
291
292 virtual void SetBoundRectDirty() override;
293 virtual const tools::Rectangle& GetCurrentBoundRect() const override;
294 virtual const tools::Rectangle& GetLastBoundRect() const override;
295 };
296
297 bool CheckControlLayer( const SdrObject *pObj );
298
299 /** ContactObject for connection of formats as representatives of draw objects
300 in SwClient and the objects themselves in Drawing (SDrObjUserCall). */
301
302 typedef std::unique_ptr< SwDrawVirtObj, SdrObjectFreeOp > SwDrawVirtObjPtr;
303
304 class SAL_DLLPUBLIC_RTTI SwDrawContact final : public SwContact
305 {
306 private:
307 /** anchored drawing object instance for the
308 'master' drawing object */
309 SwAnchoredDrawObject maAnchoredDrawObj;
310
311 /** container for 'virtual' drawing object supporting drawing objects in headers/footers. */
312 std::vector< SwDrawVirtObjPtr > maDrawVirtObjs;
313
314 /** boolean indicating set 'master' drawing
315 object has been cleared. */
316 bool mbMasterObjCleared : 1;
317
318 /** internal flag to indicate that disconnect
319 from layout is in progress */
320 bool mbDisconnectInProgress : 1;
321
322 /** Needed data for handling of nested <SdrObjUserCall> events in
323 method <Changed_(..)> */
324 bool mbUserCallActive : 1;
325 /** event type, which is handled for <mpSdrObjHandledByCurrentUserCall>.
326 Note: value only valid, if <mbUserCallActive> is true. */
327 SdrUserCallType meEventTypeOfCurrentUserCall;
328
329 friend class NestedUserCallHdl;
330
331
332 void RemoveAllVirtObjs();
333
334 void InvalidateObjs_( const bool _bUpdateSortedObjsList = false );
335
336 SwDrawContact( const SwDrawContact& ) = delete;
337 SwDrawContact& operator=( const SwDrawContact& ) = delete;
338
339 virtual void SwClientNotify(const SwModify&, const SfxHint& rHint) override;
340
341 public:
342
343 SwDrawContact( SwFrameFormat *pToRegisterIn, SdrObject *pObj );
344 virtual ~SwDrawContact() override;
345
346 virtual const SwAnchoredObject* GetAnchoredObj( const SdrObject* _pSdrObj ) const override;
347 virtual SwAnchoredObject* GetAnchoredObj( SdrObject* _pSdrObj ) override;
348
GetMaster() const349 virtual const SdrObject* GetMaster() const override
350 { return const_cast<SwDrawContact*>(this)->GetMaster(); };
351 virtual SdrObject* GetMaster() override;
352
353 const SwFrame* GetAnchorFrame( const SdrObject* _pDrawObj = nullptr ) const;
354 SwFrame* GetAnchorFrame( SdrObject const * _pDrawObj = nullptr );
355
GetPageFrame() const356 const SwPageFrame* GetPageFrame() const
357 {
358 return maAnchoredDrawObj.GetPageFrame();
359 }
GetPageFrame()360 SwPageFrame* GetPageFrame()
361 {
362 return maAnchoredDrawObj.GetPageFrame();
363 }
364 void ChkPage();
365 SwPageFrame* FindPage( const SwRect &rRect );
366
367 /** Inserts SdrObject in the arrays of the layout ((SwPageFrame and SwFrame).
368 The anchor is determined according to the attribute SwFormatAnchor.
369 If required the object gets unregistered with the old anchor. */
370 void ConnectToLayout( const SwFormatAnchor *pAnch = nullptr );
371 /** method to insert 'master' drawing object
372 into drawing page */
373 void InsertMasterIntoDrawPage();
374
375 void DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer = true );
376 /** disconnect for a dedicated drawing object -
377 could be 'master' or 'virtual'. */
378 void DisconnectObjFromLayout( SdrObject* _pDrawObj );
379 /** method to remove 'master' drawing object
380 from drawing page.
381 To be used by the undo for delete of object. Call it after method
382 <DisconnectFromLayout( bool = true )> is already performed.
383 Note: <DisconnectFromLayout( bool )> no longer removes the 'master'
384 drawing object from drawing page. */
385 void RemoveMasterFromDrawPage();
386
387 /** get drawing object ('master' or 'virtual')
388 by frame. */
389 SdrObject* GetDrawObjectByAnchorFrame( const SwFrame& _rAnchorFrame );
390
391 /// Virtual methods of SdrObjUserCall.
392 virtual void Changed(const SdrObject& rObj, SdrUserCallType eType, const tools::Rectangle& rOldBoundRect) override;
393
394 /** Used by Changed() and by UndoDraw.
395 Notifies paragraphs that have to get out of the way. */
396 void Changed_(const SdrObject& rObj, SdrUserCallType eType, const tools::Rectangle* pOldBoundRect);
397
398 /// Moves all SW-connections to new Master)
399 void ChangeMasterObject( SdrObject *pNewMaster );
400
401 SwDrawVirtObj* AddVirtObj();
402
403 void NotifyBackgrdOfAllVirtObjs( const tools::Rectangle* pOldBoundRect );
404
405 /** get data collection of anchored objects, handled by with contact */
406
407 static void GetTextObjectsFromFormat( std::list<SdrTextObj*>&, SwDoc* );
408 virtual void GetAnchoredObjs( std::vector<SwAnchoredObject*>& _roAnchoredObjs ) const override;
409 };
410
411 #endif
412
413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
414