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 
20 #include "objectformatterlayfrm.hxx"
21 #include <anchoredobject.hxx>
22 #include <sortedobjs.hxx>
23 #include <pagefrm.hxx>
24 
25 #include <layact.hxx>
26 #include <osl/diagnose.h>
27 
SwObjectFormatterLayFrame(SwLayoutFrame & _rAnchorLayFrame,const SwPageFrame & _rPageFrame,SwLayAction * _pLayAction)28 SwObjectFormatterLayFrame::SwObjectFormatterLayFrame( SwLayoutFrame& _rAnchorLayFrame,
29                                                   const SwPageFrame& _rPageFrame,
30                                                   SwLayAction* _pLayAction )
31     : SwObjectFormatter( _rPageFrame, _pLayAction ),
32       mrAnchorLayFrame( _rAnchorLayFrame )
33 {
34 }
35 
~SwObjectFormatterLayFrame()36 SwObjectFormatterLayFrame::~SwObjectFormatterLayFrame()
37 {
38 }
39 
CreateObjFormatter(SwLayoutFrame & _rAnchorLayFrame,const SwPageFrame & _rPageFrame,SwLayAction * _pLayAction)40 std::unique_ptr<SwObjectFormatterLayFrame> SwObjectFormatterLayFrame::CreateObjFormatter(
41                                                 SwLayoutFrame& _rAnchorLayFrame,
42                                                 const SwPageFrame& _rPageFrame,
43                                                 SwLayAction* _pLayAction )
44 {
45     if ( !_rAnchorLayFrame.IsPageFrame() &&
46          !_rAnchorLayFrame.IsFlyFrame() )
47     {
48         OSL_FAIL( "<SwObjectFormatterLayFrame::CreateObjFormatter(..)> - unexpected type of anchor frame " );
49         return nullptr;
50     }
51 
52     std::unique_ptr<SwObjectFormatterLayFrame> pObjFormatter;
53 
54     // create object formatter, if floating screen objects are registered at
55     // given anchor layout frame.
56     if ( _rAnchorLayFrame.GetDrawObjs() ||
57          ( _rAnchorLayFrame.IsPageFrame() &&
58             static_cast<SwPageFrame&>(_rAnchorLayFrame).GetSortedObjs() ) )
59     {
60         pObjFormatter.reset(
61             new SwObjectFormatterLayFrame( _rAnchorLayFrame, _rPageFrame, _pLayAction ));
62     }
63 
64     return pObjFormatter;
65 }
66 
GetAnchorFrame()67 SwFrame& SwObjectFormatterLayFrame::GetAnchorFrame()
68 {
69     return mrAnchorLayFrame;
70 }
71 
72 // #i40147# - add parameter <_bCheckForMovedFwd>.
73 // Not relevant for objects anchored at layout frame.
DoFormatObj(SwAnchoredObject & _rAnchoredObj,const bool)74 bool SwObjectFormatterLayFrame::DoFormatObj( SwAnchoredObject& _rAnchoredObj,
75                                            const bool )
76 {
77     FormatObj_( _rAnchoredObj );
78 
79     // #124218# - consider that the layout action has to be
80     // restarted due to a deleted page frame.
81     return GetLayAction() == nullptr || !GetLayAction()->IsAgain();
82 }
83 
DoFormatObjs()84 bool SwObjectFormatterLayFrame::DoFormatObjs()
85 {
86     bool bSuccess = FormatObjsAtFrame_();
87 
88     if ( bSuccess && GetAnchorFrame().IsPageFrame() )
89     {
90         // anchor layout frame is a page frame.
91         // Thus, format also all anchored objects, which are registered at
92         // this page frame, whose 'anchor' isn't on this page frame and whose
93         // anchor frame is valid.
94         bSuccess = AdditionalFormatObjsOnPage();
95     }
96 
97     return bSuccess;
98 }
99 
100 /** method to format all anchored objects, which are registered at
101     the page frame, whose 'anchor' isn't on this page frame and whose
102     anchor frame is valid.
103 
104     OD 2004-07-02 #i28701#
105 */
AdditionalFormatObjsOnPage()106 bool SwObjectFormatterLayFrame::AdditionalFormatObjsOnPage()
107 {
108     if ( !GetAnchorFrame().IsPageFrame() )
109     {
110         OSL_FAIL( "<SwObjectFormatterLayFrame::AdditionalFormatObjsOnPage()> - mis-usage of method, call only for anchor frames of type page frame" );
111         return true;
112     }
113 
114     // #124218# - consider, if the layout action
115     // has to be restarted due to a delete of a page frame.
116     if ( GetLayAction() && GetLayAction()->IsAgain() )
117     {
118         return false;
119     }
120 
121     SwPageFrame& rPageFrame = static_cast<SwPageFrame&>(GetAnchorFrame());
122 
123     if ( !rPageFrame.GetSortedObjs() )
124     {
125         // nothing to do, if no floating screen object is registered at the anchor frame.
126         return true;
127     }
128 
129     bool bSuccess( true );
130 
131     for ( size_t i = 0; i < rPageFrame.GetSortedObjs()->size(); ++i )
132     {
133         SwAnchoredObject* pAnchoredObj = (*rPageFrame.GetSortedObjs())[i];
134 
135         // #i51941# - do not format object, which are anchored
136         // inside or at fly frame.
137         if ( pAnchoredObj->GetAnchorFrame()->FindFlyFrame() )
138         {
139             continue;
140         }
141         // #i33751#, #i34060# - method <GetPageFrameOfAnchor()>
142         // is replaced by method <FindPageFrameOfAnchor()>. It's return value
143         // have to be checked.
144         SwPageFrame* pPageFrameOfAnchor = pAnchoredObj->FindPageFrameOfAnchor();
145         // #i26945# - check, if the page frame of the
146         // object's anchor frame isn't the given page frame
147         OSL_ENSURE( pPageFrameOfAnchor,
148                 "<SwObjectFormatterLayFrame::AdditionalFormatObjsOnPage()> - missing page frame" );
149         if ( pPageFrameOfAnchor &&
150              // #i35911#
151              pPageFrameOfAnchor->GetPhyPageNum() < rPageFrame.GetPhyPageNum() )
152         {
153             // if format of object fails, stop formatting and pass fail to
154             // calling method via the return value.
155             if ( !DoFormatObj( *pAnchoredObj ) )
156             {
157                 bSuccess = false;
158                 break;
159             }
160 
161             // considering changes at <GetAnchorFrame().GetDrawObjs()> during
162             // format of the object.
163             if ( !rPageFrame.GetSortedObjs() ||
164                  i > rPageFrame.GetSortedObjs()->size() )
165             {
166                 break;
167             }
168             else
169             {
170                 const size_t nActPosOfObj =
171                     rPageFrame.GetSortedObjs()->ListPosOf( *pAnchoredObj );
172                 if ( nActPosOfObj == rPageFrame.GetSortedObjs()->size() ||
173                      nActPosOfObj > i )
174                 {
175                     --i;
176                 }
177                 else if ( nActPosOfObj < i )
178                 {
179                     i = nActPosOfObj;
180                 }
181             }
182         }
183     } // end of loop on <rPageFrame.GetSortedObjs()>
184 
185     return bSuccess;
186 }
187 
188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
189