Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/uiview/uivwimp.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 <config_features.h>
21
#include <config_fuzzers.h>
22
23
#include <cmdid.h>
24
25
#include <com/sun/star/scanner/XScannerManager2.hpp>
26
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
27
#include <comphelper/propertysequence.hxx>
28
#include <comphelper/servicehelper.hxx>
29
#include <vcl/weld/MessageDialog.hxx>
30
#include <vcl/svapp.hxx>
31
#include <sfx2/viewfrm.hxx>
32
#include <sfx2/bindings.hxx>
33
#include <sfx2/docfile.hxx>
34
35
#include <sfx2/docinsert.hxx>
36
#include <sfx2/request.hxx>
37
#include <uivwimp.hxx>
38
#include <unotxvw.hxx>
39
#include <unodispatch.hxx>
40
#include <swmodule.hxx>
41
#include <swdtflvr.hxx>
42
43
#include <strings.hrc>
44
45
using namespace ::com::sun::star;
46
using namespace ::com::sun::star::uno;
47
using namespace ::com::sun::star::scanner;
48
using namespace ::com::sun::star::lang;
49
using namespace ::com::sun::star::datatransfer::clipboard;
50
51
SwView_Impl::SwView_Impl(SwView* pShell)
52
4.16k
    : m_pView(pShell)
53
4.16k
    , m_eShellMode(ShellMode::Text)
54
4.16k
    , m_nParam(0)
55
4.16k
    , m_bSelectObject(false)
56
4.16k
    , m_bEditingPositionSet(false)
57
4.16k
{
58
4.16k
    mxXTextView = new SwXTextView(m_pView);
59
4.16k
    m_xDispatchProviderInterceptor = new SwXDispatchProviderInterceptor(*m_pView);
60
4.16k
}
61
62
SwView_Impl::~SwView_Impl()
63
4.16k
{
64
4.16k
    if(m_xDispatchProviderInterceptor)
65
4.16k
        m_xDispatchProviderInterceptor->Invalidate();
66
4.16k
    mxXTextView->Invalidate();
67
4.16k
    mxXTextView.clear();
68
69
4.16k
    if( mxScanEvtLstnr.is() )
70
0
           mxScanEvtLstnr->ViewDestroyed();
71
4.16k
    if( mxClipEvtLstnr.is() )
72
0
    {
73
0
        mxClipEvtLstnr->AddRemoveListener( false );
74
0
        mxClipEvtLstnr->ViewDestroyed();
75
0
    }
76
4.16k
    DisconnectTransferableDDE();
77
78
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
79
    m_xConfigItem.reset();
80
#endif
81
4.16k
    m_pDocInserter.reset();
82
4.16k
    m_pRequest.reset();
83
4.16k
}
84
85
void SwView_Impl::SetShellMode(ShellMode eSet)
86
4.16k
{
87
4.16k
    m_eShellMode = eSet;
88
4.16k
}
89
90
view::XSelectionSupplier*   SwView_Impl::GetUNOObject()
91
0
{
92
0
    return mxXTextView.get();
93
0
}
94
95
SwXTextView*    SwView_Impl::GetUNOObject_Impl()
96
20.1k
{
97
20.1k
    return mxXTextView.get();
98
20.1k
}
99
100
void SwView_Impl::ExecuteScan( SfxRequest& rReq )
101
0
{
102
0
    switch(rReq.GetSlot())
103
0
    {
104
0
        case SID_TWAIN_SELECT:
105
0
        {
106
0
            bool bDone = false;
107
0
            Reference<XScannerManager2> xScanMgr = SwModule::get()->GetScannerManager();
108
109
0
            if( xScanMgr.is() )
110
0
            {
111
0
                try
112
0
                {
113
0
                    SwScannerEventListener& rListener = GetScannerEventListener();
114
0
                    const Sequence< ScannerContext >
115
0
                        aContexts( xScanMgr->getAvailableScanners() );
116
117
0
                    if( aContexts.hasElements() )
118
0
                    {
119
0
                        Reference< XEventListener > xLstner = &rListener;
120
0
                        ScannerContext aContext( aContexts.getConstArray()[ 0 ] );
121
122
0
                        Reference<lang::XInitialization> xInit(xScanMgr, UNO_QUERY);
123
0
                        if (xInit.is())
124
0
                        {
125
                            //  initialize dialog
126
0
                            weld::Window* pWindow = rReq.GetFrameWeld();
127
0
                            uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence(
128
0
                            {
129
0
                                {"ParentWindow", pWindow ? uno::Any(pWindow->GetXWindow()) : uno::Any(Reference<awt::XWindow>())}
130
0
                            }));
131
0
                            xInit->initialize( aSeq );
132
0
                        }
133
134
0
                        bDone = xScanMgr->configureScannerAndScan( aContext, xLstner );
135
0
                    }
136
0
                }
137
0
                catch(...)
138
0
                {
139
0
                }
140
141
0
            }
142
0
            if( bDone )
143
0
                rReq.Done();
144
0
            else
145
0
            {
146
0
                rReq.Ignore();
147
0
            }
148
0
        }
149
0
        break;
150
151
0
        case SID_TWAIN_TRANSFER:
152
0
        {
153
0
            bool bDone = false;
154
155
0
            Reference<XScannerManager2> xScanMgr = SwModule::get()->GetScannerManager();
156
0
            if( xScanMgr.is() )
157
0
            {
158
0
                SwScannerEventListener& rListener = GetScannerEventListener();
159
0
                try
160
0
                {
161
0
                    const Sequence< scanner::ScannerContext >aContexts( xScanMgr->getAvailableScanners() );
162
0
                    if( aContexts.hasElements() )
163
0
                    {
164
0
                        Reference< XEventListener > xLstner = &rListener;
165
0
                        xScanMgr->startScan( aContexts.getConstArray()[ 0 ], xLstner );
166
0
                        bDone = true;
167
0
                    }
168
0
                }
169
0
                catch(...)
170
0
                {
171
0
                }
172
0
            }
173
174
0
            if( !bDone )
175
0
            {
176
0
                std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(rReq.GetFrameWeld(),
177
0
                                                          VclMessageType::Info, VclButtonsType::Ok,
178
0
                                                          SwResId(STR_SCAN_NOSOURCE)));
179
0
                xBox->run();
180
0
                rReq.Ignore();
181
0
            }
182
0
            else
183
0
            {
184
0
                rReq.Done();
185
0
                SfxBindings& rBind = m_pView->GetViewFrame().GetBindings();
186
0
                rBind.Invalidate( SID_TWAIN_SELECT );
187
0
                rBind.Invalidate( SID_TWAIN_TRANSFER );
188
0
            }
189
0
        }
