Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/tabcontr.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <TabControl.hxx>
21
22
#include <sfx2/viewfrm.hxx>
23
#include <sfx2/dispatch.hxx>
24
#include <vcl/commandevent.hxx>
25
#include <vcl/vclevent.hxx>
26
27
#include <app.hrc>
28
29
#include <DrawViewShell.hxx>
30
#include <helpids.h>
31
#include <View.hxx>
32
#include <drawdoc.hxx>
33
#include <DrawDocShell.hxx>
34
35
namespace sd {
36
37
38
TabControl::TabControlTransferable::~TabControlTransferable()
39
0
{
40
0
}
41
42
void TabControl::TabControlTransferable::AddSupportedFormats()
43
0
{
44
0
    AddFormat( SotClipboardFormatId::STARDRAW_TABBAR );
45
0
}
46
47
bool TabControl::TabControlTransferable::GetData( const css::datatransfer::DataFlavor& /*rFlavor*/, const OUString& /*rDestDoc*/ )
48
0
{
49
0
    return false;
50
0
}
51
52
void TabControl::TabControlTransferable::DragFinished( sal_Int8 /*nDropAction*/ )
53
0
{
54
0
    mrParent.DragFinished();
55
0
}
56
57
TabControl::TabControl(DrawViewShell* pViewSh, vcl::Window* pParent) :
58
0
    TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_SIZEABLE | WB_DRAG) ),
59
0
    DragSourceHelper( this ),
60
0
    DropTargetHelper( this ),
61
0
    pDrViewSh(pViewSh),
62
0
    bInternalMove(false)
63
0
{
64
0
    EnableEditMode();
65
0
    SetSizePixel(Size(0, 0));
66
0
    SetMaxPageWidth( 150 );
67
0
    SetHelpId( HID_SD_TABBAR_PAGES );
68
0
}
Unexecuted instantiation: sd::TabControl::TabControl(sd::DrawViewShell*, vcl::Window*)
Unexecuted instantiation: sd::TabControl::TabControl(sd::DrawViewShell*, vcl::Window*)
69
70
TabControl::~TabControl()
71
0
{
72
0
    disposeOnce();
73
0
}
74
75
void TabControl::dispose()
76
0
{
77
0
    DragSourceHelper::dispose();
78
0
    DropTargetHelper::dispose();
79
0
    TabBar::dispose();
80
0
}
81
82
void TabControl::Select()
83
0
{
84
0
    SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
85
0
    pDispatcher->Execute(SID_SWITCHPAGE, SfxCallMode::ASYNCHRON |
86
0
                            SfxCallMode::RECORD);
87
0
}
88
89
void  TabControl::MouseButtonDown(const MouseEvent& rMEvt)
90
0
{
91
0
    if (rMEvt.IsLeft()
92
0
        && !rMEvt.IsMod1()
93
0
        && !rMEvt.IsMod2()
94
0
        && !rMEvt.IsShift())
95
0
    {
96
0
        Point aPos = PixelToLogic( rMEvt.GetPosPixel() );
97
0
        sal_uInt16 aPageId = GetPageId(aPos);
98
99
        //initialize
100
0
        if (aPageId == 0)
101
0
        {
102
0
            SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
103
104
0
            pDispatcher->Execute(SID_INSERTPAGE_QUICK,
105
0
                                SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
106
0
        }
107
0
    }
108
109
    // A single left click with pressed control key on a tab page first
110
    // switches to that page before the usual handling (copying with drag
111
    // and drop) takes place.
112
0
    else if (rMEvt.IsLeft() && rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift())
113
0
    {
114
0
        pDrViewSh->SwitchPage (GetPageId (rMEvt.GetPosPixel()) - 1);
115
0
    }
116
117
    // When only the right button is pressed then first process a
118
    // synthesized left button click to make the page the current one
119
    // whose tab has been clicked.  When then the actual right button
120
    // click is processed the resulting context menu relates to the
121
    // now current page.
122
0
    if (rMEvt.IsRight() && ! rMEvt.IsLeft())
123
0
    {
124
0
        MouseEvent aSyntheticEvent (
125
0
            rMEvt.GetPosPixel(),
126
0
            rMEvt.GetClicks(),
127
0
            rMEvt.GetMode(),
128
0
            MOUSE_LEFT,
129
0
            rMEvt.GetModifier());
130
0
        TabBar::MouseButtonDown(aSyntheticEvent);
131
0
    }
132
133
0
    TabBar::MouseButtonDown(rMEvt);
134
0
}
135
136
void TabControl::DoubleClick()
137
0
{
138
0
    if (GetCurPageId() != 0)
139
0
    {
140
0
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
141
0
        pDispatcher->Execute( SID_MODIFYPAGE,
142
0
                        SfxCallMode::SYNCHRON | SfxCallMode::RECORD );
143
0
    }
144
0
}
145
146
void TabControl::StartDrag( sal_Int8, const Point& )
147
0
{
148
0
    bInternalMove = true;
149
150
    // object is delete by reference mechanism
151
0
    ( new TabControl::TabControlTransferable( *this ) )->StartDrag( this, DND_ACTION_COPYMOVE );
152
0
}
153
154
void TabControl::DragFinished()
155
0
{
156
0
    bInternalMove = false;
157
0
}
158
159
sal_Int8 TabControl::AcceptDrop( const AcceptDropEvent& rEvt )
160
0
{
161
0
    sal_Int8 nRet = DND_ACTION_NONE;
162
163
0
    if( rEvt.mbLeaving )
164
0
        EndSwitchPage();
165
166
0
    if( !pDrViewSh->GetDocSh()->IsReadOnly() )
167
0
    {
168
0
        SdDrawDocument* pDoc = pDrViewSh->GetDoc();
169
0
        Point           aPos( rEvt.maPosPixel );
170
171
0
        if( bInternalMove )
172
0
        {
173
0
            if( rEvt.mbLeaving || ( pDrViewSh->GetEditMode() == EditMode::MasterPage ) )
174
0
                HideDropPos();
175
0
            else
176
0
            {
177
0
                ShowDropPos( aPos );
178
0
                nRet = rEvt.mnAction;
179
0
            }
180
0
        }
181
0
        else
182
0
        {
183
0
            HideDropPos();
184
185
0
            sal_Int32 nPageId = GetPageId( aPos ) - 1;
186
187
0
            if( ( nPageId >= 0 ) && pDoc->GetPage( static_cast<sal_uInt16>(nPageId) ) )
188
0
            {
189
0
                nRet = pDrViewSh->AcceptDrop( rEvt, *this, nullptr, static_cast<sal_uInt16>(nPageId), SDRLAYER_NOTFOUND );
190
0
                SwitchPage( aPos );
191
0
            }
192
0
        }
193
0
    }
194
195
0
    return nRet;
196
0
}
197
198
sal_Int8 TabControl::ExecuteDrop( const ExecuteDropEvent& rEvt )
199
0
{
200
0
    SdDrawDocument* pDoc = pDrViewSh->GetDoc();
201
0
    Point           aPos( rEvt.maPosPixel );
202
0
    sal_Int8        nRet = DND_ACTION_NONE;
203
204
0
    if( bInternalMove )
205
0
    {
206
0
        sal_uInt16 nDropPos = ShowDropPos( aPos );
207
0
        assert(nDropPos > 0);
208
0
        sal_uInt16 nPageId = nDropPos - 1;
209
210
0
        switch (rEvt.mnAction)
211
0
        {
212
0
            case DND_ACTION_MOVE:
213
0
                if( pDrViewSh->IsSwitchPageAllowed() && pDoc->MoveSelectedPages( nPageId ) )
214
0
                {
215
0
                    SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
216
0
                    pDispatcher->Execute(SID_SWITCHPAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
217
0
                }
218
0
                break;
219
220
0
            case DND_ACTION_COPY:
221
0
            {
222
                // Copying the selected page to the place that rEvt points
223
                // takes place in three steps:
224
                // 1. Create a copy of the selected page.  This copy will
225
                // lie directly behind the selected page.
226
                // 2. Move the copy to the desired place.
227
                // 3. Select the copy.
228
0
                if (pDrViewSh->IsSwitchPageAllowed())
229
0
                {
230
                    // 1. Create a copy.
231
0
                    sal_uInt16 nPageNumOfCopy = pDoc->DuplicatePage (GetCurPageId() - 1);
232
                    // 2. Move page.  For this first switch to the copy:
233
                    // MovePages operates on the currently selected page(s).
234
0
                    pDrViewSh->SwitchPage (nPageNumOfCopy);
235
                    // Adapt target page id when necessary, i.e. page copy
236
                    // has been inserted in front of the target page.
237
0
                    sal_uInt16 nPageNum = nPageId;
238
0
                    if ((nPageNumOfCopy <= nPageNum) && (nPageNum != sal_uInt16(-1)))
239
0
                        nPageNum += 1;
240
0
                    if (pDoc->MoveSelectedPages(nPageNum))
241
0
                    {
242
                        // 3. Switch to the copy that has been moved to its
243
                        // final destination.  Use an asynchron slot call to
244
                        // be executed after the still pending ones.
245
0
                        if (nPageNumOfCopy >= nPageNum || (nPageNum == sal_uInt16(-1)))
246
0
                            nPageNum += 1;
247
0
                        SetCurPageId (GetPageId(nPageNum));
248
0
                        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
249
0
                        pDispatcher->Execute(SID_SWITCHPAGE,
250
0
                            SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
251
0
                    }
252
0
                }
253
254
0
                break;
255
0
            }
256
0
        }
257
258
0
        nRet = rEvt.mnAction;
259
0
    }
260
0
    else
261
0
    {
262
0
        sal_Int32 nPageId = GetPageId( aPos ) - 1;
263
264
0
        if( ( nPageId >= 0 ) && pDoc->GetPage( static_cast<sal_uInt16>(nPageId) ) )
265
0
        {
266
0
            nRet = pDrViewSh->ExecuteDrop( rEvt, *this, nullptr, static_cast<sal_uInt16>(nPageId), SDRLAYER_NOTFOUND );
267
0
        }
268
0
    }
269
270
0
    HideDropPos();
271
0
    EndSwitchPage();
272
273
0
    return nRet;
274
0
}
275
276
void TabControl::Command(const CommandEvent& rCEvt)
277
0
{
278
0
    if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
279
0
    {
280
0
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
281
0
        pDispatcher->ExecutePopup(u"pagetab"_ustr);
282
0
    }
283
0
}
284
285
bool TabControl::StartRenaming()
286
0
{
287
0
    bool bOK = false;
288
289
0
    if (pDrViewSh->GetPageKind() == PageKind::Standard)
290
0
    {
291
0
        bOK = true;
292
293
0
        ::sd::View* pView = pDrViewSh->GetView();
294
295
0
        if ( pView->IsTextEdit() )
296
0
            pView->SdrEndTextEdit();
297
0
    }
298
299
0
    return bOK;
300
0
}
301
302
TabBarAllowRenamingReturnCode TabControl::AllowRenaming()
303
0
{
304
0
    bool bOK = true;
305
306
0
    OUString aNewName( GetEditText() );
307
0
    OUString aCompareName( GetPageText( GetEditPageId() ) );
308
309
0
    if( aCompareName != aNewName )
310
0
    {
311
        // rename page
312
0
        if (pDrViewSh->GetDocSh()->CheckPageName(GetFrameWeld(), aNewName))
313
0
        {
314
0
            SetEditText( aNewName );
315
0
            EndRenaming();
316
0
        }
317
0
        else
318
0
        {
319
0
            bOK = false;
320
0
        }
321
0
    }
322
0
    return bOK ? TABBAR_RENAMING_YES : TABBAR_RENAMING_NO;
323
0
}
324
325
void TabControl::EndRenaming()
326
0
{
327
0
    if( !IsEditModeCanceled() )
328
0
        pDrViewSh->RenameSlide( GetEditPageId(), GetEditText() );
329
0
}
330
331
void TabControl::ActivatePage()
332
0
{
333
0
    if ( /*IsInSwitching && */ pDrViewSh->IsSwitchPageAllowed() )
334
0
    {
335
0
        SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
336
0
        pDispatcher->Execute(SID_SWITCHPAGE,
337
0
                             SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
338
0
    }
339
0
}
340
341
bool TabControl::DeactivatePage()
342
0
{
343
0
    return pDrViewSh->IsSwitchPageAllowed();
344
0
}
345
346
void TabControl::SendActivatePageEvent()
347
0
{
348
0
    CallEventListeners (VclEventId::TabbarPageActivated,
349
0
        reinterpret_cast<void*>(GetCurPageId()));
350
0
}
351
352
void TabControl::SendDeactivatePageEvent()
353
0
{
354
0
    CallEventListeners (VclEventId::TabbarPageDeactivated,
355
0
        reinterpret_cast<void*>(GetCurPageId()));
356
0
}
357
358
} // end of namespace sd
359
360
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */