Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/cui/source/tabpages/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 73 kB image not shown  

Quelle  swpossizetabpage.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <memory>
#include <cstddef>
#include <type_traits>
#include <swpossizetabpage.hxx>
#include <svx/dlgutil.hxx>
#include <svx/anchorid.hxx>
#include <svl/intitem.hxx>
#include <svx/swframevalidation.hxx>
#include <sfx2/htmlmode.hxx>
#include <svx/svdview.hxx>
#include <svx/svdpagv.hxx>
#include <svx/swframeposstrings.hxx>
#include <svx/rectenum.hxx>
#include <sal/macros.h>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <svx/svxids.hrc>
#include <svtools/unitconv.hxx>
#include <osl/diagnose.h>
#include <svl/grabbagitem.hxx>

#include <bitmaps.hlst>

using namespace ::com::sun::star::text;

namespace {

enum class LB;

}

struct FrmMap
{
    SvxSwFramePosString::StringId   eStrId;
    SvxSwFramePosString::StringId   eMirrorStrId;
    short                           nAlign;
    LB                              nLBRelations;
};

namespace {

struct RelationMap
{
    SvxSwFramePosString::StringId   eStrId;
    SvxSwFramePosString::StringId   eMirrorStrId;
    LB                              nLBRelation;
    short nRelation;
};
struct StringIdPair_Impl
{
    SvxSwFramePosString::StringId eHori;
    SvxSwFramePosString::StringId eVert;
};

enum class LB {
    NONE                = 0x000000,
    Frame               = 0x000001, // paragraph text area
    PrintArea           = 0x000002, // paragraph text area + indents
    VertFrame           = 0x000004, // vertical paragraph text area
    VertPrintArea       = 0x000008, // vertical paragraph text area + indents
    RelFrameLeft        = 0x000010, // left paragraph margin
    RelFrameRight       = 0x000020, // right paragraph margin

    RelPageLeft         = 0x000040, // left page margin
    RelPageRight        = 0x000080, // right page margin
    RelPageFrame        = 0x000100, // complete page
    RelPagePrintArea    = 0x000200, // text area of page

    FlyRelPageLeft      = 0x000400, // left frame margin
    FlyRelPageRight     = 0x000800, // right frame margin
    FlyRelPageFrame     = 0x001000, // complete frame
    FlyRelPagePrintArea = 0x002000, // frame interior

    RelBase             = 0x004000, // as char, relative to baseline
    RelChar             = 0x008000, // as char, relative to character
    RelRow              = 0x010000, // as char, relative to line

// #i22305#
    FlyVertFrame        = 0x020000, // vertical entire frame
    FlyVertPrintArea    = 0x040000, // vertical frame text area

// #i22341#
    VertLine            = 0x080000, // vertical text line

    RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
    RelPagePrintAreaTop = 0x200000,

    LAST = 0x400000
};

}

namespace o3tl {
    template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
}

RelationMap const aRelationMap[] =
{
    {SvxSwFramePosString::FRAME,         SvxSwFramePosString::FRAME,             LB::Frame,           RelOrientation::FRAME},
    {SvxSwFramePosString::PRTAREA,       SvxSwFramePosString::PRTAREA,           LB::PrintArea,         RelOrientation::PRINT_AREA},
    {SvxSwFramePosString::REL_PG_LEFT,   SvxSwFramePosString::MIR_REL_PG_LEFT,   LB::RelPageLeft,     RelOrientation::PAGE_LEFT},
    {SvxSwFramePosString::REL_PG_RIGHT,  SvxSwFramePosString::MIR_REL_PG_RIGHT,  LB::RelPageRight,    RelOrientation::PAGE_RIGHT},
    {SvxSwFramePosString::REL_FRM_LEFT,  SvxSwFramePosString::MIR_REL_FRM_LEFT,  LB::RelFrameLeft,    RelOrientation::FRAME_LEFT},
    {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::MIR_REL_FRM_RIGHT, LB::RelFrameRight,   RelOrientation::FRAME_RIGHT},
    {SvxSwFramePosString::REL_PG_FRAME,  SvxSwFramePosString::REL_PG_FRAME,      LB::RelPageFrame,    RelOrientation::PAGE_FRAME},
    {SvxSwFramePosString::REL_PG_PRTAREA,SvxSwFramePosString::REL_PG_PRTAREA,    LB::RelPagePrintArea,  RelOrientation::PAGE_PRINT_AREA},
    {SvxSwFramePosString::REL_PG_PRTAREA_TOP,SvxSwFramePosString::REL_PG_PRTAREA_TOP,    LB::RelPagePrintAreaTop,  RelOrientation::PAGE_PRINT_AREA_TOP},
    {SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,    LB::RelPagePrintAreaBottom,  RelOrientation::PAGE_PRINT_AREA_BOTTOM},
    {SvxSwFramePosString::REL_CHAR,      SvxSwFramePosString::REL_CHAR,          LB::RelChar,        RelOrientation::CHAR},

    {SvxSwFramePosString::FLY_REL_PG_LEFT,       SvxSwFramePosString::FLY_MIR_REL_PG_LEFT,    LB::FlyRelPageLeft,     RelOrientation::PAGE_LEFT},
    {SvxSwFramePosString::FLY_REL_PG_RIGHT,      SvxSwFramePosString::FLY_MIR_REL_PG_RIGHT,   LB::FlyRelPageRight,    RelOrientation::PAGE_RIGHT},
    {SvxSwFramePosString::FLY_REL_PG_FRAME,      SvxSwFramePosString::FLY_REL_PG_FRAME,       LB::FlyRelPageFrame,    RelOrientation::PAGE_FRAME},
    {SvxSwFramePosString::FLY_REL_PG_PRTAREA,    SvxSwFramePosString::FLY_REL_PG_PRTAREA,     LB::FlyRelPagePrintArea,  RelOrientation::PAGE_PRINT_AREA},

    {SvxSwFramePosString::REL_BORDER,        SvxSwFramePosString::REL_BORDER,             LB::VertFrame,          RelOrientation::FRAME},
    {SvxSwFramePosString::REL_PRTAREA,       SvxSwFramePosString::REL_PRTAREA,            LB::VertPrintArea,        RelOrientation::PRINT_AREA},

    // #i22305#
    {SvxSwFramePosString::FLY_REL_PG_FRAME,      SvxSwFramePosString::FLY_REL_PG_FRAME,       LB::FlyVertFrame,      RelOrientation::FRAME},
    {SvxSwFramePosString::FLY_REL_PG_PRTAREA,    SvxSwFramePosString::FLY_REL_PG_PRTAREA,     LB::FlyVertPrintArea,    RelOrientation::PRINT_AREA},

    // #i22341#
    {SvxSwFramePosString::REL_LINE,  SvxSwFramePosString::REL_LINE,   LB::VertLine,   RelOrientation::TEXT_LINE}
};

RelationMap const aAsCharRelationMap[] =
{
    {SvxSwFramePosString::REL_BASE,  SvxSwFramePosString::REL_BASE,   LB::RelBase,   RelOrientation::FRAME},
    {SvxSwFramePosString::REL_CHAR,  SvxSwFramePosString::REL_CHAR,   LB::RelChar,   RelOrientation::FRAME},
    {SvxSwFramePosString::REL_ROW,   SvxSwFramePosString::REL_ROW,   LB::RelRow,     RelOrientation::FRAME}
};

/*--------------------------------------------------------------------
    Anchored at page
 --------------------------------------------------------------------*/


constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
                                      LB::RelPageRight;

FrmMap const aHPageMap[] =
{
    {SvxSwFramePosString::LEFT,       SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,      HORI_PAGE_REL},
    {SvxSwFramePosString::RIGHT,      SvxSwFramePosString::MIR_RIGHT,      HoriOrientation::RIGHT,     HORI_PAGE_REL},
    {SvxSwFramePosString::CENTER_HORI,SvxSwFramePosString::CENTER_HORI,    HoriOrientation::CENTER,    HORI_PAGE_REL},
    {SvxSwFramePosString::FROMLEFT,   SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      HORI_PAGE_REL}
};

FrmMap const aHPageHtmlMap[] =
{
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      LB::RelPageFrame}
};

#define VERT_PAGE_REL   (LB::RelPageFrame|LB::RelPagePrintArea)

FrmMap const aVPageMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,       VERT_PAGE_REL},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::BOTTOM,    VERT_PAGE_REL},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CENTER,    VERT_PAGE_REL},
    {SvxSwFramePosString::FROMTOP,       SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,      VERT_PAGE_REL}
};

FrmMap const aVPageHtmlMap[] =
{
    {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,      LB::RelPageFrame}
};

/*--------------------------------------------------------------------
    Anchored at frame
 --------------------------------------------------------------------*/


constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
                                       LB::FlyRelPageLeft|LB::FlyRelPageRight;

FrmMap const aHFrameMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,  HORI_FRAME_REL},
    {SvxSwFramePosString::RIGHT,         SvxSwFramePosString::MIR_RIGHT,      HoriOrientation::RIGHT,     HORI_FRAME_REL},
    {SvxSwFramePosString::CENTER_HORI,   SvxSwFramePosString::CENTER_HORI,    HoriOrientation::CENTER,    HORI_FRAME_REL},
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      HORI_FRAME_REL}
};

FrmMap const aHFlyHtmlMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,      LB::FlyRelPageFrame},
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      LB::FlyRelPageFrame}
};

// #i18732# - own vertical alignment map for to frame anchored objects
// #i22305#
#define VERT_FRAME_REL   (LB::FlyVertFrame|LB::FlyVertPrintArea)

FrmMap const aVFrameMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,       VERT_FRAME_REL},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::BOTTOM,    VERT_FRAME_REL},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CENTER,    VERT_FRAME_REL},
    {SvxSwFramePosString::FROMTOP,       SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,      VERT_FRAME_REL}
};

FrmMap const aVFlyHtmlMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,       LB::FlyVertFrame},
    {SvxSwFramePosString::FROMTOP,       SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,      LB::FlyVertFrame}
};

FrmMap const aVMultiSelectionMap[] =
{
    {SvxSwFramePosString::FROMTOP,       SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,      LB::NONE}
};
FrmMap const aHMultiSelectionMap[] =
{
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::FROMLEFT,       HoriOrientation::NONE,      LB::NONE}
};

/*--------------------------------------------------------------------
    Anchored at paragraph
 --------------------------------------------------------------------*/


constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
                                      LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
                                      LB::RelFrameRight;

FrmMap const aHParaMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,      HORI_PARA_REL},
    {SvxSwFramePosString::RIGHT,         SvxSwFramePosString::MIR_RIGHT,      HoriOrientation::RIGHT,     HORI_PARA_REL},
    {SvxSwFramePosString::CENTER_HORI,   SvxSwFramePosString::CENTER_HORI,    HoriOrientation::CENTER,    HORI_PARA_REL},
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      HORI_PARA_REL}
};

#define HTML_HORI_PARA_REL  (LB::Frame|LB::PrintArea)

FrmMap const aHParaHtmlMap[] =
{
    {SvxSwFramePosString::LEFT,  SvxSwFramePosString::LEFT,   HoriOrientation::LEFT,      HTML_HORI_PARA_REL},
    {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT,  HoriOrientation::RIGHT,     HTML_HORI_PARA_REL}
};

FrmMap const aHParaHtmlAbsMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,      HTML_HORI_PARA_REL},
    {SvxSwFramePosString::RIGHT,         SvxSwFramePosString::MIR_RIGHT,      HoriOrientation::RIGHT,     HTML_HORI_PARA_REL}
};


constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
                                      LB::RelPageFrame|LB::RelPagePrintArea| LB::RelPagePrintAreaTop |LB::RelPagePrintAreaBottom;

FrmMap const aVParaMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,       VERT_PARA_REL},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::BOTTOM,    VERT_PARA_REL},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CENTER,    VERT_PARA_REL},
    {SvxSwFramePosString::FROMTOP,       SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,      VERT_PARA_REL}
};

FrmMap const aVParaHtmlMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,       LB::VertPrintArea}
};

/*--------------------------------------------------------------------
    Anchored at character
 --------------------------------------------------------------------*/


constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
                                      LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
                                      LB::RelFrameRight|LB::RelChar;

static FrmMap aHCharMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,      HORI_CHAR_REL},
    {SvxSwFramePosString::RIGHT,         SvxSwFramePosString::MIR_RIGHT,      HoriOrientation::RIGHT,     HORI_CHAR_REL},
    {SvxSwFramePosString::CENTER_HORI,   SvxSwFramePosString::CENTER_HORI,    HoriOrientation::CENTER,    HORI_CHAR_REL},
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      HORI_CHAR_REL}
};

#define HTML_HORI_CHAR_REL  (LB::Frame|LB::PrintArea|LB::RelChar)

static FrmMap aHCharHtmlMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::LEFT,           HoriOrientation::LEFT,      HTML_HORI_CHAR_REL},
    {SvxSwFramePosString::RIGHT,         SvxSwFramePosString::RIGHT,          HoriOrientation::RIGHT,     HTML_HORI_CHAR_REL}
};

static FrmMap aHCharHtmlAbsMap[] =
{
    {SvxSwFramePosString::LEFT,          SvxSwFramePosString::MIR_LEFT,       HoriOrientation::LEFT,          LB::PrintArea|LB::RelChar},
    {SvxSwFramePosString::RIGHT,         SvxSwFramePosString::MIR_RIGHT,      HoriOrientation::RIGHT,     LB::PrintArea},
    {SvxSwFramePosString::FROMLEFT,      SvxSwFramePosString::MIR_FROMLEFT,   HoriOrientation::NONE,      LB::RelPageFrame}
};

// #i18732# - allow vertical alignment at page areas
// #i22341# - handle <LB::RelChar> on its own
constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
                                      LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPagePrintAreaBottom;

static FrmMap aVCharMap[] =
{
    // #i22341#
    // introduce mappings for new vertical alignment at top of line <LB::VertLine>
    // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
    // Note: because of these adjustments the map becomes ambiguous in its values
    //       <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
    //       in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
    //       and <SwFrmPage::FillPosLB(..)>
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,           VERT_CHAR_REL|LB::RelChar},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::BOTTOM,        VERT_CHAR_REL|LB::RelChar},
    {SvxSwFramePosString::BELOW,         SvxSwFramePosString::BELOW,          VertOrientation::CHAR_BOTTOM,   LB::RelChar},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CENTER,        VERT_CHAR_REL|LB::RelChar},
    {SvxSwFramePosString::FROMTOP,       SvxSwFramePosString::FROMTOP,        VertOrientation::NONE,          VERT_CHAR_REL},
    {SvxSwFramePosString::FROMBOTTOM,    SvxSwFramePosString::FROMBOTTOM,     VertOrientation::NONE,          LB::RelChar|LB::VertLine},
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::LINE_TOP,      LB::VertLine},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::LINE_BOTTOM,   LB::VertLine},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::LINE_CENTER,   LB::VertLine}
};


FrmMap const aVCharHtmlMap[] =
{
    {SvxSwFramePosString::BELOW,         SvxSwFramePosString::BELOW,          VertOrientation::CHAR_BOTTOM,   LB::RelChar}
};

FrmMap const aVCharHtmlAbsMap[] =
{
    {SvxSwFramePosString::TOP,    SvxSwFramePosString::TOP,            VertOrientation::TOP,           LB::RelChar},
    {SvxSwFramePosString::BELOW,  SvxSwFramePosString::BELOW,          VertOrientation::CHAR_BOTTOM,   LB::RelChar}
};
/*--------------------------------------------------------------------
    anchored as character
 --------------------------------------------------------------------*/


FrmMap const aVAsCharMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,           LB::RelBase},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::BOTTOM,        LB::RelBase},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CENTER,        LB::RelBase},

    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::CHAR_TOP,      LB::RelChar},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::CHAR_BOTTOM,   LB::RelChar},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CHAR_CENTER,   LB::RelChar},

    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::LINE_TOP,      LB::RelRow},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::LINE_BOTTOM,   LB::RelRow},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::LINE_CENTER,   LB::RelRow},

    {SvxSwFramePosString::FROMBOTTOM,    SvxSwFramePosString::FROMBOTTOM,     VertOrientation::NONE,          LB::RelBase}
};

FrmMap const aVAsCharHtmlMap[] =
{
    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::TOP,           LB::RelBase},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::CENTER,        LB::RelBase},

    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::CHAR_TOP,      LB::RelChar},

    {SvxSwFramePosString::TOP,           SvxSwFramePosString::TOP,            VertOrientation::LINE_TOP,      LB::RelRow},
    {SvxSwFramePosString::BOTTOM,        SvxSwFramePosString::BOTTOM,         VertOrientation::LINE_BOTTOM,   LB::RelRow},
    {SvxSwFramePosString::CENTER_VERT,   SvxSwFramePosString::CENTER_VERT,    VertOrientation::LINE_CENTER,   LB::RelRow}
};

static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
{
    if( !pMap )
        return 0;

    if( pMap == aVParaHtmlMap )
        return std::size(aVParaHtmlMap);
    if( pMap == aVAsCharHtmlMap )
        return std::size( aVAsCharHtmlMap );
    if( pMap == aHParaHtmlMap )
        return std::size( aHParaHtmlMap );
    if( pMap == aHParaHtmlAbsMap )
        return std::size( aHParaHtmlAbsMap );
    if( pMap == aVPageMap )
        return std::size( aVPageMap );
    if( pMap == aVPageHtmlMap )
        return std::size( aVPageHtmlMap );
    if( pMap == aVAsCharMap )
        return std::size( aVAsCharMap );
    if( pMap == aVParaMap )
        return std::size( aVParaMap );
    if( pMap == aHParaMap )
        return std::size( aHParaMap );
    if( pMap == aHFrameMap )
        return std::size( aHFrameMap );
    if( pMap == aVFrameMap )
        return std::size( aVFrameMap );
    if( pMap == aHCharMap )
        return std::size( aHCharMap );
    if( pMap == aHCharHtmlMap )
        return std::size( aHCharHtmlMap );
    if( pMap == aHCharHtmlAbsMap )
        return std::size( aHCharHtmlAbsMap );
    if( pMap == aVCharMap )
        return std::size( aVCharMap );
    if( pMap == aVCharHtmlMap )
        return std::size( aVCharHtmlMap );
    if( pMap == aVCharHtmlAbsMap )
        return std::size( aVCharHtmlAbsMap );
    if( pMap == aHPageHtmlMap )
        return std::size( aHPageHtmlMap );
    if( pMap == aHFlyHtmlMap )
        return std::size( aHFlyHtmlMap );
    if( pMap == aVFlyHtmlMap )
        return std::size( aVFlyHtmlMap );
    if( pMap == aVMultiSelectionMap )
        return std::size( aVMultiSelectionMap );
    if( pMap == aHMultiSelectionMap )
        return std::size( aHMultiSelectionMap );
    return std::size(aHPageMap);
}

static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
            SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL, bool bDontMirrorRTL)
{
    //special handling of STR_FROMLEFT
    if(SvxSwFramePosString::FROMLEFT == eStringId)
    {
        bool bMirrorRtlDrawObjs = !bDontMirrorRTL;
        bool bSwapLR = bRTL && bMirrorRtlDrawObjs;
        eStringId = bVertical ?
            bRTL ? SvxSwFramePosString::FROMBOTTOM : SvxSwFramePosString::FROMTOP :
            bSwapLR ? SvxSwFramePosString::FROMRIGHT : SvxSwFramePosString::FROMLEFT;
        return eStringId;
    }
    if(bVertical)
    {
        //exchange horizontal strings with vertical strings and vice versa
        static const StringIdPair_Impl aHoriIds[] =
        {
            {SvxSwFramePosString::LEFT,           SvxSwFramePosString::TOP},
            {SvxSwFramePosString::RIGHT,          SvxSwFramePosString::BOTTOM},
            {SvxSwFramePosString::CENTER_HORI,    SvxSwFramePosString::CENTER_VERT},
            {SvxSwFramePosString::FROMTOP,        SvxSwFramePosString::FROMRIGHT},
            {SvxSwFramePosString::REL_PG_LEFT,    SvxSwFramePosString::REL_PG_TOP},
            {SvxSwFramePosString::REL_PG_RIGHT,   SvxSwFramePosString::REL_PG_BOTTOM} ,
            {SvxSwFramePosString::REL_FRM_LEFT,   SvxSwFramePosString::REL_FRM_TOP},
            {SvxSwFramePosString::REL_FRM_RIGHT,  SvxSwFramePosString::REL_FRM_BOTTOM}
        };
        static const StringIdPair_Impl aVertIds[] =
        {
            {SvxSwFramePosString::TOP,            SvxSwFramePosString::RIGHT},
            {SvxSwFramePosString::BOTTOM,         SvxSwFramePosString::LEFT },
            {SvxSwFramePosString::CENTER_VERT,    SvxSwFramePosString::CENTER_HORI},
            {SvxSwFramePosString::FROMTOP,        SvxSwFramePosString::FROMRIGHT },
            {SvxSwFramePosString::REL_PG_TOP,     SvxSwFramePosString::REL_PG_LEFT },
            {SvxSwFramePosString::REL_PG_BOTTOM,  SvxSwFramePosString::REL_PG_RIGHT } ,
            {SvxSwFramePosString::REL_FRM_TOP,    SvxSwFramePosString::REL_FRM_LEFT },
            {SvxSwFramePosString::REL_FRM_BOTTOM, SvxSwFramePosString::REL_FRM_RIGHT }
        };
        for(const auto &a : aHoriIds)
        {
            if(a.eHori == eStringId)
            {
                eStringId = a.eVert;
                return eStringId;
            }
        }
        for(const auto &a : aVertIds)
        {
            if(a.eHori == eStringId)
            {
                eStringId = a.eVert;
                break;
            }
        }
    }
    return eStringId;
}
// #i22341# - helper method in order to determine all possible
// listbox relations in a relation map for a given relation
static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
{
    LB nLBRelations = LB::NONE;

    for (RelationMap const & nRelMapPos : aRelationMap)
    {
        if ( nRelMapPos.nRelation == _nRel )
        {
            nLBRelations |= nRelMapPos.nLBRelation;
        }
    }

    return nLBRelations;
}

// #i22341# - helper method on order to determine all possible
// listbox relations in a relation map for a given string ID
static LB lcl_GetLBRelationsForStrID(const FrmMap* _pMap,
                                     const SvxSwFramePosString::StringId _eStrId,
                                     const bool _bUseMirrorStr )
{
    LB nLBRelations = LB::NONE;

    std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
    for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
    {
        if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
             ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
        {
            nLBRelations |= _pMap[nRelMapPos].nLBRelations;
        }
    }

    return nLBRelations;
}

SvxSwPosSizeTabPage::SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
    : SfxTabPage(pPage, pController, u"cui/ui/swpossizepage.ui"_ustr, u"SwPosSizePage"_ustr, &rInAttrs)
    , m_pVMap(nullptr)
    , m_pHMap(nullptr)
    , m_pSdrView(nullptr)
    , m_nOldH(HoriOrientation::CENTER)
    , m_nOldHRel(RelOrientation::FRAME)
    , m_nOldV(VertOrientation::TOP)
    , m_nOldVRel(RelOrientation::PRINT_AREA)
    , m_fWidthHeightRatio(1.0)
    , m_bHtmlMode(false)
    , m_bIsVerticalFrame(false)
    , m_bPositioningDisabled(false)
    , m_bIsMultiSelection(false)
    , m_bIsInRightToLeft(false)
    , m_nProtectSizeState(TRISTATE_FALSE)
    , m_aRatioTop(ConnectorType::Top)
    , m_aRatioBottom(ConnectorType::Bottom)
    , m_xWidthMF(m_xBuilder->weld_metric_spin_button(u"width"_ustr, FieldUnit::CM))
    , m_xHeightMF(m_xBuilder->weld_metric_spin_button(u"height"_ustr, FieldUnit::CM))
    , m_xKeepRatioCB(m_xBuilder->weld_check_button(u"ratio"_ustr))
    , m_xCbxScaleImg(m_xBuilder->weld_image(u"imRatio"_ustr))
    , m_xImgRatioTop(new weld::CustomWeld(*m_xBuilder, u"daRatioTop"_ustr, m_aRatioTop))
    , m_xImgRatioBottom(new weld::CustomWeld(*m_xBuilder, u"daRatioBottom"_ustr, m_aRatioBottom))
    , m_xToPageRB(m_xBuilder->weld_radio_button(u"topage"_ustr))
    , m_xToParaRB(m_xBuilder->weld_radio_button(u"topara"_ustr))
    , m_xToCharRB(m_xBuilder->weld_radio_button(u"tochar"_ustr))
    , m_xAsCharRB(m_xBuilder->weld_radio_button(u"aschar"_ustr))
    , m_xToFrameRB(m_xBuilder->weld_radio_button(u"toframe"_ustr))
    , m_xPositionCB(m_xBuilder->weld_check_button(u"pos"_ustr))
    , m_xSizeCB(m_xBuilder->weld_check_button(u"size"_ustr))
    , m_xPosFrame(m_xBuilder->weld_widget(u"posframe"_ustr))
    , m_xHoriFT(m_xBuilder->weld_label(u"horiposft"_ustr))
    , m_xHoriLB(m_xBuilder->weld_combo_box(u"horipos"_ustr))
    , m_xHoriByFT(m_xBuilder->weld_label(u"horibyft"_ustr))
    , m_xHoriByMF(m_xBuilder->weld_metric_spin_button(u"byhori"_ustr, FieldUnit::CM))
    , m_xHoriToFT(m_xBuilder->weld_label(u"horitoft"_ustr))
    , m_xHoriToLB(m_xBuilder->weld_combo_box(u"horianchor"_ustr))
    , m_xHoriMirrorCB(m_xBuilder->weld_check_button(u"mirror"_ustr))
    , m_xVertFT(m_xBuilder->weld_label(u"vertposft"_ustr))
    , m_xVertLB(m_xBuilder->weld_combo_box(u"vertpos"_ustr))
    , m_xVertByFT(m_xBuilder->weld_label(u"vertbyft"_ustr))
    , m_xVertByMF(m_xBuilder->weld_metric_spin_button(u"byvert"_ustr, FieldUnit::CM))
    , m_xVertToFT(m_xBuilder->weld_label(u"verttoft"_ustr))
    , m_xVertToLB(m_xBuilder->weld_combo_box(u"vertanchor"_ustr))
    , m_xFollowCB(m_xBuilder->weld_check_button(u"followtextflow"_ustr))
    , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, m_aExampleWN))
{
    setOptimalFrmWidth();
    setOptimalRelWidth();

    FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
    SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
    SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
    SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
    SetFieldUnit(*m_xHeightMF, eDlgUnit, true);

    // vertical alignment = fill makes the drawingarea expand the associated spinedits so we have to size it here
    const sal_Int16 aHeight
        = static_cast<sal_Int16>(std::max(int(m_xKeepRatioCB->get_preferred_size().getHeight() / 2
                                              - m_xWidthMF->get_preferred_size().getHeight() / 2),
                                          12));
    const sal_Int16 aWidth
        = static_cast<sal_Int16>(m_xKeepRatioCB->get_preferred_size().getWidth() / 2);
    m_xImgRatioTop->set_size_request(aWidth, aHeight);
    m_xImgRatioBottom->set_size_request(aWidth, aHeight);
    //init needed for gtk3
    m_xCbxScaleImg->set_from_icon_name(m_xKeepRatioCB->get_active() ? RID_SVXBMP_LOCKED
                                                                    : RID_SVXBMP_UNLOCKED);
    m_xKeepRatioCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RatioHdl_Impl));

    SetExchangeSupport();

    Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
    m_xWidthMF->connect_focus_out(aLk3);
    m_xHeightMF->connect_focus_out(aLk3);
    m_xHoriByMF->connect_focus_out(aLk3);
    m_xVertByMF->connect_focus_out(aLk3);
    m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));

    Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxSwPosSizeTabPage, ModifyHdl);
    m_xWidthMF->connect_value_changed( aLk );
    m_xHeightMF->connect_value_changed( aLk );
    m_xHoriByMF->connect_value_changed( aLk );
    m_xVertByMF->connect_value_changed( aLk );

    Link<weld::Toggleable&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
    m_xToPageRB->connect_toggled( aLk2 );
    m_xToParaRB->connect_toggled( aLk2 );
    m_xToCharRB->connect_toggled( aLk2 );
    m_xAsCharRB->connect_toggled( aLk2 );
    m_xToFrameRB->connect_toggled( aLk2 );

    m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
    m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));

    m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
    m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));

    m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
    m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
}

SvxSwPosSizeTabPage::~SvxSwPosSizeTabPage()
{
    m_xWidthMF.reset();
    m_xHeightMF.reset();
    m_xHoriByMF.reset();
    m_xVertByMF.reset();
}

namespace
{
    struct FrmMaps
    {
        FrmMap const *pMap;
        size_t nCount;
    };
}

void SvxSwPosSizeTabPage::setOptimalFrmWidth()
{
    static const FrmMaps aMaps[] = {
        { aHPageMap, std::size(aHPageMap) },
        { aHPageHtmlMap, std::size(aHPageHtmlMap) },
        { aVPageMap, std::size(aVPageMap) },
        { aVPageHtmlMap, std::size(aVPageHtmlMap) },
        { aHFrameMap, std::size(aHFrameMap) },
        { aHFlyHtmlMap, std::size(aHFlyHtmlMap) },
        { aVFrameMap, std::size(aVFrameMap) },
        { aVFlyHtmlMap, std::size(aVFlyHtmlMap) },
        { aHParaMap, std::size(aHParaMap) },
        { aHParaHtmlMap, std::size(aHParaHtmlMap) },
        { aHParaHtmlAbsMap, std::size(aHParaHtmlAbsMap) },
        { aVParaMap, std::size(aVParaMap) },
        { aVParaHtmlMap, std::size(aVParaHtmlMap) },
        { aHCharMap, std::size(aHCharMap) },
        { aHCharHtmlMap, std::size(aHCharHtmlMap) },
        { aHCharHtmlAbsMap, std::size(aHCharHtmlAbsMap) },
        { aVCharMap, std::size(aVCharMap) },
        { aVCharHtmlMap, std::size(aVCharHtmlMap) },
        { aVCharHtmlAbsMap, std::size(aVCharHtmlAbsMap) },
        { aVAsCharMap, std::size(aVAsCharMap) },
        { aVAsCharHtmlMap, std::size(aVAsCharHtmlMap) }
    };

    std::vector<SvxSwFramePosString::StringId> aFrames;
    for (const FrmMaps& aMap : aMaps)
    {
        for (size_t j = 0; j < aMap.nCount; ++j)
        {
            aFrames.push_back(aMap.pMap[j].eStrId);
            aFrames.push_back(aMap.pMap[j].eMirrorStrId);
        }
    }

    std::sort(aFrames.begin(), aFrames.end());
    aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());

    for (auto const& frame : aFrames)
    {
        m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
    }

    Size aBiggest(m_xHoriLB->get_preferred_size());
    m_xHoriLB->set_size_request(aBiggest.Width(), -1);
    m_xVertLB->set_size_request(aBiggest.Width(), -1);
    m_xHoriLB->clear();
}

namespace
{
    struct RelationMaps
    {
        RelationMap const *pMap;
        size_t nCount;
    };
}

void SvxSwPosSizeTabPage::setOptimalRelWidth()
{
    static const RelationMaps aMaps[] = {
        { aRelationMap, std::size(aRelationMap) },
        { aAsCharRelationMap, std::size(aAsCharRelationMap) }
    };

    std::vector<SvxSwFramePosString::StringId> aRels;
    for (const RelationMaps& aMap : aMaps)
    {
        for (size_t j = 0; j < aMap.nCount; ++j)
        {
            aRels.push_back(aMap.pMap[j].eStrId);
            aRels.push_back(aMap.pMap[j].eMirrorStrId);
        }
    }

    std::sort(aRels.begin(), aRels.end());
    aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());

    for (auto const& elem : aRels)
    {
        m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
    }

    Size aBiggest(m_xHoriLB->get_preferred_size());
    m_xHoriLB->set_size_request(aBiggest.Width(), -1);
    m_xVertLB->set_size_request(aBiggest.Width(), -1);
    m_xHoriLB->clear();
}

std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
{
    return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
}

const WhichRangesContainer & SvxSwPosSizeTabPage::GetRanges()
{
    static const WhichRangesContainer ranges(svl::Items<
        SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
        SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
        SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
        SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
        SID_HTML_MODE, SID_HTML_MODE,
        SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
        SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION,
        SID_ATTR_CHAR_GRABBAG, SID_ATTR_CHAR_GRABBAG
    >);
    return ranges;
}

bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
{
    bool bAnchorChanged = false;
    RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
    bool bModified = false;
    if(bAnchorChanged)
    {
        rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
        bModified = true;
    }
    if (m_xPositionCB->get_state_changed_from_saved())
    {
        if (m_xPositionCB->get_inconsistent())
            rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
        else
            rSet->Put(
                SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
                m_xPositionCB->get_state() == TRISTATE_TRUE ) );
        bModified = true;
    }

    if (m_xSizeCB->get_state_changed_from_saved())
    {
        if (m_xSizeCB->get_inconsistent())
            rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
        else
            rSet->Put(
                SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
                m_xSizeCB->get_state() == TRISTATE_TRUE ) );
        bModified = true;
    }

    const SfxItemSet& rOldSet = GetItemSet();

    if(!m_bPositioningDisabled)
    {
        //on multiple selections the positioning is set via SdrView
        if (m_bIsMultiSelection)
        {
            if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
            {
                auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
                auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));

                // old rectangle with CoreUnit
                m_aRect = m_pSdrView->GetAllMarkedRect();
                m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );

                nHoriByPos += m_aAnchorPos.X();
                nVertByPos += m_aAnchorPos.Y();

                rSet->Put( SfxInt32Item( SID_ATTR_TRANSFORM_POS_X, nHoriByPos ) );
                rSet->Put( SfxInt32Item( SID_ATTR_TRANSFORM_POS_Y, nVertByPos ) );

                bModified = true;
            }
        }
        else
        {
            if ( m_pHMap )
            {
                const SfxInt16Item& rHoriOrient =
                        rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT );
                const SfxInt16Item& rHoriRelation =
                        rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION);
                const SfxInt32Item& rHoriPosition =
                        rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION);

                sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
                short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
                short nRel = GetRelation(*m_xHoriToLB);
                const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
                if (
                    nAlign != rHoriOrient.GetValue() ||
                    nRel != rHoriRelation.GetValue() ||
                    (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
                   )
                {
                    rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
                    rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
                    if(m_xHoriByMF->get_sensitive())
                        rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
                    bModified = true;
                }
            }
            if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
                bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));

            if ( m_pVMap )
            {
                const SfxInt16Item& rVertOrient =
                        rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT);
                const SfxInt16Item& rVertRelation =
                        rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION);
                const SfxInt32Item& rVertPosition =
                        rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION);

                sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
                short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
                short nRel = GetRelation(*m_xVertToLB);
                // #i34055# - convert vertical position for
                // as-character anchored objects
                auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
                if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
                {
                    nVertByPos *= -1;
                }
                if ( nAlign != rVertOrient.GetValue() ||
                     nRel != rVertRelation.GetValue() ||
                     ( m_xVertByMF->get_sensitive() &&
                       nVertByPos != rVertPosition.GetValue() ) )
                {
                    rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
                    rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
                    if(m_xVertByMF->get_sensitive())
                        rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
                    bModified = true;
                }
            }

            // #i18732#
            if (m_xFollowCB->get_state_changed_from_saved())
            {
                //Writer internal type - based on SfxBoolItem
                const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
                if(pItem)
                {
                    std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
                    pFollow->SetValue(m_xFollowCB->get_active());
                    bModified |= nullptr != rSet->Put(std::move(pFollow));
                }
            }
        }
    }
    if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
    {
        sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
        sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
        rSet->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, nWidth ) );
        rSet->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, nHeight ) );
        //this item is required by SdrEditView::SetGeoAttrToMarked()
        rSet->Put( SfxUInt16Item( SID_ATTR_TRANSFORM_SIZE_POINT, sal_uInt16(RectPoint::LT) ) );

        bModified = true;
    }

    return bModified;
}

void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
{
    const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
    bool bInvalidateAnchor = false;
    RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
    if(pItem)
    {
        nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
        switch(nAnchorType)
        {
            case RndStdIds::FLY_AT_PAGE:   m_xToPageRB->set_active(true);  break;
            case RndStdIds::FLY_AT_PARA:   m_xToParaRB->set_active(true);  break;
            case RndStdIds::FLY_AT_CHAR:   m_xToCharRB->set_active(true);  break;
            case RndStdIds::FLY_AS_CHAR:   m_xAsCharRB->set_active(true);  break;
            case RndStdIds::FLY_AT_FLY:    m_xToFrameRB->set_active(true); break;
            default : bInvalidateAnchor = true;
        }
        m_xToPageRB->save_state();
        m_xToParaRB->save_state();
        m_xToCharRB->save_state();
        m_xAsCharRB->save_state();
        m_xToFrameRB->save_state();
    }
    if (bInvalidateAnchor)
    {
        m_xToPageRB->set_sensitive( false );
        m_xToParaRB->set_sensitive( false );
        m_xToCharRB->set_sensitive( false );
        m_xAsCharRB->set_sensitive( false );
        m_xToFrameRB->set_sensitive( false );
    }

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
    if (pItem)
    {
        bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
        m_xPositionCB->set_active(bProtected);
        m_xSizeCB->set_sensitive(!bProtected);
    }
    else
    {
        m_xPositionCB->set_inconsistent(true);
    }

    m_xPositionCB->save_state();

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );

    if (pItem)
    {
        m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
    }
    else
        m_xSizeCB->set_inconsistent(true);
    m_xSizeCB->save_state();

    pItem = GetItem( *rSet, SID_HTML_MODE );
    if(pItem)
    {
        m_bHtmlMode =
            (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
            != 0;
    }

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
    if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
    {
        OUString sHLabel = m_xHoriFT->get_label();
        m_xHoriFT->set_label(m_xVertFT->get_label());
        m_xVertFT->set_label(sHLabel);
        m_bIsVerticalFrame = true;
    }
    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
    if(pItem)
        m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();

    pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
    if(pItem)
    {
        const bool bFollowTextFlow =
            static_cast<const SfxBoolItem*>(pItem)->GetValue();
        m_xFollowCB->set_active(bFollowTextFlow);
    }
    m_xFollowCB->save_state();

    const SfxGrabBagItem* pGrabBag = GetItem(*rSet, SID_ATTR_CHAR_GRABBAG);
    if (pGrabBag)
    {
        const std::map<OUString, css::uno::Any>& rMap = pGrabBag->GetGrabBag();
        auto it = rMap.find(u"DoNotMirrorRtlDrawObjs"_ustr);
        if (it != rMap.end())
        {
            it->second >>= m_bDoNotMirrorRtlDrawObjs;
        }
    }

    if(m_bHtmlMode)
    {
        m_xHoriMirrorCB->hide();
        m_xKeepRatioCB->set_sensitive(false);
        // #i18732# - hide checkbox in HTML mode
        m_xFollowCB->hide();
    }
    else
    {
        // #i18732# correct enable/disable of check box 'Mirror on..'
        m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);

        // #i18732# - enable/disable check box 'Follow text flow'.
        m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
                                   m_xToCharRB->get_active());
    }

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
    sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );

    m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
    m_xWidthMF->save_value();

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
    sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
    m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
    m_xHeightMF->save_value();
    m_fWidthHeightRatio = double(nWidth) / double(nHeight);

    if(m_bPositioningDisabled)
        return;

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
    if(pItem)
    {
        short nHoriOrientation = static_castconst SfxInt16Item*>(pItem)->GetValue();
        m_nOldH = nHoriOrientation;
    }
    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
    if(pItem)
    {
        short nVertOrientation = static_castconst SfxInt16Item*>(pItem)->GetValue();
        m_nOldV = nVertOrientation;
    }
    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
    if(pItem)
    {
        m_nOldHRel = static_castconst SfxInt16Item*>(pItem)->GetValue();
    }

    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
    if(pItem)
    {
        m_nOldVRel = static_castconst SfxInt16Item*>(pItem)->GetValue();
    }
    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
    if(pItem)
        m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
    m_xHoriMirrorCB->save_state();

    sal_Int32 nHoriPos = 0;
    sal_Int32 nVertPos = 0;
    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
    if(pItem)
        nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
    pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
    if(pItem)
        nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();

    InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);

    m_xVertByMF->save_value();
    m_xHoriByMF->save_value();
    // #i18732#
    m_xFollowCB->save_state();

    RangeModifyHdl(m_xWidthMF->get_widget());  // initially set maximum values
}

DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
{
    if( _pSet )
    {
        _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
                m_xPositionCB->get_active()));
        _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
                m_xSizeCB->get_active()));
        FillItemSet( _pSet );
    }
    return DeactivateRC::LeavePage;
}

void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
{
    if (nAnchorEnable & SvxAnchorIds::Fly)
        m_xToFrameRB->show();
    if (!(nAnchorEnable & SvxAnchorIds::Page))
        m_xToPageRB->set_sensitive(false);
}

RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
{
    RndStdIds nRet = RndStdIds::UNKNOWN;
    weld::RadioButton* pCheckedButton = nullptr;
    if(m_xToParaRB->get_sensitive())
    {
        if(m_xToPageRB->get_active())
        {
            nRet = RndStdIds::FLY_AT_PAGE;
            pCheckedButton = m_xToPageRB.get();
        }
        else if(m_xToParaRB->get_active())
        {
            nRet = RndStdIds::FLY_AT_PARA;
            pCheckedButton = m_xToParaRB.get();
        }
        else if(m_xToCharRB->get_active())
        {
            nRet = RndStdIds::FLY_AT_CHAR;
            pCheckedButton = m_xToCharRB.get();
        }
        else if(m_xAsCharRB->get_active())
        {
            nRet = RndStdIds::FLY_AS_CHAR;
            pCheckedButton = m_xAsCharRB.get();
        }
        else if(m_xToFrameRB->get_active())
        {
            nRet = RndStdIds::FLY_AT_FLY;
            pCheckedButton = m_xToFrameRB.get();
        }
    }
    if(pbHasChanged)
    {
         if(pCheckedButton)
             *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
         else
             *pbHasChanged = false;
    }
    return nRet;
}

IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RatioHdl_Impl, weld::Toggleable&, void)
{
    m_xCbxScaleImg->set_from_icon_name(m_xKeepRatioCB->get_active() ? RID_SVXBMP_LOCKED : RID_SVXBMP_UNLOCKED);
}

IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::Toggleable&, void)
{
    RangeModifyHdl(m_xWidthMF->get_widget());
}

IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
{
    if (m_bPositioningDisabled)
        return;
    SvxSwFrameValidation        aVal;

    aVal.nAnchorType = GetAnchorType();
    aVal.bAutoHeight = false;
    aVal.bMirror = m_xHoriMirrorCB->get_active();
    // #i18732#
    aVal.bFollowTextFlow = m_xFollowCB->get_active();

    if ( m_pHMap )
    {
        // horizontal alignment
        sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
        sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
        sal_uInt16 nRel = GetRelation(*m_xHoriToLB);

        aVal.nHoriOrient = static_cast<short>(nAlign);
        aVal.nHRelOrient = static_cast<short>(nRel);
    }
    else
        aVal.nHoriOrient = HoriOrientation::NONE;

    if ( m_pVMap )
    {
        // vertical alignment
        sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
        sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
        sal_uInt16 nRel = GetRelation(*m_xVertToLB);

        aVal.nVertOrient = static_cast<short>(nAlign);
        aVal.nVRelOrient = static_cast<short>(nRel);
    }
    else
        aVal.nVertOrient = VertOrientation::NONE;

    const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
    const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));

    aVal.nHPos = nAtHorzPosVal;
    aVal.nVPos = nAtVertPosVal;

    sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
    sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
    aVal.nWidth  = nWidth;
    aVal.nHeight = nHeight;

    m_aValidateLink.Call(aVal);

    // minimum width also for style
    m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
    m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);

    sal_Int32 nMaxWidth(aVal.nMaxWidth);
    sal_Int32 nMaxHeight(aVal.nMaxHeight);

    sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
    m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);

    nTmp = m_xWidthMF->normalize(nMaxWidth);
    m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);

    m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
                           m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
    if ( aVal.nHPos != nAtHorzPosVal )
        m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);

    m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
                           m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
    if ( aVal.nVPos != nAtVertPosVal )
        m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
}

IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::Toggleable&, void)
{
    m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);

    // #i18732# - enable check box 'Follow text flow' for anchor
    // type to-paragraph' and to-character
    m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());

    RndStdIds nId = GetAnchorType();

    InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
    RangeModifyHdl(m_xWidthMF->get_widget());

    if(m_bHtmlMode)
    {
        PosHdl(*m_xHoriLB);
        PosHdl(*m_xVertLB);
    }
}

IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::Toggleable&, void)
{
    RndStdIds nId = GetAnchorType();
    InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
}

IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
{
    bool bHori = &rLB == m_xHoriToLB.get();

    UpdateExample();

    if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
    {
        if(bHori)
        {
            sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
            if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
            {
                m_xVertLB->set_active(1);
            }
            else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
            {
                m_xVertLB->set_active(0);
            }
        }
    }
    RangeModifyHdl(m_xWidthMF->get_widget());
}

IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
{
    bool bHori = &rLB == m_xHoriLB.get();
    weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
    weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
    FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;


    sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
    sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);

    if (bHori)
    {
        bool bEnable = HoriOrientation::NONE == nAlign;
        m_xHoriByMF->set_sensitive( bEnable );
        m_xHoriByFT->set_sensitive( bEnable );
    }
    else
    {
        bool bEnable = VertOrientation::NONE == nAlign;
        m_xVertByMF->set_sensitive( bEnable );
        m_xVertByFT->set_sensitive( bEnable );
    }

    RangeModifyHdl(m_xWidthMF->get_widget());

    short nRel = 0;
    if (rLB.get_active() != -1)
    {
        if (pRelLB->get_active() != -1)
            nRel = weld::fromId<RelationMap*>(pRelLB->get_active_id())->nRelation;

        FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
    }
    else
        pRelLB->clear();

    UpdateExample();

    // special treatment for HTML-Mode with horz-vert-dependencies
    if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
        return;

    bool bSet = false;
    if(bHori)
    {
        // on the right only below is allowed - from the left only at the top
        // from the left at the character -> below
        if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
                0 == m_xVertLB->get_active())
        {
            if(RelOrientation::FRAME == nRel)
                m_xVertLB->set_active(1);
            else
                m_xVertLB->set_active(0);
            bSet = true;
        }
        else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
        {
            m_xVertLB->set_active(0);
            bSet = true;
        }
        else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
        {
            m_xVertLB->set_active(0);
            bSet = true;
        }
        if(bSet)
            PosHdl(*m_xVertLB);
    }
    else
    {
        if(VertOrientation::TOP == nAlign)
        {
            if(1 == m_xHoriLB->get_active())
            {
                m_xHoriLB->set_active(0);
                bSet = true;
            }
            m_xHoriToLB->set_active(1);
        }
        else if(VertOrientation::CHAR_BOTTOM == nAlign)
        {
            if(2 == m_xHoriLB->get_active())
            {
                m_xHoriLB->set_active(0);
                bSet = true;
            }
            m_xHoriToLB->set_active(0) ;
        }
        if(bSet)
            PosHdl(*m_xHoriLB);
    }
}

IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
{
    auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
    auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
    if (m_xKeepRatioCB->get_active())
    {
        if ( &rEdit == m_xWidthMF.get() )
        {
            nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
            m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
        }
        else if(&rEdit == m_xHeightMF.get())
        {
            nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
            m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
        }
    }
    m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
    UpdateExample();
}

IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::Toggleable&, void)
{
    if (m_xSizeCB->get_sensitive())
    {
        m_nProtectSizeState = m_xSizeCB->get_state();
    }

    m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ?  TRISTATE_TRUE : m_nProtectSizeState);
    m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
}

short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
{
    short nRel = 0;
    int nPos = rRelationLB.get_active();
    if (nPos != -1)
    {
        RelationMap *pEntry = weld::fromId<RelationMap*>(rRelationLB.get_id(nPos));
        nRel = pEntry->nRelation;
    }

    return nRel;
}

short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
{
    short nAlign = 0;

    // #i22341# - special handling also for map <aVCharMap>,
    // because it contains ambiguous items for alignment
    if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
            pMap == aVCharMap )
    {
        if (rRelationLB.get_active() != -1)
        {
            LB  nRel = weld::fromId<RelationMap*>(rRelationLB.get_active_id())->nLBRelation;
            std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
            SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;

            for (std::size_t i = 0; i < nMapCount; i++)
            {
                if (pMap[i].eStrId == eStrId)
                {
                    LB nLBRelations = pMap[i].nLBRelations;
                    if (nLBRelations & nRel)
                    {
                        nAlign = pMap[i].nAlign;
                        break;
                    }
                }
            }
        }
    }
    else if (pMap)
        nAlign = pMap[nMapPos].nAlign;

    return nAlign;
}

sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox&&nbsp;rAlignLB)
{
    sal_uInt16 nMapPos = 0;
    int nLBSelPos = rAlignLB.get_active();

    if (nLBSelPos != -1)
    {
        if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
        {
            std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
            OUString sSelEntry(rAlignLB.get_active_text());

            for (std::size_t i = 0; i < nMapCount; i++)
            {
                SvxSwFramePosString::StringId eResId = pMap[i].eStrId;

                OUString sEntry = SvxSwFramePosString::GetString(eResId);

                if (sEntry == sSelEntry)
                {
                    nMapPos = sal::static_int_cast< sal_uInt16 >(i);
                    break;
                }
            }
        }
        else
            nMapPos = nLBSelPos;
    }

    return nMapPos;
}

void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
                                sal_uInt16 nH,
                                sal_uInt16 nHRel,
                                sal_uInt16 nV,
                                sal_uInt16 nVRel,
                                tools::Long   nX,
                                tools::Long   nY)
{
    int nPos = m_xVertLB->get_active();
    if (nPos != -1 && m_pVMap)
    {
        m_nOldV    = m_pVMap[nPos].nAlign;
        nPos = m_xVertToLB->get_active();
        if (nPos != -1)
            m_nOldVRel = weld::fromId<RelationMap*>(m_xVertToLB->get_id(nPos))->nRelation;
    }

    nPos = m_xHoriLB->get_active();
    if (nPos != -1 && m_pHMap)
    {
        m_nOldH    = m_pHMap[nPos].nAlign;

        nPos = m_xHoriToLB->get_active();
        if (nPos != -1)
            m_nOldHRel = weld::fromId<RelationMap*>(m_xHoriToLB->get_id(nPos))->nRelation;
    }

    bool bEnable = true;
    if( m_bIsMultiSelection )
    {
        m_pVMap = aVMultiSelectionMap;
        m_pHMap = aHMultiSelectionMap;
    }
    else if (nAnchor == RndStdIds::FLY_AT_PAGE)
    {
        m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
        m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
    }
    else if (nAnchor == RndStdIds::FLY_AT_FLY)
    {
        // #i18732# - own vertical alignment map for to frame
        // anchored objects.
        m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
        m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
    }
    else if (nAnchor == RndStdIds::FLY_AT_PARA)
    {
        if(m_bHtmlMode)
        {
            m_pVMap = aVParaHtmlMap;
            m_pHMap = aHParaHtmlAbsMap;
        }
        else
        {
            m_pVMap = aVParaMap;
            m_pHMap = aHParaMap;
        }
    }
    else if (nAnchor == RndStdIds::FLY_AT_CHAR)
    {
        if(m_bHtmlMode)
        {
            m_pVMap = aVCharHtmlAbsMap;
            m_pHMap = aHCharHtmlAbsMap;
        }
        else
        {
            m_pVMap = aVCharMap;
            m_pHMap = aHCharMap;
        }
    }
    else if (nAnchor == RndStdIds::FLY_AS_CHAR)
    {
        m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap     : aVAsCharMap;
        m_pHMap = nullptr;
        bEnable = false;
    }
    m_xHoriLB->set_sensitive(bEnable);
    m_xHoriFT->set_sensitive(bEnable);

    // select current Pos
    // horizontal
    if ( nH == USHRT_MAX )
    {
        nH    = m_nOldH;
        nHRel = m_nOldHRel;
    }
    // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
    sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
    FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);

    // vertical
    if ( nV == USHRT_MAX )
    {
        nV    = m_nOldV;
        nVRel = m_nOldVRel;
    }
    // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
    nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
    FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);

    // Edits init
    bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
    if (!bEnable)
    {
        m_xHoriByMF->set_value(0, FieldUnit::TWIP);
    }
    else if(m_bIsMultiSelection)
    {
         m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
    }
    else
    {
        if (nX != LONG_MAX)
            m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
    }
    m_xHoriByFT->set_sensitive(bEnable);
    m_xHoriByMF->set_sensitive(bEnable);

    bEnable = nV == VertOrientation::NONE;
    if ( !bEnable )
    {
        m_xVertByMF->set_value( 0, FieldUnit::TWIP );
    }
    else if(m_bIsMultiSelection)
    {
         m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
    }
    else
    {
        if (nAnchor == RndStdIds::FLY_AS_CHAR)
        {
            if ( nY == LONG_MAX )
                nY = 0;
            else
                nY *= -1;
        }
        if ( nY != LONG_MAX )
            m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
    }
    m_xVertByFT->set_sensitive( bEnable );
    m_xVertByMF->set_sensitive( bEnable );
    UpdateExample();
}

void SvxSwPosSizeTabPage::UpdateExample()
{
    int nPos = m_xHoriLB->get_active();
    if (m_pHMap && nPos != -1)
    {
        sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
        short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
        short nRel = GetRelation(*m_xHoriToLB);

        m_aExampleWN.SetHAlign(nAlign);
        m_aExampleWN.SetHoriRel(nRel);
    }

    nPos = m_xVertLB->get_active();
    if (m_pVMap && nPos != -1)
    {
        sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
        sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
        sal_uInt16 nRel = GetRelation(*m_xVertToLB);

        m_aExampleWN.SetVAlign(nAlign);
        m_aExampleWN.SetVertRel(nRel);
    }

    // Size
    auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
    auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
    m_aExampleWN.SetRelPos(Point(nXPos, nYPos));

    m_aExampleWN.SetAnchor( GetAnchorType() );
    m_aExampleWN.Invalidate();
}

--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=97 G=95

¤ Dauer der Verarbeitung: 0.17 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.