/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 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 xInit(xScanMgr, UNO_QUERY); if (xInit.is()) { // initialize dialog weld::Window* pWindow = rReq.GetFrameWeld(); uno::Sequence aSeq(comphelper::InitAnyPropertySequence( { {"ParentWindow", pWindow ? uno::Any(pWindow->GetXWindow()) : uno::Any(Reference())} })); 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 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 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 pTransferable = xTransferable.get(); if(pTransferable) pTransferable->Invalidate(); } } void SwView_Impl::DisconnectTransferableDDE() { for (const auto& xTransferable: mxTransferables) { rtl::Reference 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& rTunnel) { return !rTunnel.get(); }); mxTransferables.emplace_back(&rTransferable); } osl_atomic_decrement(&rTransferable.m_refCount); } void SwView_Impl::StartDocumentInserter( const OUString& rFactory, const Link& 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 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: */