Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/frmdlg/frmmgr.cxx
Line
Count
Source
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 <cmdid.h>
21
#include <hintids.hxx>
22
23
#include <svl/stritem.hxx>
24
#include <editeng/boxitem.hxx>
25
#include <editeng/lrspitem.hxx>
26
#include <editeng/ulspitem.hxx>
27
#include <editeng/shaditem.hxx>
28
#include <svx/swframevalidation.hxx>
29
#include <svx/xdef.hxx>
30
#include <tools/globname.hxx>
31
#include <comphelper/classids.hxx>
32
#include <osl/diagnose.h>
33
#include <fmtclds.hxx>
34
#include <utility>
35
#include <wrtsh.hxx>
36
#include <view.hxx>
37
#include <viewopt.hxx>
38
#include <uitool.hxx>
39
#include <frmmgr.hxx>
40
#include <format.hxx>
41
#include <mdiexp.hxx>
42
#include <poolfmt.hxx>
43
#include <com/sun/star/text/HoriOrientation.hpp>
44
#include <com/sun/star/text/VertOrientation.hpp>
45
#include <com/sun/star/text/RelOrientation.hpp>
46
#include <grfatr.hxx>
47
48
using namespace ::com::sun::star;
49
50
const WhichRangesContainer aFrameMgrRange(svl::Items<
51
                            RES_FRMATR_BEGIN, RES_FRMATR_END-1, // 87-129
52
53
                            // RotGrfFlyFrame: Support here, but seems not to be
54
                            // added in range of m_pOwnSh->GetFlyFrameAttr result
55
                            // (see below). Tried to find, but could not identify
56
                            RES_GRFATR_ROTATION, RES_GRFATR_ROTATION, // 132
57
58
                            // FillAttribute support
59
                            XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1014-1033
60
61
                            SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
62
                            FN_SET_FRM_NAME, FN_SET_FRM_NAME
63
                            >);
64
65
// determine frame attributes via Shell
66
SwFlyFrameAttrMgr::SwFlyFrameAttrMgr( bool bNew, SwWrtShell* pSh, Frmmgr_Type nType, const SvGlobalName* pName ) :
67
0
    m_aSet( static_cast<SwAttrPool&>(pSh->GetAttrPool()), aFrameMgrRange ),
68
0
    m_pOwnSh( pSh ),
69
0
    m_bAbsPos( false ),
70
0
    m_bNewFrame( bNew ),
71
0
    m_bIsInVertical( false ),
72
0
    m_bIsInVerticalL2R( false )
73
0
{
74
0
    if ( m_bNewFrame )
75
0
    {
76
0
        SwPoolFormatId nId;
77
0
        switch ( nType )
78
0
        {
79
0
            case Frmmgr_Type::TEXT:  nId = SwPoolFormatId::FRM_FRAME;    break;
80
0
            case Frmmgr_Type::OLE:   nId = SwPoolFormatId::FRM_OLE;      break;
81
0
            case Frmmgr_Type::GRF:   nId = SwPoolFormatId::FRM_GRAPHIC;  break;
82
            // set defaults:
83
0
            default:    nId=SwPoolFormatId::ZERO; break;
84
0
        }
85
0
        m_aSet.SetParent( &m_pOwnSh->GetFormatFromPool( nId )->GetAttrSet());
86
0
        m_aSet.Put( SwFormatFrameSize( SwFrameSize::Minimum, DFLT_WIDTH, DFLT_HEIGHT ));
87
88
0
        SetFrameSizeFromTable();
89
90
0
        if ( 0 != ::GetHtmlMode(pSh->GetView().GetDocShell()) )
91
0
            m_aSet.Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT, text::RelOrientation::PRINT_AREA ) );
92
93
0
        if (nType == Frmmgr_Type::GRF || nType == Frmmgr_Type::OLE)
94
0
        {
95
0
            if (!pName || *pName != SvGlobalName( SO3_SM_CLASSID ))
96
0
            {
97
                // Default anchor for new graphics and objects is at-char, except for Math objects.
98
0
                SwViewOption aViewOpt(*pSh->GetViewOptions());
99
100
0
                RndStdIds eAnchorType = aViewOpt.GetDefaultAnchorType();
101
102
0
                const SwFormatAnchor rStyleAnchor
103
0
                    = m_pOwnSh->GetFormatFromPool(nId)->GetAttrSet().GetAnchor();
104
0
                if (rStyleAnchor.GetAnchorId() != RndStdIds::FLY_AT_PARA)
105
0
                {
106
                    // The style has a custom anchor type, prefer that over the user profile
107
                    // default.
108
0
                    eAnchorType = rStyleAnchor.GetAnchorId();
109
0
                }
110
111
0
                m_aSet.Put(SwFormatAnchor(eAnchorType));
112
0
            }
113
0
        }
114
0
    }
115
0
    else if ( nType == Frmmgr_Type::NONE )
116
0
    {
117
0
        m_pOwnSh->GetFlyFrameAttr( m_aSet );
118
0
        bool bRightToLeft;
119
0
        m_bIsInVertical = m_pOwnSh->IsFrameVertical(true, bRightToLeft, m_bIsInVerticalL2R);
120
0
    }
121
0
    ::PrepareBoxInfo( m_aSet, *m_pOwnSh );
122
0
}
123
124
SwFlyFrameAttrMgr::SwFlyFrameAttrMgr( bool bNew, SwWrtShell* pSh, SfxItemSet aSet ) :
125
0
    m_aSet(std::move( aSet )),
126
0
    m_pOwnSh( pSh ),
127
0
    m_bAbsPos( false ),
128
0
    m_bNewFrame( bNew ),
129
0
    m_bIsInVertical(false),
130
0
    m_bIsInVerticalL2R(false)
131
0
{
132
0
    if(!bNew)
133
0
    {
134
0
        bool bRightToLeft;
135
0
        m_bIsInVertical = pSh->IsFrameVertical(true, bRightToLeft, m_bIsInVerticalL2R);
136
0
    }
137
0
}
138
139
// Initialise
140
void SwFlyFrameAttrMgr::UpdateAttrMgr()
141
0
{
142
0
    if ( !m_bNewFrame && m_pOwnSh->IsFrameSelected() )
143
0
        m_pOwnSh->GetFlyFrameAttr( m_aSet );
144
0
    ::PrepareBoxInfo( m_aSet, *m_pOwnSh );
145
0
}
146
147
void SwFlyFrameAttrMgr::UpdateFlyFrame_()
148
0
{
149
0
    if (const SfxStringItem* pItem = m_aSet.GetItemIfSet(FN_SET_FRM_NAME, false))
150
0
        m_pOwnSh->SetFlyName(UIName(pItem->GetValue()));
151
152
0
    m_pOwnSh->SetModified();
153
154
0
    if ( m_bAbsPos )
155
0
    {
156
0
        m_pOwnSh->SetFlyPos( m_aAbsPos );
157
0
        m_bAbsPos = false;
158
0
    }
159
0
}
160
161
// change existing Fly-Frame
162
void SwFlyFrameAttrMgr::UpdateFlyFrame()
163
0
{
164
0
    OSL_ENSURE( m_pOwnSh->IsFrameSelected(),
165
0
        "no frame selected or no shell, update not possible");
166
167
0
    if( !m_pOwnSh->IsFrameSelected() )
168
0
        return;
169
170
    //JP 6.8.2001: set never an invalid anchor into the core.
171
0
    const SwFormatAnchor *pGItem, *pItem;
172
0
    if( (pItem = m_aSet.GetItemIfSet( RES_ANCHOR, false )) )
173
0
    {
174
0
        SfxItemSet aGetSet(SfxItemSet::makeFixedSfxItemSet<RES_ANCHOR, RES_ANCHOR>(*m_aSet.GetPool()));
175
0
        if( m_pOwnSh->GetFlyFrameAttr( aGetSet ) && 1 == aGetSet.Count() &&
176
0
            (pGItem = aGetSet.GetItemIfSet( RES_ANCHOR, false ))
177
0
            && pGItem->GetAnchorId() == pItem->GetAnchorId() )
178
0
            m_aSet.ClearItem( RES_ANCHOR );
179
0
    }
180
181
    // return wg. BASIC
182
0
    if( m_aSet.Count() )
183
0
    {
184
0
        m_pOwnSh->StartAllAction();
185
0
        m_pOwnSh->SetFlyFrameAttr( m_aSet );
186
0
        UpdateFlyFrame_();
187
0
        m_pOwnSh->EndAllAction();
188
0
    }
189
0
}
190
191
// insert frame
192
void SwFlyFrameAttrMgr::InsertFlyFrame()
193
0
{
194
0
    m_pOwnSh->StartAllAction();
195
196
0
    bool bRet = nullptr != m_pOwnSh->NewFlyFrame( m_aSet );
197
198
    // turn on the right mode at the shell, frame got selected automatically.
199
0
    if ( bRet )
200
0
    {
201
0
        UpdateFlyFrame_();
202
0
        m_pOwnSh->EnterSelFrameMode();
203
0
        FrameNotify(m_pOwnSh, FLY_DRAG_START);
204
0
    }
205
0
    m_pOwnSh->EndAllAction();
206
0
}
207
208
// Insert frames of type eAnchorType. Position and size are being set explicitly.
209
// Not-allowed values of the enumeration type get corrected.
210
void SwFlyFrameAttrMgr::InsertFlyFrame(RndStdIds    eAnchorType,
211
                                   const Point  &rPos,
212
                                   const Size   &rSize )
213
0
{
214
0
    OSL_ENSURE( eAnchorType == RndStdIds::FLY_AT_PAGE ||
215
0
            eAnchorType == RndStdIds::FLY_AT_PARA ||
216
0
            eAnchorType == RndStdIds::FLY_AT_CHAR ||
217
0
            eAnchorType == RndStdIds::FLY_AT_FLY  ||
218
0
            eAnchorType == RndStdIds::FLY_AS_CHAR,     "invalid frame type" );
219
220
0
    SetPos( rPos );
221
222
0
    SetSize( rSize );
223
0
    SetAnchor( eAnchorType );
224
0
    InsertFlyFrame();
225
0
}
226
227
// set anchor
228
void SwFlyFrameAttrMgr::SetAnchor( RndStdIds eId )
229
0
{
230
0
    sal_uInt16 nPhyPageNum, nVirtPageNum;
231
0
    m_pOwnSh->GetPageNum( nPhyPageNum, nVirtPageNum );
232
233
0
    m_aSet.Put( SwFormatAnchor( eId, RndStdIds::FLY_AT_PAGE == eId ? nPhyPageNum : 0 ) );
234
0
    if ((RndStdIds::FLY_AT_PAGE == eId) || (RndStdIds::FLY_AT_PARA == eId) || (RndStdIds::FLY_AT_CHAR == eId)
235
0
        || (RndStdIds::FLY_AT_FLY == eId))
236
0
    {
237
0
        SwFormatVertOrient aVertOrient( GetVertOrient() );
238
0
        SwFormatHoriOrient aHoriOrient( GetHoriOrient() );
239
0
        aHoriOrient.SetRelationOrient( text::RelOrientation::FRAME );
240
0
        aVertOrient.SetRelationOrient( text::RelOrientation::FRAME );
241
0
        m_aSet.Put( aVertOrient );
242
0
        m_aSet.Put( aHoriOrient );
243
0
    }
244
0
}
245
246
// set the attribute for columns
247
void SwFlyFrameAttrMgr::SetCol( const SwFormatCol &rCol )
248
0
{
249
0
    m_aSet.Put( rCol );
250
0
}
251
252
//  set absolute position
253
void SwFlyFrameAttrMgr::SetAbsPos( const Point& rPoint )
254
0
{
255
0
    m_bAbsPos = true;
256
0
    m_aAbsPos = rPoint;
257
0
    SwFormatVertOrient aVertOrient( GetVertOrient() );
258
0
    SwFormatHoriOrient aHoriOrient( GetHoriOrient() );
259
0
    aHoriOrient.SetHoriOrient( text::HoriOrientation::NONE );
260
0
    aVertOrient.SetVertOrient( text::VertOrientation::NONE );
261
0
    m_aSet.Put( aVertOrient );
262
0
    m_aSet.Put( aHoriOrient );
263
0
}
264
265
// check metrics for correctness
266
void SwFlyFrameAttrMgr::ValidateMetrics( SvxSwFrameValidation& rVal,
267
        const SwFormatAnchor* pToCharContentPos,
268
        bool bOnlyPercentRefValue )
269
0
{
270
0
    if (!bOnlyPercentRefValue)
271
0
    {
272
0
        rVal.nMinHeight = MINFLY + CalcTopSpace() + CalcBottomSpace();
273
0
        rVal.nMinWidth =  MINFLY + CalcLeftSpace()+ CalcRightSpace();
274
0
    }
275
276
0
    SwRect aBoundRect;
277
278
    // OD 18.09.2003 #i18732# - adjustment for allowing vertical position
279
    //      aligned to page for fly frame anchored to paragraph or to character.
280
0
    const RndStdIds eAnchorType = rVal.nAnchorType;
281
282
0
    SwFormatFrameSize aFormatFrameSize;
283
0
    if (rVal.bEntirePageWidth)
284
0
        aFormatFrameSize.SetWidthPercentRelation(text::RelOrientation::PAGE_FRAME);
285
0
    if (rVal.bEntirePageHeight)
286
0
        aFormatFrameSize.SetHeightPercentRelation(text::RelOrientation::PAGE_FRAME);
287
288
0
    m_pOwnSh->CalcBoundRect( aBoundRect, eAnchorType,
289
0
                           rVal.nHRelOrient,
290
0
                           rVal.nVRelOrient,
291
0
                           pToCharContentPos,
292
0
                           rVal.bFollowTextFlow,
293
0
                           rVal.bMirror, nullptr, &rVal.aPercentSize,
294
0
                           &aFormatFrameSize);
295
296
0
    if (bOnlyPercentRefValue)
297
0
        return;
298
299
    // #mongolianlayout#
300
0
    if ( m_bIsInVertical || m_bIsInVerticalL2R )
301
0
    {
302
0
        Point aPos(aBoundRect.Pos());
303
0
        tools::Long nTmp = aPos.X();
304
0
        aPos.setX( aPos.Y() );
305
0
        aPos.setY( nTmp );
306
0
        Size aSize(aBoundRect.SSize());
307
0
        nTmp = aSize.Width();
308
0
        aSize.setWidth( aSize.Height() );
309
0
        aSize.setHeight( nTmp );
310
0
        aBoundRect.Chg( aPos, aSize );
311
        //exchange width/height to enable correct values
312
0
        nTmp = rVal.nWidth;
313
0
        rVal.nWidth = rVal.nHeight;
314
0
        rVal.nHeight = nTmp;
315
0
    }
316
0
    if ((eAnchorType == RndStdIds::FLY_AT_PAGE) || (eAnchorType == RndStdIds::FLY_AT_FLY))
317
0
    {
318
        // MinimalPosition
319
0
        rVal.nMinHPos = aBoundRect.Left();
320
0
        rVal.nMinVPos = aBoundRect.Top();
321
0
        SwTwips nH = rVal.nHPos;
322
0
        SwTwips nV = rVal.nVPos;
323
324
0
        if (rVal.nHPos + rVal.nWidth > aBoundRect.Right())
325
0
        {
326
0
            if (rVal.nHoriOrient == text::HoriOrientation::NONE)
327
0
            {
328
0
                rVal.nHPos -= ((rVal.nHPos + rVal.nWidth) - aBoundRect.Right());
329
0
                nH = rVal.nHPos;
330
0
            }
331
0
            else
332
0
                rVal.nWidth = aBoundRect.Right() - rVal.nHPos;
333
0
        }
334
335
0
        if (rVal.nHPos + rVal.nWidth > aBoundRect.Right())
336
0
            rVal.nWidth = aBoundRect.Right() - rVal.nHPos;
337
338
0
        if (rVal.nVPos + rVal.nHeight > aBoundRect.Bottom())
339
0
        {
340
0
            if (rVal.nVertOrient == text::VertOrientation::NONE)
341
0
            {
342
0
                rVal.nVPos -= ((rVal.nVPos + rVal.nHeight) - aBoundRect.Bottom());
343
0
                nV = rVal.nVPos;
344
0
            }
345
0
            else
346
0
                rVal.nHeight = aBoundRect.Bottom() - rVal.nVPos;
347
0
        }
348
349
0
        if (rVal.nVPos + rVal.nHeight > aBoundRect.Bottom())
350
0
            rVal.nHeight = aBoundRect.Bottom() - rVal.nVPos;
351
352
0
        if ( rVal.nVertOrient != text::VertOrientation::NONE )
353
0
            nV = aBoundRect.Top();
354
355
0
        if ( rVal.nHoriOrient != text::HoriOrientation::NONE )
356
0
            nH = aBoundRect.Left();
357
358
0
        rVal.nMaxHPos   = aBoundRect.Right()  - rVal.nWidth;
359
0
        rVal.nMaxHeight = aBoundRect.Bottom() - nV;
360
361
0
        rVal.nMaxVPos   = aBoundRect.Bottom() - rVal.nHeight;
362
0
        rVal.nMaxWidth  = aBoundRect.Right()  - nH;
363
0
    }
364
    // OD 12.11.2003 #i22341# - handle to character anchored objects vertical
365
    // aligned at character or top of line in a special case
366
0
    else if ((eAnchorType == RndStdIds::FLY_AT_PARA) ||
367
0
                ((eAnchorType == RndStdIds::FLY_AT_CHAR) &&
368
0
                (rVal.nVRelOrient != text::RelOrientation::CHAR) &&
369
0
                (rVal.nVRelOrient != text::RelOrientation::TEXT_LINE) ) )
370
0
    {
371
0
        if (rVal.nHPos + rVal.nWidth > aBoundRect.Right())
372
0
        {
373
0
            if (rVal.nHoriOrient == text::HoriOrientation::NONE)
374
0
            {
375
0
                rVal.nHPos -= ((rVal.nHPos + rVal.nWidth) - aBoundRect.Right());
376
0
            }
377
0
            else
378
0
                rVal.nWidth = aBoundRect.Right() - rVal.nHPos;
379
0
        }
380
381
        // OD 29.09.2003 #i17567#, #i18732# - consider following the text flow
382
        // and alignment at page areas.
383
0
        const bool bMaxVPosAtBottom = !rVal.bFollowTextFlow ||
384
0
                                      rVal.nVRelOrient == text::RelOrientation::PAGE_FRAME ||
385
0
                                      rVal.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA;
386
0
        {
387
0
            SwTwips nTmpMaxVPos = ( bMaxVPosAtBottom
388
0
                                    ? aBoundRect.Bottom()
389
0
                                    : aBoundRect.Height() ) -
390
0
                                  rVal.nHeight;
391
0
            if ( rVal.nVPos > nTmpMaxVPos )
392
0
            {
393
0
                if (rVal.nVertOrient == text::VertOrientation::NONE)
394
0
                {
395
0
                    rVal.nVPos = nTmpMaxVPos;
396
0
                }
397
0
                else
398
0
                {
399
0
                    rVal.nHeight = ( bMaxVPosAtBottom
400
0
                                     ? aBoundRect.Bottom()
401
0
                                     : aBoundRect.Height() ) - rVal.nVPos;
402
0
                }
403
0
            }
404
0
        }
405
406
0
        rVal.nMinHPos  = aBoundRect.Left();
407
0
        rVal.nMaxHPos  = aBoundRect.Right() - rVal.nWidth;
408
409
0
        rVal.nMinVPos  = aBoundRect.Top();
410
        // OD 26.09.2003 #i17567#, #i18732# - determine maximum vertical position
411
0
        if ( bMaxVPosAtBottom )
412
0
        {
413
0
            rVal.nMaxVPos  = aBoundRect.Bottom() - rVal.nHeight;
414
0
        }
415
0
        else
416
0
        {
417
0
            rVal.nMaxVPos  = aBoundRect.Height() - rVal.nHeight;
418
0
        }
419
420
        // maximum width height
421
0
        const SwTwips nH = ( rVal.nHoriOrient != text::HoriOrientation::NONE )
422
0
                           ? aBoundRect.Left()
423
0
                           : rVal.nHPos;
424
0
        const SwTwips nV = ( rVal.nVertOrient != text::VertOrientation::NONE )
425
0
                           ? aBoundRect.Top()
426
0
                           : rVal.nVPos;
427
0
        rVal.nMaxHeight  = rVal.nMaxVPos + rVal.nHeight - nV;
428
0
        rVal.nMaxWidth   = rVal.nMaxHPos + rVal.nWidth - nH;
429
0
    }
430
    // OD 12.11.2003 #i22341# - special case for to character anchored objects
431
    // vertical aligned at character or top of line.
432
    // Note: (1) positive vertical values are positions above the top of line
433
    //       (2) negative vertical values are positions below the top of line
434
0
    else if ( (eAnchorType == RndStdIds::FLY_AT_CHAR) &&
435
0
              ( rVal.nVRelOrient == text::RelOrientation::CHAR ||
436
0
                rVal.nVRelOrient == text::RelOrientation::TEXT_LINE ) )
437
0
    {
438
        // determine horizontal values
439
0
        rVal.nMinHPos  = aBoundRect.Left();
440
441
0
        rVal.nMaxHPos  = aBoundRect.Right() - rVal.nWidth;
442
0
        if (rVal.nHPos + rVal.nWidth > aBoundRect.Right())
443
0
        {
444
0
            if (rVal.nHoriOrient == text::HoriOrientation::NONE)
445
0
            {
446
0
                rVal.nHPos -= ((rVal.nHPos + rVal.nWidth) - aBoundRect.Right());
447
0
            }
448
0
            else
449
0
                rVal.nWidth = aBoundRect.Right() - rVal.nHPos;
450
0
        }
451
452
0
        const SwTwips nH = ( rVal.nHoriOrient != text::HoriOrientation::NONE )
453
0
                           ? aBoundRect.Left()
454
0
                           : rVal.nHPos;
455
0
        rVal.nMaxWidth   = rVal.nMaxHPos + rVal.nWidth - nH;
456
457
        // determine vertical values
458
0
        rVal.nMinVPos = -( aBoundRect.Bottom() - rVal.nHeight );
459
0
        if ( rVal.nVPos < rVal.nMinVPos &&
460
0
             rVal.nVertOrient == text::VertOrientation::NONE )
461
0
        {
462
0
            rVal.nVPos = rVal.nMinVPos;
463
0
        }
464
465
0
        rVal.nMaxVPos  = -aBoundRect.Top();
466
0
        if ( rVal.nVPos > rVal.nMaxVPos &&
467
0
             rVal.nVertOrient == text::VertOrientation::NONE )
468
0
        {
469
0
            rVal.nVPos = rVal.nMaxVPos;
470
0
        }
471
472
0
        if ( rVal.nVertOrient == text::VertOrientation::NONE )
473
0
        {
474
0
            rVal.nMaxHeight = aBoundRect.Bottom() + rVal.nVPos;
475
0
        }
476
0
        else
477
0
        {
478
0
            rVal.nMaxHeight = aBoundRect.Height();
479
0
        }
480
0
    }
481
0
    else if ( eAnchorType == RndStdIds::FLY_AS_CHAR )
482
0
    {
483
0
        rVal.nMinHPos = 0;
484
0
        rVal.nMaxHPos = 0;
485
486
0
        rVal.nMaxHeight = aBoundRect.Height();
487
0
        rVal.nMaxWidth  = aBoundRect.Width();
488
489
0
        rVal.nMaxVPos   = aBoundRect.Height();
490
0
        rVal.nMinVPos   = -aBoundRect.Height() + rVal.nHeight;
491
0
        if (rVal.nMaxVPos < rVal.nMinVPos)
492
0
        {
493
0
            rVal.nMinVPos = rVal.nMaxVPos;
494
0
            rVal.nMaxVPos = -aBoundRect.Height();
495
0
        }
496
0
    }
497
    // #mongolianlayout#
498
0
    if ( m_bIsInVertical || m_bIsInVerticalL2R )
499
0
    {
500
        //restore width/height exchange
501
0
        tools::Long nTmp = rVal.nWidth;
502
0
        rVal.nWidth = rVal.nHeight;
503
0
        rVal.nHeight = nTmp;
504
0
    }
505
506
0
    if (rVal.nMaxWidth < rVal.nWidth)
507
0
        rVal.nWidth = rVal.nMaxWidth;
508
0
    if (rVal.nMaxHeight < rVal.nHeight)
509
0
        rVal.nHeight = rVal.nMaxHeight;
510
0
}
511
512
// correction for border
513
SwTwips SwFlyFrameAttrMgr::CalcTopSpace()
514
0
{
515
0
    const SvxShadowItem& rShadow = GetShadow();
516
0
    const SvxBoxItem&    rBox    = GetBox();
517
0
    return rShadow.CalcShadowSpace(SvxShadowItemSide::TOP ) + rBox.CalcLineSpace(SvxBoxItemLine::TOP);
518
0
}
519
520
SwTwips SwFlyFrameAttrMgr::CalcBottomSpace()
521
0
{
522
0
    const SvxShadowItem& rShadow = GetShadow();
523
0
    const SvxBoxItem& rBox       = GetBox();
524
0
    return rShadow.CalcShadowSpace(SvxShadowItemSide::BOTTOM) + rBox.CalcLineSpace(SvxBoxItemLine::BOTTOM);
525
0
}
526
527
SwTwips SwFlyFrameAttrMgr::CalcLeftSpace()
528
0
{
529
0
    const SvxShadowItem& rShadow = GetShadow();
530
0
    const SvxBoxItem&    rBox    = GetBox();
531
0
    return rShadow.CalcShadowSpace(SvxShadowItemSide::LEFT) + rBox.CalcLineSpace(SvxBoxItemLine::LEFT);
532
0
}
533
534
SwTwips SwFlyFrameAttrMgr::CalcRightSpace()
535
0
{
536
0
    const SvxShadowItem& rShadow = GetShadow();
537
0
    const SvxBoxItem&    rBox    = GetBox();
538
0
    return rShadow.CalcShadowSpace(SvxShadowItemSide::RIGHT) + rBox.CalcLineSpace(SvxBoxItemLine::RIGHT);
539
0
}
540
541
// erase attribute from the set
542
void SwFlyFrameAttrMgr::DelAttr( sal_uInt16 nId )
543
0
{
544
0
    m_aSet.ClearItem( nId );
545
0
}
546
547
void SwFlyFrameAttrMgr::SetLRSpace( tools::Long nLeft, tools::Long nRight )
548
0
{
549
0
    OSL_ENSURE( LONG_MAX != nLeft && LONG_MAX != nRight, "Which border to set?" );
550
551
0
    SvxLRSpaceItem aTmp( m_aSet.Get( RES_LR_SPACE ) );
552
0
    if (LONG_MAX != nLeft)
553
0
        aTmp.SetLeft(SvxIndentValue::twips(nLeft));
554
0
    if (LONG_MAX != nRight)
555
0
        aTmp.SetRight(SvxIndentValue::twips(nRight));
556
0
    m_aSet.Put( aTmp );
557
0
}
558
559
void SwFlyFrameAttrMgr::SetULSpace( tools::Long nTop, tools::Long nBottom )
560
0
{
561
0
    OSL_ENSURE(LONG_MAX != nTop && LONG_MAX != nBottom, "Which border to set?" );
562
563
0
    SvxULSpaceItem aTmp( m_aSet.Get( RES_UL_SPACE ) );
564
0
    if( LONG_MAX != nTop )
565
0
        aTmp.SetUpper( sal_uInt16(nTop) );
566
0
    if( LONG_MAX != nBottom )
567
0
        aTmp.SetLower( sal_uInt16(nBottom) );
568
0
    m_aSet.Put( aTmp );
569
0
}
570
571
void SwFlyFrameAttrMgr::SetPos( const Point& rPoint )
572
0
{
573
0
    SwFormatVertOrient aVertOrient( GetVertOrient() );
574
0
    SwFormatHoriOrient aHoriOrient( GetHoriOrient() );
575
576
0
    aHoriOrient.SetPos       ( rPoint.X() );
577
0
    aHoriOrient.SetHoriOrient( text::HoriOrientation::NONE  );
578
579
0
    aVertOrient.SetPos       ( rPoint.Y() );
580
0
    aVertOrient.SetVertOrient( text::VertOrientation::NONE  );
581
582
0
    m_aSet.Put( aVertOrient );
583
0
    m_aSet.Put( aHoriOrient );
584
0
}
585
586
void SwFlyFrameAttrMgr::SetHorzOrientation( sal_Int16 eOrient )
587
0
{
588
0
    SwFormatHoriOrient aHoriOrient( GetHoriOrient() );
589
0
    aHoriOrient.SetHoriOrient( eOrient );
590
0
    m_aSet.Put( aHoriOrient );
591
0
}
592
593
void SwFlyFrameAttrMgr::SetVertOrientation( sal_Int16 eOrient )
594
0
{
595
0
    SwFormatVertOrient aVertOrient( GetVertOrient() );
596
0
    aVertOrient.SetVertOrient( eOrient );
597
0
    m_aSet.Put( aVertOrient );
598
0
}
599
600
void SwFlyFrameAttrMgr::SetHeightSizeType( SwFrameSize eType )
601
0
{
602
0
    SwFormatFrameSize aSize( GetFrameSize() );
603
0
    aSize.SetHeightSizeType( eType );
604
0
    m_aSet.Put( aSize );
605
0
}
606
607
void SwFlyFrameAttrMgr::SetRotation(Degree10 nOld, Degree10 nNew, const Size& rUnrotatedSize)
608
0
{
609
    // RotGrfFlyFrame: Central handling of real change of rotation here, all adaptations use this.
610
    // Adaptation of pos/size may be wanted in the future. Already tried to keep last Size in
611
    // UnrotatedSize in the SwRotationGrf Item, but this will lead to various problems. Also tried
612
    // to use m_aSet.Put(...) as in other methods (also tried read methods for Rotation/UnrotatedSize) but
613
    // somehow the needed ID (RES_GRFATR_ROTATION) is *not* in the SfxItemSet of the Frame, so for
614
    // now set directly. Undo/Redo is preserved by AttributeChange
615
0
    if(nOld != nNew)
616
0
    {
617
0
        m_pOwnSh->SetAttrItem(SwRotationGrf(nNew, rUnrotatedSize));
618
0
    }
619
0
}
620
621
void SwFlyFrameAttrMgr::SetSize( const Size& rSize )
622
0
{
623
0
    SwFormatFrameSize aSize( GetFrameSize() );
624
0
    aSize.SetSize(Size(std::max(rSize.Width(), tools::Long(MINFLY)), std::max(rSize.Height(), tools::Long(MINFLY))));
625
0
    m_aSet.Put( aSize );
626
0
}
627
628
void SwFlyFrameAttrMgr::SetAttrSet(const SfxItemSet& rSet)
629
0
{
630
0
    m_aSet.ClearItem();
631
0
    m_aSet.Put( rSet );
632
0
}
633
634
const SwTableFormat* SwFlyFrameAttrMgr::SingleTableSelected(const SwWrtShell& rWrtShell)
635
0
{
636
0
    if (!rWrtShell.IsTableMode())
637
0
    {
638
0
        return nullptr;
639
0
    }
640
641
    // We have a table selection.
642
0
    SwSelBoxes aBoxes;
643
0
    GetTableSel(rWrtShell, aBoxes);
644
0
    if (aBoxes.empty())
645
0
    {
646
0
        return nullptr;
647
0
    }
648
649
0
    auto pTableNd = const_cast<SwTableNode*>(aBoxes[0]->GetSttNd()->FindTableNode());
650
0
    if (!pTableNd)
651
0
    {
652
0
        return nullptr;
653
0
    }
654
655
0
    SwTable& rTable = pTableNd->GetTable();
656
0
    if (aBoxes.size() != rTable.GetTabSortBoxes().size())
657
0
    {
658
0
        return nullptr;
659
0
    }
660
661
0
    return rTable.GetFrameFormat();
662
0
}
663
664
void SwFlyFrameAttrMgr::SetFrameSizeFromTable()
665
0
{
666
0
    const SwTableFormat* pTableFormat = SingleTableSelected(*m_pOwnSh);
667
0
    if (!pTableFormat)
668
0
    {
669
0
        return;
670
0
    }
671
672
    // The whole table is selected: default fly width should be the table width
673
    // in this case.
674
0
    m_aSet.Put(pTableFormat->GetFrameSize());
675
676
    // The table can have its own border already, so an additional fly border makes no sense.
677
0
    SvxBoxItem aBoxItem(RES_BOX);
678
0
    m_aSet.Put(aBoxItem);
679
0
}
680
681
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */