Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sw/source/uibase/wrtsh/wrtsh3.cxx
Line
Count
Source (jump to first uncovered line)
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 <svx/svxids.hrc>
21
#include <sfx2/app.hxx>
22
#include <sfx2/bindings.hxx>
23
#include <sfx2/viewfrm.hxx>
24
#include <svx/svdmark.hxx>
25
#include <svx/svdview.hxx>
26
#include <svx/svdouno.hxx>
27
#include <svx/srchdlg.hxx>
28
#include <com/sun/star/form/FormButtonType.hpp>
29
#include <com/sun/star/beans/XPropertySet.hpp>
30
#include <osl/diagnose.h>
31
#include <sfx2/dispatch.hxx>
32
#include <comphelper/lok.hxx>
33
#include <tools/json_writer.hxx>
34
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
35
36
#include <swmodule.hxx>
37
#include <wrtsh.hxx>
38
#include <view.hxx>
39
#include <IMark.hxx>
40
#include <doc.hxx>
41
#include <formatcontentcontrol.hxx>
42
#include <IDocumentUndoRedo.hxx>
43
#include <SwRewriter.hxx>
44
#include <strings.hrc>
45
#include <textcontentcontrol.hxx>
46
47
using namespace ::com::sun::star;
48
49
bool SwWrtShell::MoveBookMark( BookMarkMove eFuncId, const ::sw::mark::MarkBase* const pMark)
50
0
{
51
0
    addCurrentPosition();
52
0
    (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
53
54
0
    bool bRet = true;
55
0
    switch(eFuncId)
56
0
    {
57
0
        case BOOKMARK_INDEX:bRet = SwCursorShell::GotoMark( pMark );break;
58
0
        case BOOKMARK_NEXT: bRet = SwCursorShell::GoNextBookmark();break;
59
0
        case BOOKMARK_PREV: bRet = SwCursorShell::GoPrevBookmark();break;
60
0
        default:;//prevent warning
61
0
    }
62
63
0
    if( bRet && IsSelFrameMode() )
64
0
    {
65
0
        UnSelectFrame();
66
0
        LeaveSelFrameMode();
67
0
    }
68
0
    if( IsSelection() )
69
0
    {
70
0
        m_fnKillSel = &SwWrtShell::ResetSelect;
71
0
        m_fnSetCursor = &SwWrtShell::SetCursorKillSel;
72
0
    }
73
0
    return bRet;
74
0
}
75
76
bool SwWrtShell::GotoField( const SwFormatField& rField )
77
0
{
78
0
    (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
79
80
0
    bool bRet = SwCursorShell::GotoFormatField( rField );
81
0
    if( bRet && IsSelFrameMode() )
82
0
    {
83
0
        UnSelectFrame();
84
0
        LeaveSelFrameMode();
85
0
    }
86
87
0
    if( IsSelection() )
88
0
    {
89
0
        m_fnKillSel = &SwWrtShell::ResetSelect;
90
0
        m_fnSetCursor = &SwWrtShell::SetCursorKillSel;
91
0
    }
92
93
0
    return bRet;
94
0
}
95
96
bool SwWrtShell::GotoContentControl(const SwFormatContentControl& rContentControl,
97
                                    bool bOnlyRefresh)
98
0
{
99
0
    const std::shared_ptr<SwContentControl>& pContentControl = rContentControl.GetContentControl();
100
0
    if (IsFrameSelected() && pContentControl && pContentControl->GetPicture())
101
0
    {
102
        // A frame is already selected, and its anchor is inside a picture content control.
103
0
        if (pContentControl->GetShowingPlaceHolder())
104
0
        {
105
            // Replace the placeholder image with a real one.
106
0
            GetView().StopShellTimer();
107
0
            if (comphelper::LibreOfficeKit::isActive())
108
0
            {
109
0
                tools::JsonWriter aJson;
110
0
                aJson.put("action", "change-picture");
111
0
                OString pJson(aJson.finishAndGetAsOString());
112
0
                if (SfxViewShell* pNotifySh = GetSfxViewShell())
113
0
                    pNotifySh->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL,
114
0
                                                              pJson);
115
0
            }
116
0
            else
117
0
            {
118
0
                GetView().GetViewFrame().GetDispatcher()->Execute(SID_CHANGE_PICTURE,
119
0
                                                                   SfxCallMode::SYNCHRON);
120
0
            }
121
0
            pContentControl->SetShowingPlaceHolder(false);
122
0
        }
123
0
        return true;
124
0
    }
125
126
0
    (this->*m_fnKillSel)(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
127
128
0
    bool bRet = SwCursorShell::GotoFormatContentControl(rContentControl);
129
130
0
    if (bRet && pContentControl && pContentControl->GetCheckbox())
131
0
    {
132
        // Checkbox: GotoFormatContentControl() selected the old state.
133
0
        LockView(/*bViewLocked=*/true);
134
0
        OUString aOldState = GetCursorDescr();
135
0
        OUString aNewState;
136
0
        if (pContentControl->GetChecked())
137
0
            aNewState = bOnlyRefresh ? pContentControl->GetCheckedState()
138
0
                                     : pContentControl->GetUncheckedState();
139
0
        else
140
0
            aNewState = bOnlyRefresh ? pContentControl->GetUncheckedState()
141
0
                                     : pContentControl->GetCheckedState();
142
143
0
        SwRewriter aRewriter;
144
0
        aRewriter.AddRule(UndoArg1, aOldState);
145
0
        aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
146
0
        aRewriter.AddRule(UndoArg3, aNewState);
147
0
        GetIDocumentUndoRedo().StartUndo(SwUndoId::REPLACE, &aRewriter);
148
149
        // Toggle the state.
150
0
        pContentControl->SetReadWrite(true);
151
0
        DelLeft();
152
0
        if (!bOnlyRefresh)
153
0
            pContentControl->SetChecked(!pContentControl->GetChecked());
154
0
        Insert(aNewState);
155
0
        pContentControl->SetReadWrite(false);
156
157
0
        GetIDocumentUndoRedo().EndUndo(SwUndoId::REPLACE, &aRewriter);
158
0
        LockView(/*bViewLocked=*/false);
159
0
        ShowCursor();
160
0
    }
161
0
    else if (bRet && pContentControl && pContentControl->GetSelectedListItem())
162
0
    {
163
        // Dropdown: GotoFormatContentControl() selected the old content.
164
0
        size_t nSelectedListItem = *pContentControl->GetSelectedListItem();
165
0
        LockView(/*bViewLocked=*/true);
166
0
        OUString aOldState = GetCursorDescr();
167
0
        OUString aNewState = pContentControl->GetListItems()[nSelectedListItem].ToString();
168
0
        SwRewriter aRewriter;
169
0
        aRewriter.AddRule(UndoArg1, aOldState);
170
0
        aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
171
0
        aRewriter.AddRule(UndoArg3, SwResId(STR_START_QUOTE) + aNewState + SwResId(STR_END_QUOTE));
172
0
        GetIDocumentUndoRedo().StartUndo(SwUndoId::REPLACE, &aRewriter);
173
174
        // Update the content.
175
0
        pContentControl->SetReadWrite(true);
176
0
        DelLeft();
177
0
        pContentControl->SetSelectedListItem(std::nullopt);
178
0
        Insert(aNewState);
179
0
        pContentControl->SetReadWrite(false);
180
181
0
        GetIDocumentUndoRedo().EndUndo(SwUndoId::REPLACE, &aRewriter);
182
0
        LockView(/*bViewLocked=*/false);
183
0
        ShowCursor();
184
0
    }
185
0
    else if (bRet && pContentControl && pContentControl->GetSelectedDate())
186
0
    {
187
        // Date: GotoFormatContentControl() selected the old content.
188
0
        LockView(/*bViewLocked=*/true);
189
0
        OUString aOldState = GetCursorDescr();
190
0
        OUString aNewState = pContentControl->GetDateString();
191
0
        SwRewriter aRewriter;
192
0
        aRewriter.AddRule(UndoArg1, aOldState);
193
0
        aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
194
0
        aRewriter.AddRule(UndoArg3, SwResId(STR_START_QUOTE) + aNewState + SwResId(STR_END_QUOTE));
195
0
        GetIDocumentUndoRedo().StartUndo(SwUndoId::REPLACE, &aRewriter);
196
197
        // Write the doc model.
198
0
        pContentControl->SetCurrentDateValue(*pContentControl->GetSelectedDate());
199
0
        pContentControl->SetSelectedDate(std::nullopt);
200
201
        // Update the content.
202
0
        DelLeft();
203
0
        Insert(aNewState);
204
205
0
        GetIDocumentUndoRedo().EndUndo(SwUndoId::REPLACE, &aRewriter);
206
0
        LockView(/*bViewLocked=*/false);
207
0
        ShowCursor();
208
0
    }
209
210
0
    if (bRet && IsSelFrameMode())
211
0
    {
212
0
        UnSelectFrame();
213
0
        LeaveSelFrameMode();
214
0
    }
215
216
0
    if (IsSelection())
217
0
    {
218
0
        m_fnKillSel = &SwWrtShell::ResetSelect;
219
0
        m_fnSetCursor = &SwWrtShell::SetCursorKillSel;
220
0
    }
221
222
0
    return bRet;
223
0
}
224
225
bool SwWrtShell::GotoFieldmark(::sw::mark::Fieldmark const * const pMark)
226
0
{
227
0
    (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
228
0
    bool bRet = SwCursorShell::GotoFieldmark(pMark);
229
0
    if( bRet && IsSelFrameMode() )
230
0
    {
231
0
        UnSelectFrame();
232
0
        LeaveSelFrameMode();
233
0
    }
234
0
    if( IsSelection() )
235
0
    {
236
0
        m_fnKillSel = &SwWrtShell::ResetSelect;
237
0
        m_fnSetCursor = &SwWrtShell::SetCursorKillSel;
238
0
    }
239
0
    return bRet;
240
0
}
241
242
// Invalidate FontWork-Slots
243
244
void SwWrtShell::DrawSelChanged( )
245
12
{
246
12
    static sal_uInt16 const aInval[] =
247
12
    {
248
12
        SID_ATTR_FILL_STYLE, SID_ATTR_FILL_COLOR, SID_ATTR_LINE_STYLE,
249
12
        SID_ATTR_LINE_WIDTH, SID_ATTR_LINE_COLOR,
250
        /*AF: these may be needed for the sidebar.
251
        SID_SVX_AREA_TRANSPARENCY, SID_SVX_AREA_TRANSP_GRADIENT,
252
        SID_SVX_AREA_TRANS_TYPE,
253
        */
254
12
        0
255
12
    };
256
257
12
    GetView().GetViewFrame().GetBindings().Invalidate(aInval);
258
259
12
    bool bOldVal = g_bNoInterrupt;
260
12
    g_bNoInterrupt = true;    // Trick to run AttrChangedNotify by timer.
261
12
    GetView().AttrChangedNotify(nullptr);
262
12
    g_bNoInterrupt = bOldVal;
263
12
}
264
265
void SwWrtShell::GotoMark( const SwMarkName& rName )
266
0
{
267
0
    auto ppMark = getIDocumentMarkAccess()->findMark( rName );
268
0
    if (ppMark == getIDocumentMarkAccess()->getAllMarksEnd())
269
0
        return;
270
0
    MoveBookMark( BOOKMARK_INDEX, *ppMark );
271
0
}
272
273
void SwWrtShell::GotoMark( const ::sw::mark::MarkBase* const pMark )
274
0
{
275
0
    MoveBookMark( BOOKMARK_INDEX, pMark );
276
0
}
277
278
bool SwWrtShell::GoNextBookmark()
279
0
{
280
0
    if ( !getIDocumentMarkAccess()->getBookmarksCount() )
281
0
    {
282
0
        SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
283
0
        return false;
284
0
    }
285
0
    LockView( true );
286
0
    bool bRet = MoveBookMark( BOOKMARK_NEXT );
287
0
    if ( !bRet )
288
0
    {
289
0
        MoveBookMark( BOOKMARK_INDEX, *getIDocumentMarkAccess()->getBookmarksBegin() );
290
0
        SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
291
0
    }
292
0
    else
293
0
        SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
294
0
    LockView( false );
295
0
    ShowCursor();
296
0
    return true;
297
0
}
298
299
bool SwWrtShell::GoPrevBookmark()
300
0
{
301
0
    if ( !getIDocumentMarkAccess()->getBookmarksCount() )
302
0
    {
303
0
        SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
304
0
        return false;
305
0
    }
306
0
    LockView( true );
307
0
    bool bRet = MoveBookMark( BOOKMARK_PREV );
308
0
    if ( !bRet )
309
0
    {
310
0
        MoveBookMark( BOOKMARK_INDEX, *( getIDocumentMarkAccess()->getBookmarksEnd() - 1 ) );
311
0
        SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
312
0
    }
313
0
    else
314
0
        SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
315
0
    LockView( false );
316
0
    ShowCursor();
317
0
    return true;
318
0
}
319
320
void SwWrtShell::ExecMacro( const SvxMacro& rMacro, OUString* pRet, SbxArray* pArgs )
321
0
{
322
    // execute macro, if it is allowed.
323
0
    if ( IsMacroExecAllowed() )
324
0
    {
325
0
        GetDoc()->ExecMacro( rMacro, pRet, pArgs );
326
0
    }
327
0
}
328
329
sal_uInt16 SwWrtShell::CallEvent( SvMacroItemId nEvent, const SwCallMouseEvent& rCallEvent,
330
                                bool bChkPtr)
331
0
{
332
0
    return GetDoc()->CallEvent( nEvent, rCallEvent, bChkPtr );
333
0
}
334
335
    // If a util::URL-Button is selected, return its util::URL
336
    // otherwise an empty string.
337
bool SwWrtShell::GetURLFromButton( OUString& rURL, OUString& rDescr ) const
338
0
{
339
0
    bool bRet = false;
340
0
    const SdrView *pDView = GetDrawView();
341
0
    if( pDView )
342
0
    {
343
        // A fly is precisely achievable if it is selected.
344
0
        const SdrMarkList &rMarkList = pDView->GetMarkedObjectList();
345
346
0
        if (rMarkList.GetMark(0))
347
0
        {
348
0
            SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( rMarkList.GetMark(0)->GetMarkedSdrObj() );
349
0
            if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
350
0
            {
351
0
                const uno::Reference< awt::XControlModel >&  xControlModel = pUnoCtrl->GetUnoControlModel();
352
353
0
                OSL_ENSURE( xControlModel.is(), "UNO-Control without Model" );
354
0
                if( !xControlModel.is() )
355
0
                    return bRet;
356
357
0
                uno::Reference< beans::XPropertySet >  xPropSet(xControlModel, uno::UNO_QUERY);
358
359
0
                uno::Any aTmp;
360
361
0
                uno::Reference< beans::XPropertySetInfo >   xInfo = xPropSet->getPropertySetInfo();
362
0
                if(xInfo->hasPropertyByName( u"ButtonType"_ustr ))
363
0
                {
364
0
                    aTmp = xPropSet->getPropertyValue( u"ButtonType"_ustr );
365
0
                    form::FormButtonType eTmpButtonType;
366
0
                    aTmp >>= eTmpButtonType;
367
0
                    if( form::FormButtonType_URL == eTmpButtonType)
368
0
                    {
369
                        // Label
370
0
                        aTmp = xPropSet->getPropertyValue( u"Label"_ustr );
371
0
                        OUString uTmp;
372
0
                        if( (aTmp >>= uTmp) && !uTmp.isEmpty())
373
0
                        {
374
0
                            rDescr = uTmp;
375
0
                        }
376
377
                        // util::URL
378
0
                        aTmp = xPropSet->getPropertyValue( u"TargetURL"_ustr );
379
0
                        if( (aTmp >>= uTmp) && !uTmp.isEmpty())
380
0
                        {
381
0
                            rURL = uTmp;
382
0
                        }
383
0
                        bRet = true;
384
0
                    }
385
0
                }
386
0
            }
387
0
        }
388
0
    }
389
390
0
    return bRet;
391
0
}
392
393
SwPostItMgr* SwWrtShell::GetPostItMgr()
394
421k
{
395
421k
    return m_rView.GetPostItMgr();
396
421k
}
397
398
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */