This is preparing to change how GraphicManager works where it won't base itself around GraphicObject anymore but Graphic. No functional or cosmetic change was made to the classes, only changes that were needed because of the move and rename. The only thing that wasn't moved is the GraphicRenderer as it is not needed in vcl for now (but makes sense to move it in the future to keep graphic stuff together). grfmgr was renamed to GraphicObject as the GraphicManager will be changed a lot and most likely moved out, so the name grfmgr won't make any sense anymore. All the UNO implementations were renamed with a prefix Uno and used the same name as the class name. This is made to be more specific which are the Uno objects (for example graphic.cxx contained the implementation of XGraphic, which is similar to graph.cxx contains Graphic). Change-Id: I54a2fa6c7e997469aaa7770db05244adb9f64137 Reviewed-on: https://gerrit.libreoffice.org/51068 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
203 lines
6.0 KiB
C++
203 lines
6.0 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/.
|
|
*/
|
|
|
|
#include <svx/extedit.hxx>
|
|
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/graph.hxx>
|
|
#include <vcl/GraphicObject.hxx>
|
|
#include <vcl/cvtgrf.hxx>
|
|
#include <vcl/graphicfilter.hxx>
|
|
#include <svx/xoutbmp.hxx>
|
|
#include <svx/graphichelper.hxx>
|
|
#include <svx/svdpagv.hxx>
|
|
#include <svx/svdograf.hxx>
|
|
#include <svx/fmview.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/bindings.hxx>
|
|
#include <salhelper/thread.hxx>
|
|
#include <osl/file.hxx>
|
|
#include <osl/thread.hxx>
|
|
#include <osl/process.h>
|
|
#include <osl/time.h>
|
|
#include <svtools/filechangedchecker.hxx>
|
|
#include <unotools/ucbstreamhelper.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
#include <memory>
|
|
|
|
#include <com/sun/star/system/SystemShellExecute.hpp>
|
|
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
|
|
|
|
using namespace css::uno;
|
|
using namespace css::system;
|
|
|
|
ExternalToolEdit::ExternalToolEdit()
|
|
{
|
|
}
|
|
|
|
ExternalToolEdit::~ExternalToolEdit()
|
|
{
|
|
}
|
|
|
|
void ExternalToolEdit::HandleCloseEvent(ExternalToolEdit* pData)
|
|
{
|
|
Graphic newGraphic;
|
|
|
|
//import the temp file image stream into the newGraphic
|
|
std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(pData->m_aFileName, StreamMode::READ));
|
|
if(pStream)
|
|
{
|
|
GraphicConverter::Import(*pStream, newGraphic);
|
|
|
|
// Now update the Graphic in the shell by re-reading from the newGraphic
|
|
pData->Update( newGraphic );
|
|
}
|
|
}
|
|
|
|
void ExternalToolEdit::StartListeningEvent()
|
|
{
|
|
//Start an event listener implemented via VCL timeout
|
|
assert(!m_pChecker.get());
|
|
m_pChecker.reset(new FileChangedChecker(
|
|
m_aFileName, [this] () { return HandleCloseEvent(this); }));
|
|
}
|
|
|
|
// self-destructing thread to make shell execute async
|
|
class ExternalToolEditThread
|
|
: public ::salhelper::Thread
|
|
{
|
|
private:
|
|
OUString const m_aFileName;
|
|
|
|
virtual void execute() override;
|
|
|
|
public:
|
|
explicit ExternalToolEditThread(OUString const& rFileName)
|
|
: ::salhelper::Thread("ExternalToolEdit")
|
|
, m_aFileName(rFileName)
|
|
{}
|
|
};
|
|
|
|
void ExternalToolEditThread::execute()
|
|
{
|
|
try
|
|
{
|
|
Reference<XSystemShellExecute> const xSystemShellExecute(
|
|
SystemShellExecute::create( ::comphelper::getProcessComponentContext()));
|
|
xSystemShellExecute->execute(m_aFileName, OUString(),
|
|
SystemShellExecuteFlags::URIS_ONLY);
|
|
}
|
|
catch (Exception const& e)
|
|
{
|
|
SAL_WARN("svx", "ExternalToolEditThread: " << e);
|
|
}
|
|
}
|
|
|
|
void ExternalToolEdit::Edit(GraphicObject const*const pGraphicObject)
|
|
{
|
|
//Get the graphic from the GraphicObject
|
|
const Graphic& aGraphic = pGraphicObject->GetGraphic();
|
|
|
|
//get the Preferred File Extension for this graphic
|
|
OUString fExtension;
|
|
GraphicHelper::GetPreferredExtension(fExtension, aGraphic);
|
|
|
|
//Create the temp File
|
|
OUString aTempFileBase;
|
|
OUString aTempFileName;
|
|
|
|
osl::FileBase::RC rc =
|
|
osl::FileBase::createTempFile(nullptr, nullptr, &aTempFileBase);
|
|
if (osl::FileBase::E_None != rc)
|
|
{
|
|
SAL_WARN("svx", "ExternalToolEdit::Edit: cannot create temp file");
|
|
return;
|
|
}
|
|
|
|
// Move it to a file name with image extension properly set
|
|
aTempFileName = aTempFileBase + "." + fExtension;
|
|
// FIXME: this is pretty stupid, need a better osl temp file API
|
|
rc = osl::File::move(aTempFileBase, aTempFileName);
|
|
if (osl::FileBase::E_None != rc)
|
|
{
|
|
SAL_WARN("svx", "ExternalToolEdit::Edit: cannot move temp file");
|
|
return;
|
|
}
|
|
|
|
//Write Graphic to the Temp File
|
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
|
sal_uInt16 nFilter(rGraphicFilter.GetExportFormatNumberForShortName(fExtension));
|
|
|
|
OUString aFilter(rGraphicFilter.GetExportFormatShortName(nFilter));
|
|
|
|
// Write the Graphic to the file now
|
|
XOutBitmap::WriteGraphic(aGraphic, aTempFileName, aFilter, XOutFlags::UseNativeIfPossible | XOutFlags::DontExpandFilename);
|
|
|
|
// There is a possibility that sPath extension might have been changed if the
|
|
// provided extension is not writable
|
|
m_aFileName = aTempFileName;
|
|
|
|
//Create a thread
|
|
|
|
rtl::Reference<ExternalToolEditThread> const pThread(
|
|
new ExternalToolEditThread(m_aFileName));
|
|
pThread->launch();
|
|
|
|
StartListeningEvent();
|
|
}
|
|
|
|
SdrExternalToolEdit::SdrExternalToolEdit(
|
|
FmFormView *const pView, SdrObject *const pObj)
|
|
: m_pView(pView)
|
|
, m_pObj(pObj)
|
|
{
|
|
assert(m_pObj && m_pView);
|
|
StartListening(*m_pObj->GetModel());
|
|
}
|
|
|
|
|
|
void SdrExternalToolEdit::Notify(SfxBroadcaster & rBC, SfxHint const& rHint)
|
|
{
|
|
SdrHint const*const pSdrHint(dynamic_cast<SdrHint const*>(&rHint));
|
|
if (pSdrHint
|
|
&& (SdrHintKind::ModelCleared == pSdrHint->GetKind()
|
|
|| (pSdrHint->GetObject() == m_pObj
|
|
&& SdrHintKind::ObjectRemoved == pSdrHint->GetKind())))
|
|
{
|
|
m_pView = nullptr;
|
|
m_pObj = nullptr;
|
|
m_pChecker.reset(); // avoid modifying deleted object
|
|
EndListening(rBC);
|
|
}
|
|
}
|
|
|
|
void SdrExternalToolEdit::Update(Graphic & rGraphic)
|
|
{
|
|
assert(m_pObj && m_pView); // timer should be deleted by Notify() too
|
|
SdrPageView *const pPageView = m_pView->GetSdrPageView();
|
|
if (pPageView)
|
|
{
|
|
SdrGrafObj *const pNewObj(static_cast<SdrGrafObj*>(m_pObj->Clone()));
|
|
assert(pNewObj);
|
|
OUString const description =
|
|
m_pView->GetDescriptionOfMarkedObjects() + " External Edit";
|
|
m_pView->BegUndo(description);
|
|
pNewObj->SetGraphicObject(rGraphic);
|
|
// set to new object before ReplaceObjectAtView() so that Notify() will
|
|
// not delete the running timer and crash
|
|
SdrObject *const pOldObj = m_pObj;
|
|
m_pObj = pNewObj;
|
|
m_pView->ReplaceObjectAtView(pOldObj, *pPageView, pNewObj);
|
|
m_pView->EndUndo();
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|