190
0
        break;
191
0
    }
192
0
}
193
194
SwScannerEventListener& SwView_Impl::GetScannerEventListener()
195
0
{
196
0
    if(!mxScanEvtLstnr.is())
197
0
        mxScanEvtLstnr = new SwScannerEventListener(*m_pView);
198
0
    return *mxScanEvtLstnr;
199
0
}
200
201
void SwView_Impl::AddClipboardListener()
202
0
{
203
0
    if(!mxClipEvtLstnr.is())
204
0
    {
205
0
        mxClipEvtLstnr = new SwClipboardChangeListener( *m_pView );
206
0
        mxClipEvtLstnr->AddRemoveListener( true );
207
0
    }
208
0
}
209
210
void SwView_Impl::Invalidate()
211
4.16k
{
212
4.16k
    GetUNOObject_Impl()->Invalidate();
213
4.16k
    for (const auto& xTransferable: mxTransferables)
214
0
    {
215
0
        rtl::Reference<SwTransferable> pTransferable = xTransferable.get();
216
0
        if(pTransferable)
217
0
            pTransferable->Invalidate();
218
0
    }
219
4.16k
}
220
221
void SwView_Impl::DisconnectTransferableDDE()
222
4.16k
{
223
4.16k
    for (const auto& xTransferable: mxTransferables)
224
0
    {
225
0
        rtl::Reference<SwTransferable> pTransferable = xTransferable.get();
226
0
        if(pTransferable)
227
0
            pTransferable->DisconnectDDE();
228
0
    }
229
4.16k
}
230
231
void SwView_Impl::AddTransferable(SwTransferable& rTransferable)
232
0
{
233
    //prevent removing of the non-referenced SwTransferable
234
0
    osl_atomic_increment(&rTransferable.m_refCount);
235
0
    {
236
        // Remove previously added, but no longer existing weak references.
237
0
        std::erase_if(mxTransferables,
238
0
            [](const unotools::WeakReference<SwTransferable>& rTunnel) {
239
0
                return !rTunnel.get();
240
0
            });
241
242
0
        mxTransferables.emplace_back(&rTransferable);
243
0
    }
244
0
    osl_atomic_decrement(&rTransferable.m_refCount);
245
0
}
246
247
void SwView_Impl::StartDocumentInserter(
248
    const OUString& rFactory,
249
    const Link<sfx2::FileDialogHelper*,void>& rEndDialogHdl,
250
    const sal_uInt16 nSlotId
251
)
252
0
{
253
0
    sfx2::DocumentInserter::Mode mode {sfx2::DocumentInserter::Mode::Insert};
254
0
    switch( nSlotId )
255
0
    {
256
0
        case SID_DOCUMENT_MERGE:
257
0
            mode = sfx2::DocumentInserter::Mode::Merge;
258
0
            break;
259
0
        case SID_DOCUMENT_COMPARE:
260
0
            mode = sfx2::DocumentInserter::Mode::Compare;
261
0
            break;
262
0
        default:
263
0
            break;
264
0
    }
265
266
0
    m_pDocInserter.reset(new ::sfx2::DocumentInserter(m_pView->GetFrameWeld(), rFactory, mode));
267
0
    m_pDocInserter->StartExecuteModal( rEndDialogHdl );
268
0
}
269
270
std::unique_ptr<SfxMedium> SwView_Impl::CreateMedium()
271
0
{
272
0
    return m_pDocInserter->CreateMedium();
273
0
}
274
275
void SwView_Impl::InitRequest( const SfxRequest& rRequest )
276
0
{
277
0
    m_pRequest.reset(new SfxRequest( rRequest ));
278
0
}
279
280
SwScannerEventListener::~SwScannerEventListener()
281
0
{
282
0
}
283
284
void SAL_CALL SwScannerEventListener::disposing( const EventObject& /*rEventObject*/)
285
0
{
286
0
#if defined(_WIN32) || defined UNX
287
0
    SolarMutexGuard aGuard;
288
0
    if( m_pView )
289
0
        m_pView->ScannerEventHdl();
290
0
#endif
291
0
}
292
293
SwClipboardChangeListener::~SwClipboardChangeListener()
294
0
{
295
0
}
296
297
void SAL_CALL SwClipboardChangeListener::disposing( const EventObject& /*rEventObject*/ )
298
0
{
299
0
    SolarMutexGuard aGuard;
300
0
    m_pView = nullptr; // so we don't touch the view if changedContents somehow fires afterwards
301
0
}
302
303
void SAL_CALL SwClipboardChangeListener::changedContents( const css::datatransfer::clipboard::ClipboardEvent& rEventObject )
304
305
0
{
306
0
    const SolarMutexGuard aGuard;
307
0
    if( !m_pView )
308
0
        return;
309
310
0
    {
311
0
        TransferableDataHelper aDataHelper( rEventObject.Contents );
312
0
        SwWrtShell& rSh = m_pView->GetWrtShell();
313
314
0
        m_pView->m_nLastPasteDestination = SwTransferable::GetSotDestination( rSh );
315
0
        m_pView->m_bPasteState = aDataHelper.GetXTransferable().is() &&
316
0
                        SwTransferable::IsPaste( rSh, aDataHelper );
317
318
0
        m_pView->m_bPasteSpecialState = aDataHelper.GetXTransferable().is() &&
319
0
                    SwTransferable::IsPasteSpecial( rSh, aDataHelper );
320
0
    }
321
322
0
    SfxBindings& rBind = m_pView->GetViewFrame().GetBindings();
323
0
    rBind.Invalidate( SID_PASTE );
324
0
    rBind.Invalidate( SID_PASTE_SPECIAL );
325
0
    rBind.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
326
0
}
327
328
void SwClipboardChangeListener::AddRemoveListener( bool bAdd )
329
0
{
330
0
    m_pView->AddRemoveClipboardListener( Reference< XClipboardListener >( this ), bAdd );
331
0
}
332
333
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */