Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/docvw/PageBreakWin.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
#include <bitmaps.hlst>
11
12
#include <cmdid.h>
13
#include <cntfrm.hxx>
14
#include <txtfrm.hxx>
15
#include <notxtfrm.hxx>
16
#include <ndtxt.hxx>
17
#include <DashedLine.hxx>
18
#include <doc.hxx>
19
#include <edtwin.hxx>
20
#include <fmtpdsc.hxx>
21
#include <IDocumentUndoRedo.hxx>
22
#include <IDocumentContentOperations.hxx>
23
#include <PageBreakWin.hxx>
24
#include <pagefrm.hxx>
25
#include <PostItMgr.hxx>
26
#include <FrameControlsManager.hxx>
27
#include <strings.hrc>
28
#include <tabfrm.hxx>
29
#include <uiitems.hxx>
30
#include <uiobject.hxx>
31
#include <view.hxx>
32
#include <viewopt.hxx>
33
#include <wrtsh.hxx>
34
35
#include <basegfx/color/bcolortools.hxx>
36
#include <basegfx/polygon/b2dpolygon.hxx>
37
#include <basegfx/polygon/b2dpolygontools.hxx>
38
#include <basegfx/range/b2drectangle.hxx>
39
#include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx>
40
#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
41
#include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
42
#include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
43
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
44
#include <drawinglayer/processor2d/processor2dtools.hxx>
45
#include <editeng/formatbreakitem.hxx>
46
#include <sfx2/dispatch.hxx>
47
#include <sfx2/viewfrm.hxx>
48
#include <svl/stritem.hxx>
49
#include <vcl/canvastools.hxx>
50
#include <vcl/event.hxx>
51
#include <vcl/svapp.hxx>
52
#include <vcl/settings.hxx>
53
#include <memory>
54
55
0
#define BUTTON_WIDTH 30
56
0
#define BUTTON_HEIGHT 19
57
0
#define ARROW_WIDTH 9
58
59
using namespace basegfx;
60
using namespace basegfx::utils;
61
62
SwBreakDashedLine::SwBreakDashedLine(SwEditWin* pEditWin, const SwFrame *pFrame)
63
0
    : SwDashedLine(pEditWin, &SwViewOption::GetPageBreakColor)
64
0
    , m_pEditWin(pEditWin)
65
0
    , m_pFrame(pFrame)
66
0
{
67
0
    set_id(u"PageBreak"_ustr); // for uitest
68
0
}
Unexecuted instantiation: SwBreakDashedLine::SwBreakDashedLine(SwEditWin*, SwFrame const*)
Unexecuted instantiation: SwBreakDashedLine::SwBreakDashedLine(SwEditWin*, SwFrame const*)
69
70
SwPageBreakWin& SwBreakDashedLine::GetOrCreateWin()
71
0
{
72
0
    if (!m_pWin)
73
0
    {
74
0
        m_pWin = VclPtr<SwPageBreakWin>::Create(this, m_pEditWin, m_pFrame);
75
0
        m_pWin->SetPosSizePixel(m_aBtnRect.TopLeft(), m_aBtnRect.GetSize());
76
0
        m_pWin->SetZOrder(this, ZOrderFlags::Before);
77
0
    }
78
0
    return *m_pWin;
79
0
}
80
81
void SwBreakDashedLine::DestroyWin()
82
0
{
83
0
    m_pWin.disposeAndClear();
84
0
}
85
86
void SwBreakDashedLine::MouseMove( const MouseEvent& rMEvt )
87
0
{
88
0
    if ( rMEvt.IsLeaveWindow() )
89
0
    {
90
        // don't fade if we just move to the 'button'
91
0
        Point aEventPos( GetPosPixel() + rMEvt.GetPosPixel() );
92
0
        if (m_pWin && (!Contains(aEventPos) || !m_pWin->IsVisible()))
93
0
            m_pWin->Fade(false);
94
0
    }
95
0
    else if (!m_pWin || !m_pWin->IsVisible())
96
0
    {
97
0
        GetOrCreateWin().Fade(true);
98
0
    }
99
100
0
    if (!rMEvt.IsSynthetic() && (!m_pWin || !m_pWin->IsVisible()))
101
0
    {
102
0
        UpdatePosition(rMEvt.GetPosPixel());
103
0
    }
104
0
}
105
106
void SwBreakDashedLine::ShowAll(bool bShow)
107
0
{
108
0
    Show(bShow);
109
0
}
110
111
void SwBreakDashedLine::SetReadonly(bool bReadonly)
112
0
{
113
0
    ShowAll(!bReadonly);
114
0
}
115
116
bool SwBreakDashedLine::Contains(const Point &rDocPt) const
117
0
{
118
0
    if (m_aBtnRect.Contains(rDocPt))
119
0
        return true;
120
121
0
    ::tools::Rectangle aLineRect(GetPosPixel(), GetSizePixel());
122
0
    return aLineRect.Contains(rDocPt);
123
0
}
124
125
SwPageBreakWin::SwPageBreakWin(SwBreakDashedLine* pLine, SwEditWin* pEditWin, const SwFrame *pFrame) :
126
0
    InterimItemWindow(pEditWin, u"modules/swriter/ui/pbmenubutton.ui"_ustr, u"PBMenuButton"_ustr),
127
0
    m_xMenuButton(m_xBuilder->weld_menu_button(u"menubutton"_ustr)),
128
0
    m_pLine(pLine),
129
0
    m_pEditWin(pEditWin),
130
0
    m_pFrame(pFrame),
131
0
    m_bIsAppearing( false ),
132
0
    m_nFadeRate( 100 ),
133
0
    m_nDelayAppearing( 0 ),
134
0
    m_aFadeTimer("SwPageBreakWin m_aFadeTimer"),
135
0
    m_bDestroyed( false )
136
0
{
137
0
    m_xMenuButton->connect_toggled(LINK(this, SwPageBreakWin, ToggleHdl));
138
0
    m_xMenuButton->connect_selected(LINK(this, SwPageBreakWin, SelectHdl));
139
0
    m_xMenuButton->set_accessible_name(SwResId(STR_PAGE_BREAK_BUTTON));
140
141
0
    m_xVirDev = m_xMenuButton->create_virtual_device();
142
0
    SwFrameMenuButtonBase::SetVirDevFont(*m_xVirDev);
143
144
    // Use pixels for the rest of the drawing
145
0
    m_xVirDev->SetMapMode( MapMode ( MapUnit::MapPixel ) );
146
147
0
    m_aFadeTimer.SetTimeout( 50 );
148
0
    m_aFadeTimer.SetInvokeHandler( LINK( this, SwPageBreakWin, FadeHandler ) );
149
0
}
Unexecuted instantiation: SwPageBreakWin::SwPageBreakWin(SwBreakDashedLine*, SwEditWin*, SwFrame const*)
Unexecuted instantiation: SwPageBreakWin::SwPageBreakWin(SwBreakDashedLine*, SwEditWin*, SwFrame const*)
150
151
SwPageBreakWin::~SwPageBreakWin( )
152
0
{
153
0
    disposeOnce();
154
0
}
155
156
void SwPageBreakWin::dispose()
157
0
{
158
0
    m_bDestroyed = true;
159
0
    m_aFadeTimer.Stop();
160
0
    m_xVirDev.disposeAndClear();
161
162
0
    m_pLine.reset();
163
0
    m_pEditWin.reset();
164
165
0
    m_xMenuButton.reset();
166
0
    InterimItemWindow::dispose();
167
0
}
168
169
void SwPageBreakWin::PaintButton()
170
0
{
171
0
    if (!m_xVirDev)
172
0
        return;
173
174
0
    const ::tools::Rectangle aRect(::tools::Rectangle(Point(0, 0), m_xVirDev->PixelToLogic(GetSizePixel())));
175
176
    // Properly paint the control
177
0
    BColor aColor = SwViewOption::GetCurrentViewOptions().GetPageBreakColor().getBColor();
178
179
0
    BColor aHslLine = rgb2hsl(aColor);
180
0
    double nLuminance = aHslLine.getZ();
181
0
    nLuminance += (1.0 - nLuminance) * 0.75;
182
0
    if ( aHslLine.getZ() > 0.7 )
183
0
        nLuminance = aHslLine.getZ() * 0.7;
184
0
    aHslLine.setZ(nLuminance);
185
0
    BColor aOtherColor = hsl2rgb(aHslLine);
186
187
0
    const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
188
0
    if (rSettings.GetHighContrastMode())
189
0
    {
190
0
        aColor = rSettings.GetDialogTextColor().getBColor();
191
0
        aOtherColor = rSettings.GetDialogColor().getBColor();
192
0
    }
193
194
0
    bool bRtl = AllSettings::GetLayoutRTL();
195
196
0
    drawinglayer::primitive2d::Primitive2DContainer aSeq;
197
0
    B2DRectangle aBRect = vcl::unotools::b2DRectangleFromRectangle(aRect);
198
0
    B2DPolygon aPolygon = createPolygonFromRect(aBRect, 3.0 / BUTTON_WIDTH, 3.0 / BUTTON_HEIGHT);
199
200
    // Create the polygon primitives
201
0
    aSeq.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
202
0
                                        B2DPolyPolygon(aPolygon), aOtherColor));
203
0
    aSeq.push_back(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
204
0
                                        std::move(aPolygon), aColor));
205
206
    // Create the primitive for the image
207
0
    Bitmap aBmp(RID_BMP_PAGE_BREAK);
208
0
    double nImgOfstX = 3.0;
209
0
    if (bRtl)
210
0
        nImgOfstX = aRect.Right() - aBmp.GetSizePixel().Width() - 3.0;
211
0
    aSeq.push_back(new drawinglayer::primitive2d::DiscreteBitmapPrimitive2D(
212
0
                                        aBmp, B2DPoint(nImgOfstX, 1.0)));
213
214
0
    double nTop = double(aRect.getOpenHeight()) / 2.0;
215
0
    double nBottom = nTop + 4.0;
216
0
    double nLeft = aRect.getOpenWidth() - ARROW_WIDTH - 6.0;
217
0
    if (bRtl)
218
0
        nLeft = ARROW_WIDTH - 2.0;
219
0
    double nRight = nLeft + 8.0;
220
221
0
    B2DPolygon aTriangle;
222
0
    aTriangle.append(B2DPoint(nLeft, nTop));
223
0
    aTriangle.append(B2DPoint(nRight, nTop));
224
0
    aTriangle.append(B2DPoint((nLeft + nRight) / 2.0, nBottom));
225
0
    aTriangle.setClosed(true);
226
227
0
    BColor aTriangleColor = COL_BLACK.getBColor();
228
0
    if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
229
0
        aTriangleColor = COL_WHITE.getBColor();
230
231
0
    aSeq.push_back( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
232
0
                                        B2DPolyPolygon(aTriangle), aTriangleColor));
233
234
0
    drawinglayer::primitive2d::Primitive2DContainer aGhostedSeq;
235
0
    double nFadeRate = double(m_nFadeRate) / 100.0;
236
0
    basegfx::BColorModifierSharedPtr aBColorModifier =
237
0
          std::make_shared<basegfx::BColorModifier_interpolate>(COL_WHITE.getBColor(),
238
0
                                                        1.0 - nFadeRate);
239
0
    aGhostedSeq.push_back( new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
240
0
                            std::move(aSeq), std::move(aBColorModifier)));
241
242
    // Create the processor and process the primitives
243
0
    const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
244
0
    std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(
245
0
        drawinglayer::processor2d::createProcessor2DFromOutputDevice(*m_xVirDev, aNewViewInfos));
246
247
0
    pProcessor->process(aGhostedSeq);
248
249
0
    m_xMenuButton->set_custom_button(m_xVirDev.get());
250
0
}
251
252
static SvxBreak lcl_GetBreakItem(const SwContentFrame* pCnt)
253
0
{
254
0
    SvxBreak eBreak = SvxBreak::NONE;
255
0
    if ( pCnt )
256
0
    {
257
0
        if ( pCnt->IsInTab() )
258
0
            eBreak =  pCnt->FindTabFrame()->GetBreakItem().GetBreak();
259
0
        else
260
0
            eBreak = pCnt->GetBreakItem().GetBreak();
261
0
    }
262
0
    return eBreak;
263
0
}
264
265
IMPL_LINK(SwPageBreakWin, SelectHdl, const OUString&, rIdent, void)
266
0
{
267
0
    SwFrameControlPtr pFrameControl = m_pEditWin->GetFrameControlsManager().GetControl(FrameControlType::PageBreak, m_pFrame);
268
269
0
    m_pLine->execute(rIdent);
270
271
    // Only fade if there is more than this temporary shared pointer:
272
    // The main reference has been deleted due to a page break removal
273
0
    if (pFrameControl.use_count() > 1)
274
0
        Fade( false );
275
0
}
276
277
void SwBreakDashedLine::execute(std::u16string_view rIdent)
278
0
{
279
0
    const SwPageFrame* pPageFrame = SwFrameMenuButtonBase::GetPageFrame(m_pFrame);
280
    // Is there a PageBefore break on this page?
281
0
    SwContentFrame *pCnt = const_cast<SwContentFrame*>(pPageFrame->FindFirstBodyContent());
282
0
    SvxBreak eBreak = lcl_GetBreakItem( pCnt );
283
284
    // Also check the previous page - to see if there is a PageAfter break
285
0
    SwContentFrame *pPrevCnt = nullptr;
286
0
    SvxBreak ePrevBreak = SvxBreak::NONE;
287
0
    const SwPageFrame* pPrevPage = static_cast<const SwPageFrame*>(pPageFrame->GetPrev());
288
0
    if ( pPrevPage )
289
0
    {
290
0
        pPrevCnt = const_cast<SwContentFrame*>(pPrevPage->FindLastBodyContent());
291
0
        ePrevBreak = lcl_GetBreakItem( pPrevCnt );
292
0
    }
293
294
0
    if (pCnt && rIdent == u"edit")
295
0
    {
296
0
        SwWrtShell& rSh = m_pEditWin->GetView().GetWrtShell();
297
0
        bool bOldLock = rSh.IsViewLocked();
298
0
        rSh.LockView( true );
299
300
        // Order of edit detection: first RES_BREAK PageAfter, then RES_BREAK PageBefore/RES_PAGEDESC
301
0
        if ( ePrevBreak == SvxBreak::PageAfter )
302
0
            pCnt = pPrevCnt;
303
304
0
        SwContentNode& rNd = pCnt->IsTextFrame()
305
0
            ? *static_cast<SwTextFrame*>(pCnt)->GetTextNodeFirst()
306
0
            : *static_cast<SwNoTextFrame*>(pCnt)->GetNode();
307
308
0
        rSh.Push();
309
0
        rSh.ClearMark();
310
0
        rSh.SetSelection(SwPaM(rNd));
311
312
0
        if ( pCnt->IsInTab() )
313
0
        {
314
0
            SfxStringItem aItem(m_pEditWin->GetView().GetPool().GetWhichIDFromSlotID(FN_FORMAT_TABLE_DLG), u"textflow"_ustr);
315
0
            m_pEditWin->GetView().GetViewFrame().GetDispatcher()->ExecuteList(
316
0
                    FN_FORMAT_TABLE_DLG,
317
0
                    SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
318
0
                    { &aItem });
319
0
        }
320
0
        else
321
0
        {
322
0
            SwPaM aPaM( rNd );
323
0
            SwPaMItem aPaMItem( m_pEditWin->GetView().GetPool( ).GetWhichIDFromSlotID( FN_PARAM_PAM ), &aPaM );
324
0
            SfxStringItem aItem( SID_PARA_DLG, u"textflow"_ustr );
325
0
            m_pEditWin->GetView().GetViewFrame().GetDispatcher()->ExecuteList(
326
0
                    SID_PARA_DLG,
327
0
                    SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
328
0
                    { &aItem, &aPaMItem });
329
0
        }
330
331
0
        rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
332
333
0
        rSh.LockView( bOldLock );
334
0
        m_pEditWin->GrabFocus( );
335
0
    }
336
0
    else if (pCnt && rIdent == u"delete")
337
0
    {
338
0
        SwContentNode& rNd = pCnt->IsTextFrame()
339
0
            ? *static_cast<SwTextFrame*>(pCnt)->GetTextNodeFirst()
340
0
            : *static_cast<SwNoTextFrame*>(pCnt)->GetNode();
341
342
0
        rNd.GetDoc().GetIDocumentUndoRedo( ).StartUndo( SwUndoId::UI_DELETE_PAGE_BREAK, nullptr );
343
344
0
        SfxItemSetFixed<RES_PAGEDESC, RES_BREAK> aSet(
345
0
            m_pEditWin->GetView().GetWrtShell().GetAttrPool());
346
347
0
        aSet.Put( SwFormatPageDesc( nullptr ) );
348
        // This break could be from the current paragraph, if it has a PageBefore break.
349
0
        if ( eBreak == SvxBreak::PageBefore )
350
0
            aSet.Put( SvxFormatBreakItem( SvxBreak::NONE, RES_BREAK ) );
351
352
0
        rNd.GetDoc().getIDocumentContentOperations().InsertItemSet(
353
0
            SwPaM(rNd), aSet, SetAttrMode::DEFAULT, pPageFrame->getRootFrame());
354
355
        // This break could be from the previous paragraph, if it has a PageAfter break.
356
0
        if ( ePrevBreak == SvxBreak::PageAfter )
357
0
        {
358
0
            SwContentNode& rPrevNd = pPrevCnt->IsTextFrame()
359
0
                ? *static_cast<SwTextFrame*>(pPrevCnt)->GetTextNodeFirst()
360
0
                : *static_cast<SwNoTextFrame*>(pPrevCnt)->GetNode();
361
0
            aSet.ClearItem();
362
0
            aSet.Put( SvxFormatBreakItem( SvxBreak::NONE, RES_BREAK ) );
363
0
            rPrevNd.GetDoc().getIDocumentContentOperations().InsertItemSet(
364
0
                SwPaM(rPrevNd), aSet, SetAttrMode::DEFAULT, pPrevCnt->getRootFrame());
365
0
        }
366
367
0
        rNd.GetDoc().GetIDocumentUndoRedo( ).EndUndo( SwUndoId::UI_DELETE_PAGE_BREAK, nullptr );
368
0
    }
369
0
}
370
371
void SwBreakDashedLine::UpdatePosition(const std::optional<Point>& xEvtPt)
372
0
{
373
0
    if ( xEvtPt )
374
0
    {
375
0
        if ( xEvtPt == m_xMousePt )
376
0
            return;
377
0
        m_xMousePt = xEvtPt;
378
0
    }
379
380
0
    const SwPageFrame* pPageFrame = SwFrameMenuButtonBase::GetPageFrame(m_pFrame);
381
0
    const SwFrame* pPrevPage = pPageFrame;
382
0
    do
383
0
    {
384
0
        pPrevPage = pPrevPage->GetPrev();
385
0
    }
386
0
    while ( pPrevPage && ( ( pPrevPage->getFrameArea().Top( ) == pPageFrame->getFrameArea().Top( ) )
387
0
                || static_cast< const SwPageFrame* >( pPrevPage )->IsEmptyPage( ) ) );
388
389
0
    ::tools::Rectangle aBoundRect = GetEditWin()->LogicToPixel( pPageFrame->GetBoundRect(GetEditWin()->GetOutDev()).SVRect() );
390
0
    ::tools::Rectangle aFrameRect = GetEditWin()->LogicToPixel( pPageFrame->getFrameArea().SVRect() );
391
392
0
    tools::Long nYLineOffset = ( aBoundRect.Top() + aFrameRect.Top() ) / 2;
393
0
    if ( pPrevPage )
394
0
    {
395
0
        ::tools::Rectangle aPrevFrameRect = GetEditWin()->LogicToPixel( pPrevPage->getFrameArea().SVRect() );
396
0
        nYLineOffset = ( aPrevFrameRect.Bottom() + aFrameRect.Top() ) / 2;
397
0
    }
398
399
    // Get the page + sidebar coords
400
0
    tools::Long nPgLeft = aFrameRect.Left();
401
0
    tools::Long nPgRight = aFrameRect.Right();
402
403
0
    tools::ULong nSidebarWidth = 0;
404
0
    const SwPostItMgr* pPostItMngr = GetEditWin()->GetView().GetWrtShell().GetPostItMgr();
405
0
    if ( pPostItMngr && pPostItMngr->HasNotes() && pPostItMngr->ShowNotes() )
406
0
        nSidebarWidth = pPostItMngr->GetSidebarBorderWidth( true ) + pPostItMngr->GetSidebarWidth( true );
407
408
0
    if ( pPageFrame->SidebarPosition( ) == sw::sidebarwindows::SidebarPosition::LEFT )
409
0
        nPgLeft -= nSidebarWidth;
410
0
    else if ( pPageFrame->SidebarPosition( ) == sw::sidebarwindows::SidebarPosition::RIGHT )
411
0
        nPgRight += nSidebarWidth;
412
413
0
    Size aBtnSize( BUTTON_WIDTH + ARROW_WIDTH, BUTTON_HEIGHT );
414
415
    // Place the button on the left or right?
416
0
    ::tools::Rectangle aVisArea = GetEditWin()->LogicToPixel( GetEditWin()->GetView().GetVisArea() );
417
418
0
    tools::Long nLineLeft = std::max( nPgLeft, aVisArea.Left() );
419
0
    tools::Long nLineRight = std::min( nPgRight, aVisArea.Right() );
420
0
    tools::Long nBtnLeft = nLineLeft;
421
422
0
    if ( m_xMousePt )
423
0
    {
424
0
        nBtnLeft = nLineLeft + m_xMousePt->X() - aBtnSize.getWidth() / 2;
425
426
0
        if ( nBtnLeft < nLineLeft )
427
0
            nBtnLeft = nLineLeft;
428
0
        else if ( ( nBtnLeft + aBtnSize.getWidth() ) > nLineRight )
429
0
            nBtnLeft = nLineRight - aBtnSize.getWidth();
430
0
    }
431
432
    // Set the button position
433
0
    m_aBtnRect = ::tools::Rectangle(Point(nBtnLeft, nYLineOffset - BUTTON_HEIGHT / 2), aBtnSize);
434
0
    if (m_pWin)
435
0
        m_pWin->SetRectanglePixel(m_aBtnRect);
436
437
    // Set the line position
438
0
    Point aLinePos( nLineLeft, nYLineOffset - 5 );
439
0
    Size aLineSize( nLineRight - nLineLeft, 10 );
440
0
    SetPosSizePixel(aLinePos, aLineSize);
441
0
}
442
443
void SwPageBreakWin::SetRectanglePixel(const ::tools::Rectangle& rRect)
444
0
{
445
0
    SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
446
0
    m_xVirDev->SetOutputSizePixel(rRect.GetSize());
447
0
}
448
449
void SwPageBreakWin::Fade( bool bFadeIn )
450
0
{
451
0
    m_bIsAppearing = bFadeIn;
452
0
    if ( bFadeIn )
453
0
        m_nDelayAppearing = 0;
454
455
0
    if ( !m_bDestroyed && m_aFadeTimer.IsActive( ) )
456
0
        m_aFadeTimer.Stop();
457
0
    if ( !m_bDestroyed )
458
0
        m_aFadeTimer.Start( );
459
0
}
460
461
IMPL_LINK(SwPageBreakWin, ToggleHdl, weld::Toggleable&, rMenuButton, void)
462
0
{
463
    // hide on dropdown, draw fully unfaded if dropdown before fully faded in
464
0
    Fade(rMenuButton.get_active());
465
0
}
466
467
IMPL_LINK_NOARG(SwPageBreakWin, FadeHandler, Timer *, void)
468
0
{
469
0
    const int TICKS_BEFORE_WE_APPEAR = 10;
470
0
    if ( m_bIsAppearing && m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR )
471
0
    {
472
0
        ++m_nDelayAppearing;
473
0
        m_aFadeTimer.Start();
474
0
        return;
475
0
    }
476
477
0
    if ( m_bIsAppearing && m_nFadeRate > 0 )
478
0
        m_nFadeRate -= 25;
479
0
    else if ( !m_bIsAppearing && m_nFadeRate < 100 )
480
0
        m_nFadeRate += 25;
481
482
0
    if ( m_nFadeRate != 100 && !IsVisible() )
483
0
        Show();
484
0
    else if ( m_nFadeRate == 100 && IsVisible( ) )
485
0
    {
486
0
        Hide();
487
0
        m_pLine->DestroyWin();
488
0
        return;
489
0
    }
490
0
    else
491
0
    {
492
0
        m_pLine->UpdatePosition();
493
0
        PaintButton();
494
0
    }
495
496
0
    if (IsVisible( ) && m_nFadeRate > 0 && m_nFadeRate < 100)
497
0
        m_aFadeTimer.Start();
498
0
}
499
500
FactoryFunction SwBreakDashedLine::GetUITestFactory() const
501
0
{
502
0
    return PageBreakUIObject::create;
503
0
}
504
505
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */