1
0
Fork 0
libreoffice/sw/source/uibase/uiview/uivwimp.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

333 lines
10 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <config_features.h>
#include <config_fuzzers.h>
#include <cmdid.h>
#include <com/sun/star/scanner/XScannerManager2.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
#include <comphelper/propertysequence.hxx>
#include <comphelper/servicehelper.hxx>
#include <vcl/weld.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docinsert.hxx>
#include <sfx2/request.hxx>
#include <uivwimp.hxx>
#include <unotxvw.hxx>
#include <unodispatch.hxx>
#include <swmodule.hxx>
#include <swdtflvr.hxx>
#include <strings.hrc>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::scanner;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::datatransfer::clipboard;
SwView_Impl::SwView_Impl(SwView* pShell)
: m_pView(pShell)
, m_eShellMode(ShellMode::Text)
, m_nParam(0)
, m_bSelectObject(false)
, m_bEditingPositionSet(false)
{
mxXTextView = new SwXTextView(m_pView);
m_xDispatchProviderInterceptor = new SwXDispatchProviderInterceptor(*m_pView);
}
SwView_Impl::~SwView_Impl()
{
if(m_xDispatchProviderInterceptor)
m_xDispatchProviderInterceptor->Invalidate();
mxXTextView->Invalidate();
mxXTextView.clear();
if( mxScanEvtLstnr.is() )
mxScanEvtLstnr->ViewDestroyed();
if( mxClipEvtLstnr.is() )
{
mxClipEvtLstnr->AddRemoveListener( false );
mxClipEvtLstnr->ViewDestroyed();
}
DisconnectTransferableDDE();
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
m_xConfigItem.reset();
#endif
m_pDocInserter.reset();
m_pRequest.reset();
}
void SwView_Impl::SetShellMode(ShellMode eSet)
{
m_eShellMode = eSet;
}
view::XSelectionSupplier* SwView_Impl::GetUNOObject()
{
return mxXTextView.get();
}
SwXTextView* SwView_Impl::GetUNOObject_Impl()
{
return mxXTextView.get();
}
void SwView_Impl::ExecuteScan( SfxRequest& rReq )
{
switch(rReq.GetSlot())
{
case SID_TWAIN_SELECT:
{
bool bDone = false;
Reference<XScannerManager2> xScanMgr = SwModule::get()->GetScannerManager();
if( xScanMgr.is() )
{
try
{
SwScannerEventListener& rListener = GetScannerEventListener();
const Sequence< ScannerContext >
aContexts( xScanMgr->getAvailableScanners() );
if( aContexts.hasElements() )
{
Reference< XEventListener > xLstner = &rListener;
ScannerContext aContext( aContexts.getConstArray()[ 0 ] );
Reference<lang::XInitialization> xInit(xScanMgr, UNO_QUERY);
if (xInit.is())
{
// initialize dialog
weld::Window* pWindow = rReq.GetFrameWeld();
uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence(
{
{"ParentWindow", pWindow ? uno::Any(pWindow->GetXWindow()) : uno::Any(Reference<awt::XWindow>())}
}));
xInit->initialize( aSeq );
}
bDone = xScanMgr->configureScannerAndScan( aContext, xLstner );
}
}
catch(...)
{
}
}
if( bDone )
rReq.Done();
else
{
rReq.Ignore();
}
}
break;
case SID_TWAIN_TRANSFER:
{
bool bDone = false;
Reference<XScannerManager2> xScanMgr = SwModule::get()->GetScannerManager();
if( xScanMgr.is() )
{
SwScannerEventListener& rListener = GetScannerEventListener();
try
{
const Sequence< scanner::ScannerContext >aContexts( xScanMgr->getAvailableScanners() );
if( aContexts.hasElements() )
{
Reference< XEventListener > xLstner = &rListener;
xScanMgr->startScan( aContexts.getConstArray()[ 0 ], xLstner );
bDone = true;
}
}
catch(...)
{
}
}
if( !bDone )
{
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(rReq.GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
SwResId(STR_SCAN_NOSOURCE)));
xBox->run();
rReq.Ignore();
}
else
{
rReq.Done();
SfxBindings& rBind = m_pView->GetViewFrame().GetBindings();
rBind.Invalidate( SID_TWAIN_SELECT );
rBind.Invalidate( SID_TWAIN_TRANSFER );
}
}
break;
}
}
SwScannerEventListener& SwView_Impl::GetScannerEventListener()
{
if(!mxScanEvtLstnr.is())
mxScanEvtLstnr = new SwScannerEventListener(*m_pView);
return *mxScanEvtLstnr;
}
void SwView_Impl::AddClipboardListener()
{
if(!mxClipEvtLstnr.is())
{
mxClipEvtLstnr = new SwClipboardChangeListener( *m_pView );
mxClipEvtLstnr->AddRemoveListener( true );
}
}
void SwView_Impl::Invalidate()
{
GetUNOObject_Impl()->Invalidate();
for (const auto& xTransferable: mxTransferables)
{
rtl::Reference<SwTransferable> pTransferable = xTransferable.get();
if(pTransferable)
pTransferable->Invalidate();
}
}
void SwView_Impl::DisconnectTransferableDDE()
{
for (const auto& xTransferable: mxTransferables)
{
rtl::Reference<SwTransferable> pTransferable = xTransferable.get();
if(pTransferable)
pTransferable->DisconnectDDE();
}
}
void SwView_Impl::AddTransferable(SwTransferable& rTransferable)
{
//prevent removing of the non-referenced SwTransferable
osl_atomic_increment(&rTransferable.m_refCount);
{
// Remove previously added, but no longer existing weak references.
std::erase_if(mxTransferables,
[](const unotools::WeakReference<SwTransferable>& rTunnel) {
return !rTunnel.get();
});
mxTransferables.emplace_back(&rTransferable);
}
osl_atomic_decrement(&rTransferable.m_refCount);
}
void SwView_Impl::StartDocumentInserter(
const OUString& rFactory,
const Link<sfx2::FileDialogHelper*,void>& rEndDialogHdl,
const sal_uInt16 nSlotId
)
{
sfx2::DocumentInserter::Mode mode {sfx2::DocumentInserter::Mode::Insert};
switch( nSlotId )
{
case SID_DOCUMENT_MERGE:
mode = sfx2::DocumentInserter::Mode::Merge;
break;
case SID_DOCUMENT_COMPARE:
mode = sfx2::DocumentInserter::Mode::Compare;
break;
default:
break;
}
m_pDocInserter.reset(new ::sfx2::DocumentInserter(m_pView->GetFrameWeld(), rFactory, mode));
m_pDocInserter->StartExecuteModal( rEndDialogHdl );
}
std::unique_ptr<SfxMedium> SwView_Impl::CreateMedium()
{
return m_pDocInserter->CreateMedium();
}
void SwView_Impl::InitRequest( const SfxRequest& rRequest )
{
m_pRequest.reset(new SfxRequest( rRequest ));
}
SwScannerEventListener::~SwScannerEventListener()
{
}
void SAL_CALL SwScannerEventListener::disposing( const EventObject& /*rEventObject*/)
{
#if defined(_WIN32) || defined UNX
SolarMutexGuard aGuard;
if( m_pView )
m_pView->ScannerEventHdl();
#endif
}
SwClipboardChangeListener::~SwClipboardChangeListener()
{
}
void SAL_CALL SwClipboardChangeListener::disposing( const EventObject& /*rEventObject*/ )
{
SolarMutexGuard aGuard;
m_pView = nullptr; // so we don't touch the view if changedContents somehow fires afterwards
}
void SAL_CALL SwClipboardChangeListener::changedContents( const css::datatransfer::clipboard::ClipboardEvent& rEventObject )
{
const SolarMutexGuard aGuard;
if( !m_pView )
return;
{
TransferableDataHelper aDataHelper( rEventObject.Contents );
SwWrtShell& rSh = m_pView->GetWrtShell();
m_pView->m_nLastPasteDestination = SwTransferable::GetSotDestination( rSh );
m_pView->m_bPasteState = aDataHelper.GetXTransferable().is() &&
SwTransferable::IsPaste( rSh, aDataHelper );
m_pView->m_bPasteSpecialState = aDataHelper.GetXTransferable().is() &&
SwTransferable::IsPasteSpecial( rSh, aDataHelper );
}
SfxBindings& rBind = m_pView->GetViewFrame().GetBindings();
rBind.Invalidate( SID_PASTE );
rBind.Invalidate( SID_PASTE_SPECIAL );
rBind.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
}
void SwClipboardChangeListener::AddRemoveListener( bool bAdd )
{
m_pView->AddRemoveClipboardListener( Reference< XClipboardListener >( this ), bAdd );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */