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

Quelle  column.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 <column.hxx>

#include <hintids.hxx>
#include <svx/dialmgr.hxx>
#include <svx/strings.hrc>
#include <sfx2/htmlmode.hxx>
#include <svx/colorbox.hxx>
#include <editeng/borderline.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/sizeitem.hxx>
#include <editeng/frmdiritem.hxx>
#include <editeng/ulspitem.hxx>
#include <svl/ctloptions.hxx>
#include <svl/itemset.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/event.hxx>
#include <vcl/fieldvalues.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>

#include <swmodule.hxx>

#include <swtypes.hxx>
#include <wrtsh.hxx>
#include <view.hxx>
#include <docsh.hxx>
#include <uitool.hxx>
#include <cmdid.h>
#include <viewopt.hxx>
#include <fmtclbl.hxx>
#include <fmtfsize.hxx>
#include <frmatr.hxx>
#include <colmgr.hxx>
#include <prcntfld.hxx>
#include <strings.hrc>
#include <section.hxx>
#include <pagedesc.hxx>

//to match associated data in ColumnPage.ui
#define LISTBOX_SELECTION       0
#define LISTBOX_SECTION         1
#define LISTBOX_SECTIONS        2
#define LISTBOX_PAGE            3
#define LISTBOX_FRAME           4

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

#define FRAME_FORMAT_WIDTH 1000

// static data
const sal_uInt16 nVisCols = 3;

static bool IsMarkInSameSection( SwWrtShell& rWrtSh, const SwSection* pSect )
{
    rWrtSh.SwapPam();
    bool bRet = pSect == rWrtSh.GetCurrSection();
    rWrtSh.SwapPam();
    return bRet;
}

SwColumnDlg::SwColumnDlg(weld::Window* pParent, SwWrtShell& rSh)
    : SfxDialogController(pParent, u"modules/swriter/ui/columndialog.ui"_ustr, u"ColumnDialog"_ustr)
    , m_rWrtShell(rSh)
    , m_pFrameSet(nullptr)
    , m_nOldSelection(0)
    , m_nSelectionWidth(0)
    , m_bPageChanged(false)
    , m_bSectionChanged(false)
    , m_bSelSectionChanged(false)
    , m_bFrameChanged(false)
    , m_xContentArea(m_xBuilder->weld_container(u"content"_ustr))
    , m_xOkButton(m_xBuilder->weld_button(u"ok"_ustr))
{
    SwRect aRect;
    m_rWrtShell.CalcBoundRect(aRect, RndStdIds::FLY_AS_CHAR);

    m_nSelectionWidth = aRect.Width();

    SfxItemSet* pColPgSet = nullptr;
    static const auto aSectIds = svl::Items<RES_FRM_SIZE, RES_FRM_SIZE,
                      RES_COL, RES_COL,
                      RES_COLUMNBALANCE, RES_FRAMEDIR>;

    const SwSection* pCurrSection = m_rWrtShell.GetCurrSection();
    const sal_uInt16 nFullSectCnt = m_rWrtShell.GetFullSelectedSectionCount();
    if( pCurrSection && ( !m_rWrtShell.HasSelection() || 0 != nFullSectCnt ))
    {
        m_nSelectionWidth = rSh.GetSectionWidth(*pCurrSection->GetFormat());
        if ( !m_nSelectionWidth )
            m_nSelectionWidth = USHRT_MAX;
        m_pSectionSet.reset( new SfxItemSet( m_rWrtShell.GetAttrPool(), aSectIds ) );
        m_pSectionSet->Put( pCurrSection->GetFormat()->GetAttrSet() );
        pColPgSet = m_pSectionSet.get();
    }

    if( m_rWrtShell.HasSelection() && m_rWrtShell.IsInsRegionAvailable() &&
        ( !pCurrSection || ( 1 != nFullSectCnt &&
            IsMarkInSameSection( m_rWrtShell, pCurrSection ) )))
    {
        m_pSelectionSet.reset( new SfxItemSet( m_rWrtShell.GetAttrPool(), aSectIds ) );
        pColPgSet = m_pSelectionSet.get();
    }

    if( m_rWrtShell.GetFlyFrameFormat() )
    {
        const SwFrameFormat* pFormat = rSh.GetFlyFrameFormat() ;
        m_pFrameSet = new SfxItemSet(m_rWrtShell.GetAttrPool(), aSectIds );
        m_pFrameSet->Put(pFormat->GetFrameSize());
        m_pFrameSet->Put(pFormat->GetCol());
        pColPgSet = m_pFrameSet;
    }

    const SwPageDesc* pPageDesc = m_rWrtShell.GetSelectedPageDescs();
    if( pPageDesc )
    {
        m_pPageSet = std::make_unique<SfxItemSetFixed<
                RES_FRM_SIZE, RES_FRM_SIZE,
                RES_LR_SPACE, RES_LR_SPACE,
                RES_COL, RES_COL>>(m_rWrtShell.GetAttrPool());

        const SwFrameFormat &rFormat = pPageDesc->GetMaster();
        m_nPageWidth = rFormat.GetFrameSize().GetSize().Width();

        const SvxLRSpaceItem& rLRSpace = rFormat.GetLRSpace();
        const SvxBoxItem& rBox = rFormat.GetBox();
        m_nPageWidth
            -= rLRSpace.ResolveLeft({}) + rLRSpace.ResolveRight({}) + rBox.GetSmallestDistance();

        m_pPageSet->Put(rFormat.GetCol());
        m_pPageSet->Put(rFormat.GetLRSpace());
        pColPgSet = m_pPageSet.get();
    }

    assert(pColPgSet);

    // create TabPage
    m_xTabPage = std::make_unique<SwColumnPage>(m_xContentArea.get(), this, *pColPgSet);
    m_xTabPage->GetApplyLabel()->show();
    weld::ComboBox* pApplyToLB = m_xTabPage->GetApplyComboBox();
    pApplyToLB->show();

    if (pCurrSection && (!m_rWrtShell.HasSelection() || 0 != nFullSectCnt))
    {
        pApplyToLB->remove_id(1 >= nFullSectCnt ? OUString::number(LISTBOX_SECTIONS) : OUString::number(LISTBOX_SECTION));
    }
    else
    {
        pApplyToLB->remove_id(OUString::number(LISTBOX_SECTION));
        pApplyToLB->remove_id(OUString::number(LISTBOX_SECTIONS));
    }

    if (!( m_rWrtShell.HasSelection() && m_rWrtShell.IsInsRegionAvailable() &&
        ( !pCurrSection || ( 1 != nFullSectCnt &&
            IsMarkInSameSection( m_rWrtShell, pCurrSection ) ))))
        pApplyToLB->remove_id(OUString::number(LISTBOX_SELECTION));

    if (!m_rWrtShell.GetFlyFrameFormat())
        pApplyToLB->remove_id(OUString::number(LISTBOX_FRAME));

    const int nPagePos = pApplyToLB->find_id(OUString::number(LISTBOX_PAGE));
    if (m_pPageSet && pPageDesc)
    {
        const OUString sPageStr = pApplyToLB->get_text(nPagePos) + pPageDesc->GetName().toString();
        pApplyToLB->remove(nPagePos);
        OUString sId(OUString::number(LISTBOX_PAGE));
        pApplyToLB->insert(nPagePos, sPageStr, &sId, nullptr, nullptr);
    }
    else
        pApplyToLB->remove( nPagePos );

    pApplyToLB->set_active(0);
    ObjectHdl(nullptr);

    pApplyToLB->connect_changed(LINK(this, SwColumnDlg, ObjectListBoxHdl));
    m_xOkButton->connect_clicked(LINK(this, SwColumnDlg, OkHdl));
    //#i80458# if no columns can be set then disable OK
    if (!pApplyToLB->get_count())
        m_xOkButton->set_sensitive(false);
    //#i97810# set focus to the TabPage
    m_xTabPage->ActivateColumnControl();
}

SwColumnDlg::~SwColumnDlg()
{
    m_xTabPage.reset();
}

IMPL_LINK(SwColumnDlg, ObjectListBoxHdl, weld::ComboBox&, rBox, void)
{
    ObjectHdl(&rBox);
}

void SwColumnDlg::ObjectHdl(const weld::ComboBox* pBox)
{
    SfxItemSet* pSet = EvalCurrentSelection();

    if (pBox)
    {
        m_xTabPage->FillItemSet(pSet);
    }
    weld::ComboBox* pApplyToLB = m_xTabPage->GetApplyComboBox();
    m_nOldSelection = pApplyToLB->get_active_id().toInt32();
    tools::Long nWidth = m_nSelectionWidth;
    switch(m_nOldSelection)
    {
        case LISTBOX_SELECTION  :
            pSet = m_pSelectionSet.get();
            if( m_pSelectionSet )
                pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
        break;
        case LISTBOX_SECTION    :
        case LISTBOX_SECTIONS   :
            pSet = m_pSectionSet.get();
            pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
        break;
        case LISTBOX_PAGE       :
            nWidth = m_nPageWidth;
            pSet = m_pPageSet.get();
            pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
        break;
        case LISTBOX_FRAME:
            pSet = m_pFrameSet;
        break;
    }

    bool bIsSection = pSet == m_pSectionSet.get() || pSet == m_pSelectionSet.get();
    m_xTabPage->ShowBalance(bIsSection);
    m_xTabPage->SetInSection(bIsSection);
    m_xTabPage->SetFrameMode(true);
    m_xTabPage->SetPageWidth(nWidth);
    if( pSet )
        m_xTabPage->Reset(pSet);
}

IMPL_LINK_NOARG(SwColumnDlg, OkHdl, weld::Button&, void)
{
    // evaluate current selection
    SfxItemSet* pSet = EvalCurrentSelection();
    m_xTabPage->FillItemSet(pSet);

    if(m_pSelectionSet && SfxItemState::SET == m_pSelectionSet->GetItemState(RES_COL))
    {
        //insert region with columns
        const SwFormatCol& rColItem = m_pSelectionSet->Get(RES_COL);
        //only if there actually are columns!
        if(rColItem.GetNumCols() > 1)
            m_rWrtShell.GetView().GetViewFrame().GetDispatcher()->Execute(
                FN_INSERT_REGION, SfxCallMode::ASYNCHRON, *m_pSelectionSet );
    }

    if(m_pSectionSet && m_pSectionSet->Count() && m_bSectionChanged )
    {
        const SwSection* pCurrSection = m_rWrtShell.GetCurrSection();
        const SwSectionFormat* pFormat = pCurrSection->GetFormat();
        const size_t nNewPos = m_rWrtShell.GetSectionFormatPos( *pFormat );
        SwSectionData aData(*pCurrSection);
        m_rWrtShell.UpdateSection( nNewPos, aData, m_pSectionSet.get() );
    }

    if(m_pSectionSet && m_pSectionSet->Count() && m_bSelSectionChanged )
    {
        m_rWrtShell.SetSectionAttr( *m_pSectionSet );
    }

    if(m_pPageSet && SfxItemState::SET == m_pPageSet->GetItemState(RES_COL) && m_bPageChanged)
    {
        // determine current PageDescriptor and fill the Set with it
        const size_t nCurIdx = m_rWrtShell.GetCurPageDesc();
        SwPageDesc aPageDesc(m_rWrtShell.GetPageDesc(nCurIdx));
        SwFrameFormat &rFormat = aPageDesc.GetMaster();
        rFormat.SetFormatAttr(m_pPageSet->Get(RES_COL));
        m_rWrtShell.ChgPageDesc(nCurIdx, aPageDesc);
    }
    if(m_pFrameSet && SfxItemState::SET == m_pFrameSet->GetItemState(RES_COL) && m_bFrameChanged)
    {
        SfxItemSetFixed<RES_COL, RES_COL> aTmp(*m_pFrameSet->GetPool());
        aTmp.Put(*m_pFrameSet);
        m_rWrtShell.StartAction();
        m_rWrtShell.Push();
        m_rWrtShell.SetFlyFrameAttr( aTmp );
        // undo the frame selection again
        if(m_rWrtShell.IsFrameSelected())
        {
            m_rWrtShell.UnSelectFrame();
            m_rWrtShell.LeaveSelFrameMode();
        }
        m_rWrtShell.Pop();
        m_rWrtShell.EndAction();
    }
    m_xDialog->response(RET_OK);
}

SfxItemSet* SwColumnDlg::EvalCurrentSelection()
{
    SfxItemSet* pSet = nullptr;

    switch(m_nOldSelection)
    {
        case LISTBOX_SELECTION  :
            pSet = m_pSelectionSet.get();
        break;
        case LISTBOX_SECTION    :
            pSet = m_pSectionSet.get();
            m_bSectionChanged = true;
        break;
        case LISTBOX_SECTIONS   :
            pSet = m_pSectionSet.get();
            m_bSelSectionChanged = true;
        break;
        case LISTBOX_PAGE       :
            pSet = m_pPageSet.get();
            m_bPageChanged = true;
        break;
        case LISTBOX_FRAME:
            pSet = m_pFrameSet;
            m_bFrameChanged = true;
        break;
    }

    return pSet;
}

static
sal_uInt16 GetMaxWidth( SwColMgr const * pColMgr, sal_uInt16 nCols )
{
    sal_uInt16 nMax = pColMgr->GetActualSize();
    if( --nCols )
        nMax -= pColMgr->GetGutterWidth() * nCols;
    return nMax;
}

const WhichRangesContainer SwColumnPage::s_aPageRg(svl::Items<RES_COL, RES_COL>);

void SwColumnPage::ResetColWidth()
{
    if( m_nCols )
    {
        const sal_uInt16 nWidth = GetMaxWidth( m_xColMgr.get(), m_nCols ) / m_nCols;

        for(sal_uInt16 i = 0; i < m_nCols; ++i)
            m_nColWidth[i] = static_cast<tools::Long>(nWidth);
    }

}

constexpr sal_uInt16 g_nMinWidth(MINLAY);

// Now as TabPage
SwColumnPage::SwColumnPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
    : SfxTabPage(pPage, pController, u"modules/swriter/ui/columnpage.ui"_ustr, u"ColumnPage"_ustr, &rSet)
    , m_nFirstVis(0)
    , m_nCols(0)
    , m_pModifiedField(nullptr)
    , m_bFormat(false)
    , m_bFrame(false)
    , m_bHtmlMode(false)
    , m_bLockUpdate(false)
    , m_xCLNrEdt(m_xBuilder->weld_spin_button(u"colsnf"_ustr))
    , m_xBalanceColsCB(m_xBuilder->weld_check_button(u"balance"_ustr))
    , m_xBtnBack(m_xBuilder->weld_button(u"back"_ustr))
    , m_xLbl1(m_xBuilder->weld_label(u"1"_ustr))
    , m_xLbl2(m_xBuilder->weld_label(u"2"_ustr))
    , m_xLbl3(m_xBuilder->weld_label(u"3"_ustr))
    , m_xBtnNext(m_xBuilder->weld_button(u"next"_ustr))
    , m_xAutoWidthBox(m_xBuilder->weld_check_button(u"autowidth"_ustr))
    , m_xLineTypeLbl(m_xBuilder->weld_label(u"linestyleft"_ustr))
    , m_xLineWidthLbl(m_xBuilder->weld_label(u"linewidthft"_ustr))
    , m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button(u"linewidthmf"_ustr, FieldUnit::POINT))
    , m_xLineColorLbl(m_xBuilder->weld_label(u"linecolorft"_ustr))
    , m_xLineHeightLbl(m_xBuilder->weld_label(u"lineheightft"_ustr))
    , m_xLineHeightEdit(m_xBuilder->weld_metric_spin_button(u"lineheightmf"_ustr, FieldUnit::PERCENT))
    , m_xLinePosLbl(m_xBuilder->weld_label(u"lineposft"_ustr))
    , m_xLinePosDLB(m_xBuilder->weld_combo_box(u"lineposlb"_ustr))
    , m_xTextDirectionFT(m_xBuilder->weld_label(u"textdirectionft"_ustr))
    , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box(u"textdirectionlb"_ustr)))
    , m_xLineColorDLB(new ColorListBox(m_xBuilder->weld_menu_button(u"colorlb"_ustr),
                [this]{ return GetFrameWeld(); }))
    , m_xLineTypeDLB(new SvtLineListBox(m_xBuilder->weld_menu_button(u"linestylelb"_ustr)))
    , m_xEd1(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"width1mf"_ustr, FieldUnit::CM)))
    , m_xEd2(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"width2mf"_ustr, FieldUnit::CM)))
    , m_xEd3(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"width3mf"_ustr, FieldUnit::CM)))
    , m_xDistEd1(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"spacing1mf"_ustr, FieldUnit::CM)))
    , m_xDistEd2(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"spacing2mf"_ustr, FieldUnit::CM)))
    , m_xDefaultVS(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, m_aDefaultVS))
    , m_xPgeExampleWN(new weld::CustomWeld(*m_xBuilder, u"pageexample"_ustr, m_aPgeExampleWN))
    , m_xFrameExampleWN(new weld::CustomWeld(*m_xBuilder, u"frameexample"_ustr, m_aFrameExampleWN))
    , m_xApplyToFT(m_xBuilder->weld_label(u"applytoft"_ustr))
    , m_xApplyToLB(m_xBuilder->weld_combo_box(u"applytolb"_ustr))
{
    connectPercentField(*m_xEd1);
    connectPercentField(*m_xEd2);
    connectPercentField(*m_xEd3);
    connectPercentField(*m_xDistEd1);
    connectPercentField(*m_xDistEd2);

    m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
    m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
    m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));

    SetExchangeSupport();

    m_aDefaultVS.SetColCount(5);

    for (int i = 0; i < 5; ++i)
    //Set accessible name one by one
    {
        OUString aItemText;
        switch( i )
        {
            case 0:
                aItemText =  SwResId( STR_COLUMN_VALUESET_ITEM0 ) ;
                break;
            case 1:
                aItemText =  SwResId( STR_COLUMN_VALUESET_ITEM1 ) ;
                break;
            case 2:
                aItemText =  SwResId( STR_COLUMN_VALUESET_ITEM2 ) ;
                break;
            case 3:
                aItemText =  SwResId( STR_COLUMN_VALUESET_ITEM3 );
                break;
            default:
                aItemText =  SwResId( STR_COLUMN_VALUESET_ITEM4 );
                break;
        }
        m_aDefaultVS.InsertItem( i + 1, aItemText, i );
    }

    m_aDefaultVS.SetSelectHdl(LINK(this, SwColumnPage, SetDefaultsHdl));

    Link<weld::SpinButton&,void> aCLNrLk = LINK(this, SwColumnPage, ColModify);
    m_xCLNrEdt->connect_value_changed(aCLNrLk);
    Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwColumnPage, GapModify);
    m_xDistEd1->connect_value_changed(aLk);
    m_xDistEd2->connect_value_changed(aLk);

    aLk = LINK(this, SwColumnPage, EdModify);

    m_xEd1->connect_value_changed(aLk);
    m_xEd2->connect_value_changed(aLk);
    m_xEd3->connect_value_changed(aLk);

    m_xBtnBack->connect_clicked(LINK(this, SwColumnPage, Up));
    m_xBtnNext->connect_clicked(LINK(this, SwColumnPage, Down));
    m_xAutoWidthBox->connect_toggled(LINK(this, SwColumnPage, AutoWidthHdl));

    Link<weld::MetricSpinButton&,void> aLk2 = LINK( this, SwColumnPage, UpdateColMgr );
    m_xLineTypeDLB->SetSelectHdl(LINK(this, SwColumnPage, UpdateColMgrLineBox));
    m_xLineWidthEdit->connect_value_changed(aLk2);
    m_xLineColorDLB->SetSelectHdl(LINK( this, SwColumnPage, UpdateColMgrColorBox));
    m_xLineHeightEdit->connect_value_changed(aLk2);
    m_xLinePosDLB->connect_changed(LINK(this, SwColumnPage, UpdateColMgrListBox));

    // Separator line
    m_xLineTypeDLB->SetSourceUnit( FieldUnit::TWIP );

    // Fill the line styles listbox
    m_xLineTypeDLB->InsertEntry(
        ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::SOLID),
        SvxBorderLineStyle::SOLID );
    m_xLineTypeDLB->InsertEntry(
        ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DOTTED),
        SvxBorderLineStyle::DOTTED );
    m_xLineTypeDLB->InsertEntry(
        ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DASHED),
        SvxBorderLineStyle::DASHED );

    sal_Int64 nLineWidth = m_xLineWidthEdit->get_value(FieldUnit::POINT);
    nLineWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
            nLineWidth,
            m_xLineWidthEdit->get_digits(),
            FieldUnit::POINT, MapUnit::MapTwip ));
    m_xLineTypeDLB->SetWidth(nLineWidth);
    m_xLineColorDLB->SelectEntry(COL_BLACK);
}

SwColumnPage::~SwColumnPage()
{
    m_xFrameExampleWN.reset();
    m_xPgeExampleWN.reset();
    m_xDefaultVS.reset();
    m_xDistEd2.reset();
    m_xDistEd1.reset();
    m_xEd3.reset();
    m_xEd2.reset();
    m_xEd1.reset();
    m_xLineTypeDLB.reset();
    m_xLineColorDLB.reset();
    m_xTextDirectionLB.reset();
}

void SwColumnPage::SetPageWidth(tools::Long nPageWidth)
{
    tools::Long nNewMaxWidth = static_cast< tools::Long >(m_xEd1->NormalizePercent(nPageWidth));

    m_xDistEd1->set_max(nNewMaxWidth, FieldUnit::TWIP);
    m_xDistEd2->set_max(nNewMaxWidth, FieldUnit::TWIP);
    m_xEd1->set_max(nNewMaxWidth, FieldUnit::TWIP);
    m_xEd2->set_max(nNewMaxWidth, FieldUnit::TWIP);
    m_xEd3->set_max(nNewMaxWidth, FieldUnit::TWIP);
}

void SwColumnPage::connectPercentField(SwPercentField &rWrap)
{
    weld::MetricSpinButton *pField = rWrap.get();
    assert(pField);
    m_aPercentFieldsMap[pField] = &rWrap;
}

void SwColumnPage::Reset(const SfxItemSet *rSet)
{
    const sal_uInt16 nHtmlMode =
        ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
    if(nHtmlMode & HTMLMODE_ON)
    {
        m_bHtmlMode = true;
        m_xAutoWidthBox->set_sensitive(false);
    }
    FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
    m_xEd1->SetMetric(aMetric);
    m_xEd2->SetMetric(aMetric);
    m_xEd3->SetMetric(aMetric);
    m_xDistEd1->SetMetric(aMetric);
    m_xDistEd2->SetMetric(aMetric);
    //default spacing between cols = 0.5cm
    m_xDistEd1->set_value(50, FieldUnit::CM);
    m_xDistEd2->set_value(50, FieldUnit::CM);

    m_xColMgr.reset(new SwColMgr(*rSet));
    m_nCols = m_xColMgr->GetCount() ;
    m_xCLNrEdt->set_max(std::max(o3tl::narrowing<sal_uInt16>(m_xCLNrEdt->get_max()), m_nCols));

    if(m_bFrame)
    {
        if(m_bFormat)                     // there is no size here
            m_xColMgr->SetActualWidth(FRAME_FORMAT_WIDTH);
        else
        {
            const SwFormatFrameSize& rSize = rSet->Get(RES_FRM_SIZE);
            const SvxBoxItem& rBox = rSet->Get(RES_BOX);
            m_xColMgr->SetActualWidth(o3tl::narrowing<sal_uInt16>(rSize.GetSize().Width()) - rBox.GetSmallestDistance());
        }
    }
    if (m_xBalanceColsCB->get_visible())
    {
        ifconst SwFormatNoBalancedColumns* pItem = rSet->GetItemIfSet( RES_COLUMNBALANCE, false ) )
            m_xBalanceColsCB->set_active(!pItem->GetValue());
        else
            m_xBalanceColsCB->set_active(true);
    }

    //text direction
    if( SfxItemState::DEFAULT <= rSet->GetItemState( RES_FRAMEDIR ) )
    {
        const SvxFrameDirectionItem& rItem = rSet->Get(RES_FRAMEDIR);
        SvxFrameDirection nVal  = rItem.GetValue();
        m_xTextDirectionLB->set_active_id(nVal);
        m_xTextDirectionLB->save_value();
    }

    Init();
    ActivatePage( *rSet );
}

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

// stuff attributes into the Set when OK
bool SwColumnPage::FillItemSet(SfxItemSet *rSet)
{
    // set in ItemSet;
    // the current settings are already present

    const SfxPoolItem* pOldItem;
    const SwFormatCol& rCol = m_xColMgr->GetColumns();
    if(nullptr == (pOldItem = GetOldItem( *rSet, RES_COL )) ||
                rCol != *pOldItem )
        rSet->Put(rCol);

    if (m_xBalanceColsCB->get_visible())
    {
        rSet->Put(SwFormatNoBalancedColumns(!m_xBalanceColsCB->get_active()));
    }
    if (m_xTextDirectionLB->get_visible())
    {
        if (m_xTextDirectionLB->get_value_changed_from_saved())
        {
            rSet->Put(SvxFrameDirectionItem(m_xTextDirectionLB->get_active_id(), RES_FRAMEDIR) );
        }
    }
    return true;
}

// update ColumnManager
IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrListBox, weld::ComboBox&, void )
{
    UpdateColMgr(*m_xLineWidthEdit);
}

IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrLineBox, SvtLineListBox&, void )
{
    UpdateColMgr(*m_xLineWidthEdit);
}

IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrColorBox, ColorListBox&, void )
{
    UpdateColMgr(*m_xLineWidthEdit);
}

IMPL_LINK_NOARG( SwColumnPage, UpdateColMgr, weld::MetricSpinButton&, void )
{
    if (!m_xColMgr)
        return;
    tools::Long nGutterWidth = m_xColMgr->GetGutterWidth();
    if (m_nCols > 1)
    {
            // Determine whether the most narrow column is too narrow
            // for the adjusted column gap
        tools::Long nMin = m_nColWidth[0];

        for( sal_uInt16 i = 1; i < m_nCols; ++i )
            nMin = std::min(nMin, m_nColWidth[i]);

        bool bAutoWidth = m_xAutoWidthBox->get_active();
        if(!bAutoWidth)
        {
            m_xColMgr->SetAutoWidth(false);
                // when the user didn't allocate the whole width,
                // add the missing amount to the last column.
            tools::Long nSum = 0;
            for(sal_uInt16 i = 0; i < m_nCols; ++i)
                nSum += m_nColWidth[i];
            nGutterWidth = 0;
            for(sal_uInt16 i = 0; i < m_nCols - 1; ++i)
                nGutterWidth += m_nColDist[i];
            nSum += nGutterWidth;

            tools::Long nMaxW = m_xColMgr->GetActualSize();

            if( nSum < nMaxW  )
                m_nColWidth[m_nCols - 1] += nMaxW - nSum;

            m_xColMgr->SetColWidth( 0, static_cast< sal_uInt16 >(m_nColWidth[0] + m_nColDist[0]/2) );
            for( sal_uInt16 i = 1; i < m_nCols-1; ++i )
            {
                tools::Long nActDist = (m_nColDist[i] + m_nColDist[i - 1]) / 2;
                m_xColMgr->SetColWidth( i, static_cast< sal_uInt16 >(m_nColWidth[i] + nActDist ));
            }
            m_xColMgr->SetColWidth( m_nCols-1, static_cast< sal_uInt16 >(m_nColWidth[m_nCols-1] + m_nColDist[m_nCols -2]/2) );

        }

        bool bEnable = isLineNotNone();
        m_xLineHeightEdit->set_sensitive(bEnable);
        m_xLineHeightLbl->set_sensitive(bEnable);
        m_xLineWidthLbl->set_sensitive(bEnable);
        m_xLineWidthEdit->set_sensitive(bEnable);
        m_xLineColorDLB->set_sensitive(bEnable);
        m_xLineColorLbl->set_sensitive(bEnable);

        sal_Int64 nLineWidth = m_xLineWidthEdit->get_value(FieldUnit::PERCENT);
        nLineWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
                nLineWidth,
                m_xLineWidthEdit->get_digits(),
                m_xLineWidthEdit->get_unit(), MapUnit::MapTwip ));
        if( !bEnable )
            m_xColMgr->SetNoLine();
        else
        {
            m_xColMgr->SetLineWidthAndColor(
                    m_xLineTypeDLB->GetSelectEntryStyle(),
                    nLineWidth,
                    m_xLineColorDLB->GetSelectEntryColor() );
            m_xColMgr->SetAdjust(SwColLineAdj(m_xLinePosDLB->get_active() + 1));
            m_xColMgr->SetLineHeightPercent(static_cast<short>(m_xLineHeightEdit->get_value(FieldUnit::PERCENT)));
            bEnable = m_xColMgr->GetLineHeightPercent() != 100;
        }
        m_xLinePosLbl->set_sensitive(bEnable);
        m_xLinePosDLB->set_sensitive(bEnable);

        //fdo#66815 if the values are going to be the same, don't update
        //them to avoid the listbox selection resetting
        if (nLineWidth != m_xLineTypeDLB->GetWidth())
            m_xLineTypeDLB->SetWidth(nLineWidth);
        const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
        m_xLineTypeDLB->SetColor(rStyleSettings.GetDialogTextColor());
    }
    else
    {
        m_xColMgr->NoCols();
        m_nCols = 0;
    }

    //set maximum values
    m_xCLNrEdt->set_max(std::max(tools::Long(1),
        std::min(tools::Long(nMaxCols), tools::Long(m_xColMgr->GetActualSize() / (nGutterWidth + MINLAY)) )));

    //prompt example window
    if(!m_bLockUpdate)
    {
        if(m_bFrame)
        {
            m_aFrameExampleWN.SetColumns(m_xColMgr->GetColumns());
            m_aFrameExampleWN.SetLineColor(m_xColMgr->GetLineColor());
            m_aFrameExampleWN.Invalidate();
        }
        else
            m_aPgeExampleWN.Invalidate();
    }
}

void SwColumnPage::Init()
{
    m_xCLNrEdt->set_value(m_nCols);

    bool bAutoWidth = m_xColMgr->IsAutoWidth() || m_bHtmlMode;
    m_xAutoWidthBox->set_active(bAutoWidth);

    sal_Int32 nColumnWidthSum = 0;
    // set the widths
    for(sal_uInt16 i = 0; i < m_nCols; ++i)
    {
        m_nColWidth[i] = m_xColMgr->GetColWidth(i);
        nColumnWidthSum += m_nColWidth[i];
        if(i < m_nCols - 1)
            m_nColDist[i] = m_xColMgr->GetGutterWidth(i);
    }

    if( 1 < m_nCols )
    {
        // #97495# make sure that the automatic column width's are always equal
        if(bAutoWidth)
        {
            nColumnWidthSum /= m_nCols;
            for(sal_uInt16 i = 0; i < m_nCols; ++i)
                m_nColWidth[i] = nColumnWidthSum;
        }
        SwColLineAdj eAdj = m_xColMgr->GetAdjust();
        if( COLADJ_NONE == eAdj )       // the dialog doesn't know a NONE!
        {
            eAdj = COLADJ_TOP;
            //without Adjust no line type
            m_xLineTypeDLB->SelectEntry(SvxBorderLineStyle::NONE);
            m_xLineHeightEdit->set_value(100, FieldUnit::PERCENT);
        }
        else
        {
            // Need to multiply by 100 because of the 2 decimals
            m_xLineWidthEdit->set_value( m_xColMgr->GetLineWidth() * 100, FieldUnit::TWIP);
            m_xLineColorDLB->SelectEntry( m_xColMgr->GetLineColor() );
            m_xLineTypeDLB->SelectEntry( m_xColMgr->GetLineStyle() );
            m_xLineTypeDLB->SetWidth( m_xColMgr->GetLineWidth( ) );
            m_xLineHeightEdit->set_value(m_xColMgr->GetLineHeightPercent(), FieldUnit::PERCENT);

        }
        m_xLinePosDLB->set_active( static_cast< sal_Int32 >(eAdj - 1) );
    }
    else
    {
        m_xLinePosDLB->set_active(0);
        m_xLineTypeDLB->SelectEntry(SvxBorderLineStyle::NONE);
        m_xLineHeightEdit->set_value(100, FieldUnit::PERCENT);
    }

    UpdateCols();
    Update(nullptr);

        // set maximum number of columns
        // values below 1 are not allowed
    m_xCLNrEdt->set_max(std::max(tools::Long(1),
        std::min(tools::Long(nMaxCols), tools::Long(m_xColMgr->GetActualSize() / g_nMinWidth) )));
}

bool SwColumnPage::isLineNotNone() const
{
    // nothing is turned off
    return m_xLineTypeDLB->GetSelectEntryStyle() != SvxBorderLineStyle::NONE;
}

/*
 * The number of columns has changed -- here the controls for editing of the
 * columns are en- or disabled according to the column number. In case there are
 * more than nVisCols (=3) all Edit are being enabled and the buttons for
 * scrolling too. Otherwise Edits are being enabled according to the column
 * numbers; one column can not be edited.
 */

void SwColumnPage::UpdateCols()
{
    bool bEnableBtns= false;
    bool bEnable12  = false;
    bool bEnable3   = false;
    const bool bEdit = !m_xAutoWidthBox->get_active();
    if ( m_nCols > nVisCols )
    {
        bEnableBtns = !m_bHtmlMode;
        bEnable12 = bEnable3 = bEdit;
    }
    else if( bEdit )
    {
        // here are purposely hardly any breaks
        switch(m_nCols)
        {
            case 3: bEnable3 = true;
                [[fallthrough]];
            case 2: bEnable12= truebreak;
            default/* do nothing */;
        }
    }
    m_xEd1->set_sensitive(bEnable12);
    bool bEnable = m_nCols > 1;
    m_xDistEd1->set_sensitive(bEnable);
    m_xAutoWidthBox->set_sensitive(bEnable && !m_bHtmlMode);
    m_xEd2->set_sensitive(bEnable12);
    m_xDistEd2->set_sensitive(bEnable3);
    m_xEd3->set_sensitive(bEnable3);
    m_xLbl1->set_sensitive(bEnable12);
    m_xLbl2->set_sensitive(bEnable12);
    m_xLbl3->set_sensitive(bEnable3);
    m_xBtnBack->set_sensitive(bEnableBtns);
    m_xBtnNext->set_sensitive(bEnableBtns);

    m_xLineTypeDLB->set_sensitive( bEnable );
    m_xLineTypeLbl->set_sensitive( bEnable );

    if (bEnable)
    {
        bEnable = isLineNotNone();
    }

    //all these depend on > 1 column and line style != none
    m_xLineHeightEdit->set_sensitive(bEnable);
    m_xLineHeightLbl->set_sensitive(bEnable);
    m_xLineWidthLbl->set_sensitive(bEnable);
    m_xLineWidthEdit->set_sensitive(bEnable);
    m_xLineColorDLB->set_sensitive(bEnable);
    m_xLineColorLbl->set_sensitive(bEnable);

    if (bEnable)
        bEnable = m_xColMgr->GetLineHeightPercent() != 100;

    //and these additionally depend on line height != 100%
    m_xLinePosDLB->set_sensitive(bEnable);
    m_xLinePosLbl->set_sensitive(bEnable);
}

void SwColumnPage::SetLabels( sal_uInt16 nVis )
{
    //insert ~ before the last character, e.g. 1 -> ~1, 10 -> 1~0
    const OUString sLbl( '~' );

    const OUString sLbl1(OUString::number( nVis + 1 ));
    m_xLbl1->set_label(sLbl1.replaceAt(sLbl1.getLength()-1, 0, sLbl));

    const OUString sLbl2(OUString::number( nVis + 2 ));
    m_xLbl2->set_label(sLbl2.replaceAt(sLbl2.getLength()-1, 0, sLbl));

    const OUString sLbl3(OUString::number( nVis + 3 ));
    m_xLbl3->set_label(sLbl3.replaceAt(sLbl3.getLength()-1, 0, sLbl));

    const OUString sColumnWidth = SwResId( STR_ACCESS_COLUMN_WIDTH ) ;
    m_xEd1->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl1));
    m_xEd2->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl2));
    m_xEd3->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl3));

    const OUString sDist = SwResId( STR_ACCESS_PAGESETUP_SPACING ) ;
    m_xDistEd1->set_accessible_name(
        sDist.replaceFirst("%1", sLbl1).replaceFirst("%2", sLbl2));

    m_xDistEd2->set_accessible_name(
        sDist.replaceFirst("%1", sLbl2).replaceFirst("%2", sLbl3));
}

/*
 * Handler that is called at alteration of the column number. An alteration of
 * the column number overwrites potential user's width settings; all columns
 * are equally wide.
 */

IMPL_LINK_NOARG(SwColumnPage, ColModify, weld::SpinButton&, void)
{
    ColModify(/*bForceColReset=*/false);
}

void SwColumnPage::ColModify(bool bForceColReset)
{
    m_nCols = o3tl::narrowing<sal_uInt16>(m_xCLNrEdt->get_value());
    //#107890# the handler is also called from LoseFocus()
    //then no change has been made and thus no action should be taken
    // #i17816# changing the displayed types within the ValueSet
    //from two columns to two columns with different settings doesn't invalidate the
    // example windows in ::ColModify()
    if (!bForceColReset && m_xColMgr->GetCount() == m_nCols)
        return;

    if (!bForceColReset)
        m_aDefaultVS.SetNoSelection();
    tools::Long nDist = static_cast< tools::Long >(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
    m_xColMgr->SetCount(m_nCols, o3tl::narrowing<sal_uInt16>(nDist));
    for(sal_uInt16 i = 0; i < m_nCols; i++)
        m_nColDist[i] = nDist;
    m_nFirstVis = 0;
    SetLabels( m_nFirstVis );
    UpdateCols();
    ResetColWidth();
    Update(nullptr);
}

/*
 * Modify handler for an alteration of the column width or the column gap.
 * These changes take effect time-displaced. With an alteration of the column
 * width the automatic calculation of the column width is overruled; only an
 * alteration of the column number leads back to that default.
 */

IMPL_LINK(SwColumnPage, GapModify, weld::MetricSpinButton&, rMetricField, void)
{
    if (m_nCols < 2)
        return;
    SwPercentField *pField = m_aPercentFieldsMap[&rMetricField];
    assert(pField);
    tools::Long nActValue = static_cast< tools::Long >(pField->DenormalizePercent(pField->get_value(FieldUnit::TWIP)));
    if (m_xAutoWidthBox->get_active())
    {
        const tools::Long nMaxGap = static_cast< tools::Long >
            ((m_xColMgr->GetActualSize() - m_nCols * MINLAY)/(m_nCols - 1));
        if(nActValue > nMaxGap)
        {
            nActValue = nMaxGap;
            m_xDistEd1->set_value(m_xDistEd1->NormalizePercent(nMaxGap), FieldUnit::TWIP);
        }
        m_xColMgr->SetGutterWidth(o3tl::narrowing<sal_uInt16>(nActValue));
        for(sal_uInt16 i = 0; i < m_nCols; i++)
            m_nColDist[i] = nActValue;

        ResetColWidth();
        UpdateCols();
    }
    else
    {
        const sal_uInt16 nVis = m_nFirstVis + ((pField == m_xDistEd2.get()) ? 1 : 0);
        tools::Long nDiff = nActValue - m_nColDist[nVis];
        if(nDiff)
        {
            tools::Long nLeft = m_nColWidth[nVis];
            tools::Long nRight = m_nColWidth[nVis + 1];
            if(nLeft + nRight + 2 * MINLAY < nDiff)
                nDiff = nLeft + nRight - 2 * MINLAY;
            if(nDiff < nRight - MINLAY)
            {
                nRight -= nDiff;
            }
            else
            {
                tools::Long nTemp = nDiff - nRight + MINLAY;
                nRight = MINLAY;
                if(nLeft > nTemp - MINLAY)
                {
                    nLeft -= nTemp;
                    nTemp = 0;
                }
                else
                {
                    nTemp -= nLeft + MINLAY;
                    nLeft = MINLAY;
                }
                nDiff = nTemp;
            }
            m_nColWidth[nVis] = nLeft;
            m_nColWidth[nVis + 1] = nRight;
            m_nColDist[nVis] += nDiff;

            m_xColMgr->SetColWidth( nVis, sal_uInt16(nLeft) );
            m_xColMgr->SetColWidth( nVis + 1, sal_uInt16(nRight) );
            m_xColMgr->SetGutterWidth( sal_uInt16(m_nColDist[nVis]), nVis );
        }

    }
    Update(&rMetricField);
}

IMPL_LINK(SwColumnPage, EdModify, weld::MetricSpinButton&, rEdit, void)
{
    SwPercentField *pField = m_aPercentFieldsMap[&rEdit];
    assert(pField);
    m_pModifiedField = pField;
    Timeout();
}

// Handler behind the Checkbox for automatic width. When the box is checked
// no explicit values for the column width can be entered.
IMPL_LINK(SwColumnPage, AutoWidthHdl, weld::Toggleable&, rBox, void)
{
    tools::Long nDist = static_cast< tools::Long >(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
    m_xColMgr->SetCount(m_nCols, o3tl::narrowing<sal_uInt16>(nDist));
    for(sal_uInt16 i = 0; i < m_nCols; i++)
        m_nColDist[i] = nDist;
    if (rBox.get_active())
    {
        m_xColMgr->SetGutterWidth(sal_uInt16(nDist));
        ResetColWidth();
    }
    m_xColMgr->SetAutoWidth(rBox.get_active(), sal_uInt16(nDist));
    UpdateCols();
    Update(nullptr);
}

// scroll up the contents of the edits
IMPL_LINK_NOARG(SwColumnPage, Up, weld::Button&, void)
{
    if( m_nFirstVis )
    {
        --m_nFirstVis;
        SetLabels( m_nFirstVis );
        Update(nullptr);
    }
}

// scroll down the contents of the edits.
IMPL_LINK_NOARG(SwColumnPage, Down, weld::Button&, void)
{
    if( m_nFirstVis + nVisCols < m_nCols )
    {
        ++m_nFirstVis;
        SetLabels( m_nFirstVis );
        Update(nullptr);
    }
}

// relict from ancient times - now directly without time handler; triggered by
// an alteration of the column width or the column gap.
void SwColumnPage::Timeout()
{
    SwPercentField *pField = m_pModifiedField;
    if (m_pModifiedField)
    {
            // find the changed column
        sal_uInt16 nChanged = m_nFirstVis;
        if (m_pModifiedField == m_xEd2.get())
            ++nChanged;
        else if (m_pModifiedField == m_xEd3.get())
            nChanged += 2;

        tools::Long nNewWidth = static_cast< tools::Long >
            (m_pModifiedField->DenormalizePercent(m_pModifiedField->get_value(FieldUnit::TWIP)));
        tools::Long nDiff = nNewWidth - m_nColWidth[nChanged];

        // when it's the last column
        if(nChanged == m_nCols - 1)
        {
            m_nColWidth[0] -= nDiff;
            if(m_nColWidth[0] < static_cast<tools::Long>(g_nMinWidth))
            {
                nNewWidth -= g_nMinWidth - m_nColWidth[0];
                m_nColWidth[0] = g_nMinWidth;
            }

        }
        else if(nDiff)
        {
            m_nColWidth[nChanged + 1] -= nDiff;
            if(m_nColWidth[nChanged + 1] < static_cast<tools::Long>(g_nMinWidth))
            {
                nNewWidth -= g_nMinWidth - m_nColWidth[nChanged + 1];
                m_nColWidth[nChanged + 1] = g_nMinWidth;
            }
        }
        m_nColWidth[nChanged] = nNewWidth;
        m_pModifiedField = nullptr;
    }

    Update(pField ? pField->get() : nullptr);
}

// Update the view
void SwColumnPage::Update(const weld::MetricSpinButton* pInteractiveField)
{
    m_xBalanceColsCB->set_sensitive(m_nCols > 1);
    if(m_nCols >= 2)
    {
        sal_Int64 nCurrentValue, nNewValue;

        nCurrentValue = m_xEd1->NormalizePercent(m_xEd1->DenormalizePercent(m_xEd1->get_value(FieldUnit::TWIP)));
        nNewValue = m_xEd1->NormalizePercent(m_nColWidth[m_nFirstVis]);

        //fdo#87612 if we're interacting with this widget and the value will be the same
        //then leave it alone (i.e. don't change equivalent values of e.g. .8 -> 0.8)
        if (nNewValue != nCurrentValue || pInteractiveField != m_xEd1->get())
            m_xEd1->set_value(nNewValue, FieldUnit::TWIP);

        nCurrentValue = m_xDistEd1->NormalizePercent(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
        nNewValue = m_xDistEd1->NormalizePercent(m_nColDist[m_nFirstVis]);
        if (nNewValue != nCurrentValue || pInteractiveField != m_xDistEd1->get())
            m_xDistEd1->set_value(nNewValue, FieldUnit::TWIP);

        nCurrentValue = m_xEd2->NormalizePercent(m_xEd2->DenormalizePercent(m_xEd2->get_value(FieldUnit::TWIP)));
        nNewValue = m_xEd2->NormalizePercent(m_nColWidth[m_nFirstVis+1]);
        if (nNewValue != nCurrentValue || pInteractiveField != m_xEd2->get())
            m_xEd2->set_value(nNewValue, FieldUnit::TWIP);

        if(m_nCols >= 3)
        {
            nCurrentValue = m_xDistEd2->NormalizePercent(m_xDistEd2->DenormalizePercent(m_xDistEd2->get_value(FieldUnit::TWIP)));
            nNewValue = m_xDistEd2->NormalizePercent(m_nColDist[m_nFirstVis+1]);
            if (nNewValue != nCurrentValue || pInteractiveField != m_xDistEd2->get())
                m_xDistEd2->set_value(nNewValue, FieldUnit::TWIP);

            nCurrentValue = m_xEd3->NormalizePercent(m_xEd3->DenormalizePercent(m_xEd3->get_value(FieldUnit::TWIP)));
            nNewValue = m_xEd3->NormalizePercent(m_nColWidth[m_nFirstVis+2]);
            if (nNewValue != nCurrentValue || pInteractiveField != m_xEd3->get())
                m_xEd3->set_value(nNewValue, FieldUnit::TWIP);
        }
        else
        {
            m_xEd3->set_text(OUString());
            m_xDistEd2->set_text(OUString());
        }
    }
    else
    {
        m_xEd1->set_text(OUString());
        m_xEd2->set_text(OUString());
        m_xEd3->set_text(OUString());
        m_xDistEd1->set_text(OUString());
        m_xDistEd2->set_text(OUString());
    }
    UpdateColMgr(*m_xLineWidthEdit);
}

// Update Bsp
void SwColumnPage::ActivatePage(const SfxItemSet& rSet)
{
    bool bVertical = false;
    if (SfxItemState::DEFAULT <= rSet.GetItemState(RES_FRAMEDIR))
    {
        const SvxFrameDirectionItem& rDirItem =
                    rSet.Get(RES_FRAMEDIR);
        bVertical = rDirItem.GetValue() == SvxFrameDirection::Vertical_RL_TB||
                    rDirItem.GetValue() == SvxFrameDirection::Vertical_LR_TB;
    }

    if (!m_bFrame)
    {
        if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_PAGE_SIZE ))
        {
            const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);

            sal_uInt16 nActWidth;

            if (!bVertical)
            {
                const SvxLRSpaceItem& rLRSpace = rSet.Get(RES_LR_SPACE);
                const SvxBoxItem& rBox = rSet.Get(RES_BOX);
                nActWidth = rSize.GetSize().Width() - rLRSpace.ResolveLeft({})
                            - rLRSpace.ResolveRight({}) - rBox.GetSmallestDistance();
            }
            else
            {
                const SvxULSpaceItem& rULSpace = rSet.Get( RES_UL_SPACE );
                const SvxBoxItem& rBox = rSet.Get(RES_BOX);
                nActWidth = rSize.GetSize().Height()
                                - rULSpace.GetUpper() - rULSpace.GetLower() - rBox.GetSmallestDistance();

            }

            if( m_xColMgr->GetActualSize() != nActWidth)
            {
                m_xColMgr->SetActualWidth(nActWidth);
                ColModify(/*bForceColReset=*/false);
                UpdateColMgr( *m_xLineWidthEdit );
            }
        }
        m_xFrameExampleWN->hide();
        m_aPgeExampleWN.UpdateExample(rSet, m_xColMgr.get());
        m_xPgeExampleWN->show();

    }
    else
    {
        m_xPgeExampleWN->hide();
        m_xFrameExampleWN->show();

        // Size
        const SwFormatFrameSize& rSize = rSet.Get(RES_FRM_SIZE);
        const SvxBoxItem& rBox = rSet.Get(RES_BOX);

        sal_uInt16 nTotalWish;
        if (m_bFormat)
            nTotalWish = FRAME_FORMAT_WIDTH;
        else
        {
            tools::Long const nDistance = rBox.GetSmallestDistance();
            nTotalWish = (!bVertical ? rSize.GetWidth() : rSize.GetHeight()) - 2 * nDistance;
        }

        // set maximum values of column width
        SetPageWidth(nTotalWish);

        if(m_xColMgr->GetActualSize() != nTotalWish)
        {
            m_xColMgr->SetActualWidth(nTotalWish);
            Init();
        }
        bool bPercent;
        // only relative data in frame format
        if ( m_bFormat || (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED) )
        {
            // set value for 100%
            m_xEd1->SetRefValue(nTotalWish);
            m_xEd2->SetRefValue(nTotalWish);
            m_xEd3->SetRefValue(nTotalWish);
            m_xDistEd1->SetRefValue(nTotalWish);
            m_xDistEd2->SetRefValue(nTotalWish);

            // switch to %-view
            bPercent = true;
        }
        else
            bPercent = false;

        m_xEd1->ShowPercent(bPercent);
        m_xEd2->ShowPercent(bPercent);
        m_xEd3->ShowPercent(bPercent);
        m_xDistEd1->ShowPercent(bPercent);
        m_xDistEd2->ShowPercent(bPercent);
        m_xDistEd1->SetMetricFieldMin(0);
        m_xDistEd2->SetMetricFieldMin(0);
    }
    Update(nullptr);
}

DeactivateRC SwColumnPage::DeactivatePage(SfxItemSet *_pSet)
{
    if(_pSet)
        FillItemSet(_pSet);

    return DeactivateRC::LeavePage;
}

IMPL_LINK(SwColumnPage, SetDefaultsHdl, ValueSet *, pVS, void)
{
    const sal_uInt16 nItem = pVS->GetSelectedItemId();
    if( nItem < 4 )
    {
        m_xCLNrEdt->set_value(nItem);
        m_xAutoWidthBox->set_active(true);
        m_xDistEd1->set_value(50, FieldUnit::CM);
        ColModify(/*bForceColReset=*/true);
    }
    else
    {
        m_bLockUpdate = true;
        m_xCLNrEdt->set_value(2);
        m_xAutoWidthBox->set_active(false);
        m_xDistEd1->set_value(50, FieldUnit::CM);
        ColModify(/*bForceColReset=*/true);
        // now set the width ratio to 2 : 1 or 1 : 2 respectively
        const tools::Long nSmall = static_cast< tools::Long >(m_xColMgr->GetActualSize() / 3);
        if(nItem == 4)
        {
            m_xEd2->set_value(m_xEd2->NormalizePercent(nSmall), FieldUnit::TWIP);
            m_pModifiedField = m_xEd2.get();
        }
        else
        {
            m_xEd1->set_value(m_xEd1->NormalizePercent(nSmall), FieldUnit::TWIP);
            m_pModifiedField = m_xEd1.get();
        }
        m_bLockUpdate = false;
        Timeout();

    }
}

void SwColumnPage::SetFrameMode(bool bMod)
{
    m_bFrame = bMod;
}

void SwColumnPage::SetInSection(bool bSet)
{
    if(!SvtCTLOptions::IsCTLFontEnabled())
        return;

    m_xTextDirectionFT->set_visible(bSet);
    m_xTextDirectionLB->set_visible(bSet);
}

void ColumnValueSet::UserDraw(const UserDrawEvent& rUDEvt)
{
    vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

    tools::Rectangle aRect = rUDEvt.GetRect();
    const sal_uInt16 nItemId = rUDEvt.GetItemId();
    tools::Long nRectWidth = aRect.GetWidth();
    tools::Long nRectHeight = aRect.GetHeight();

    Point aBLPos = aRect.TopLeft();
    pDev->Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR);
    pDev->SetFillColor(rStyleSettings.GetFieldColor());
    pDev->SetLineColor(rStyleSettings.GetFieldTextColor());

    tools::Long nStep = std::abs(std::abs(nRectHeight * 95 /100) / 11);
    tools::Long nTop = (nRectHeight - 11 * nStep ) / 2;
    sal_uInt16 nCols = 0;
    tools::Long nStarts[3];
    tools::Long nEnds[3];
    nStarts[0] = nRectWidth * 10 / 100;
    switch( nItemId )
    {
        case 1:
            nEnds[0] = nRectWidth * 9 / 10;
            nCols = 1;
        break;
        case 2: nCols = 2;
            nEnds[0] = nRectWidth * 45 / 100;
            nStarts[1] = nEnds[0] + nStep;
            nEnds[1] = nRectWidth * 9 / 10;
        break;
        case 3: nCols = 3;
            nEnds[0]    = nRectWidth * 30 / 100;
            nStarts[1]  = nEnds[0] + nStep;
            nEnds[1]    = nRectWidth * 63 / 100;
            nStarts[2]  = nEnds[1] + nStep;
            nEnds[2]    = nRectWidth * 9 / 10;
        break;
        case 4: nCols = 2;
            nEnds[0] = nRectWidth * 63 / 100;
            nStarts[1] = nEnds[0] + nStep;
            nEnds[1] = nRectWidth * 9 / 10;
        break;
        case 5: nCols = 2;
            nEnds[0] = nRectWidth * 30 / 100;
            nStarts[1] = nEnds[0] + nStep;
            nEnds[1] = nRectWidth * 9 / 10;
        break;
    }
    for(sal_uInt16 j = 0; j < nCols; j++ )
    {
        Point aStart(aBLPos.X() + nStarts[j], 0);
        Point aEnd(aBLPos.X() + nEnds[j], 0);
        for( sal_uInt16 i = 0; i < 12; i ++)
        {
            aStart.setY( aBLPos.Y() + nTop + i * nStep);
            aEnd.setY( aStart.Y() );
            pDev->DrawLine(aStart, aEnd);
        }
    }
    pDev->Pop();
}

void ColumnValueSet::StyleUpdated()
{
    SetFormat();
    Invalidate();
    ValueSet::StyleUpdated();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=96 H=94 G=94

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© 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.