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