Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/docvw/contentcontrolaliasbutton.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
#include <contentcontrolaliasbutton.hxx>
11
12
#include <basegfx/matrix/b2dhommatrixtools.hxx>
13
#include <basegfx/vector/b2dvector.hxx>
14
#include <drawinglayer/attribute/fontattribute.hxx>
15
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
16
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
17
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
18
#include <drawinglayer/processor2d/processor2dtools.hxx>
19
#include <vcl/metric.hxx>
20
#include <vcl/weld/Builder.hxx>
21
22
#include <HeaderFooterWin.hxx>
23
#include <edtwin.hxx>
24
#include <formatcontentcontrol.hxx>
25
#include <swabstdlg.hxx>
26
#include <view.hxx>
27
#include <viewopt.hxx>
28
#include <wrtsh.hxx>
29
30
constexpr tools::Long TEXT_PADDING = 3;
31
constexpr tools::Long BOX_DISTANCE = 3;
32
constexpr tools::Long BUTTON_WIDTH = 12;
33
34
SwContentControlAliasButton::SwContentControlAliasButton(SwEditWin* pEditWin,
35
                                                         const SwContentControl* pContentControl)
36
0
    : SwFrameMenuButtonBase(pEditWin, nullptr,
37
0
                            u"modules/swriter/ui/contentcontrolaliasbutton.ui"_ustr,
38
0
                            u"ContentControlAliasButton"_ustr)
39
0
    , m_xPushButton(m_xBuilder->weld_button(u"button"_ustr))
40
0
    , m_sLabel(pContentControl->GetAlias())
41
0
{
42
0
    m_xPushButton->set_accessible_name(m_sLabel);
43
0
    m_xPushButton->connect_clicked(LINK(this, SwContentControlAliasButton, ClickHdl));
44
0
    m_xVirDev = m_xPushButton->create_virtual_device();
45
0
    SetVirDevFont();
46
0
}
Unexecuted instantiation: SwContentControlAliasButton::SwContentControlAliasButton(SwEditWin*, SwContentControl const*)
Unexecuted instantiation: SwContentControlAliasButton::SwContentControlAliasButton(SwEditWin*, SwContentControl const*)
47
48
0
SwContentControlAliasButton::~SwContentControlAliasButton() { disposeOnce(); }
49
50
void SwContentControlAliasButton::dispose()
51
0
{
52
0
    m_xPushButton.reset();
53
0
    m_xVirDev.disposeAndClear();
54
0
    SwFrameMenuButtonBase::dispose();
55
0
}
56
57
void SwContentControlAliasButton::SetOffset(Point aTopLeftPixel)
58
0
{
59
    // Compute the text size and get the box position & size from it.
60
0
    tools::Rectangle aTextRect;
61
0
    m_xVirDev->GetTextBoundRect(aTextRect, m_sLabel);
62
0
    tools::Rectangle aTextPxRect = m_xVirDev->LogicToPixel(aTextRect);
63
0
    FontMetric aFontMetric = m_xVirDev->GetFontMetric(m_xVirDev->GetFont());
64
0
    Size aBoxSize(aTextPxRect.GetWidth() + BUTTON_WIDTH + TEXT_PADDING * 2,
65
0
                  aFontMetric.GetLineHeight() + TEXT_PADDING * 2);
66
0
    Point aBoxPos(aTopLeftPixel.X() + BOX_DISTANCE, aTopLeftPixel.Y() - aBoxSize.Height());
67
68
    // Set the position & size of the window.
69
0
    SetPosSizePixel(aBoxPos, aBoxSize);
70
0
    m_xVirDev->SetOutputSizePixel(aBoxSize);
71
72
0
    PaintButton();
73
0
}
74
75
IMPL_LINK_NOARG(SwContentControlAliasButton, ClickHdl, weld::Button&, void)
76
0
{
77
0
    if (m_bReadOnly)
78
0
    {
79
0
        return;
80
0
    }
81
82
0
    SwView& rView = GetEditWin()->GetView();
83
0
    SwWrtShell& rWrtSh = rView.GetWrtShell();
84
0
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
85
0
    ScopedVclPtr<VclAbstractDialog> pDlg(
86
0
        pFact->CreateSwContentControlDlg(GetEditWin()->GetFrameWeld(), rWrtSh));
87
0
    VclAbstractDialog::AsyncContext aContext;
88
0
    aContext.maEndDialogFn = [](sal_Int32) {};
89
0
    pDlg->StartExecuteAsync(aContext);
90
0
}
91
92
void SwContentControlAliasButton::PaintButton()
93
0
{
94
0
    if (!m_xVirDev)
95
0
    {
96
0
        return;
97
0
    }
98
99
0
    m_xVirDev->SetMapMode(MapMode(MapUnit::MapPixel));
100
0
    drawinglayer::primitive2d::Primitive2DContainer aSeq;
101
0
    tools::Rectangle aRect(Point(0, 0), m_xVirDev->PixelToLogic(GetSizePixel()));
102
103
    // Create button
104
0
    SwFrameButtonPainter::PaintButton(aSeq, aRect, /*bOnTop=*/false);
105
106
    // Create the text primitive
107
0
    const SwViewOption* pVOpt = GetEditWin()->GetView().GetWrtShell().GetViewOptions();
108
0
    basegfx::BColor aLineColor = pVOpt->GetHeaderFooterMarkColor().getBColor();
109
0
    basegfx::B2DVector aFontSize;
110
0
    drawinglayer::attribute::FontAttribute aFontAttr
111
0
        = drawinglayer::primitive2d::getFontAttributeFromVclFont(aFontSize, m_xVirDev->GetFont(),
112
0
                                                                 false, false);
113
114
0
    FontMetric aFontMetric = m_xVirDev->GetFontMetric(m_xVirDev->GetFont());
115
0
    double nTextOffsetY = aFontMetric.GetAscent() + TEXT_PADDING;
116
0
    double nTextOffsetX = std::abs(aRect.GetWidth() - m_xVirDev->GetTextWidth(m_sLabel)) / 2.0;
117
0
    Point aTextPos(nTextOffsetX, nTextOffsetY);
118
119
0
    basegfx::B2DHomMatrix aTextMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(
120
0
        aFontSize.getX(), aFontSize.getY(), static_cast<double>(aTextPos.X()),
121
0
        static_cast<double>(aTextPos.Y()));
122
123
0
    aSeq.push_back(new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
124
0
        aTextMatrix, m_sLabel, 0, m_sLabel.getLength(), std::vector<double>(), {},
125
0
        std::move(aFontAttr), css::lang::Locale(), aLineColor));
126
127
    // Create the processor and process the primitives
128
0
    drawinglayer::geometry::ViewInformation2D aViewInfo;
129
0
    std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor
130
0
        = drawinglayer::processor2d::createProcessor2DFromOutputDevice(*m_xVirDev, aViewInfo);
131
132
0
    pProcessor->process(aSeq);
133
134
0
    m_xPushButton->set_custom_button(m_xVirDev.get());
135
0
}
136
137
0
void SwContentControlAliasButton::ShowAll(bool bShow) { Show(bShow); }
138
139
bool SwContentControlAliasButton::Contains(const Point& rDocPt) const
140
0
{
141
0
    tools::Rectangle aRect(GetPosPixel(), GetSizePixel());
142
0
    return aRect.Contains(rDocPt);
143
0
}
144
145
0
void SwContentControlAliasButton::SetReadonly(bool bReadonly) { m_bReadOnly = bReadonly; }
146
147
void SwContentControlAliasButton::SetContentControl(const SwContentControl* pContentControl)
148
0
{
149
0
    m_sLabel = pContentControl->GetAlias();
150
0
}
151
152
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */