bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / core / extedit.cxx
blobbb15fca328a33dd101e949d426eab1598ef5440a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <svx/extedit.hxx>
12 #include <vcl/svapp.hxx>
13 #include <vcl/graph.hxx>
14 #include <vcl/cvtgrf.hxx>
15 #include <vcl/graphicfilter.hxx>
16 #include <svx/xoutbmp.hxx>
17 #include <svx/graphichelper.hxx>
18 #include <svx/svdpagv.hxx>
19 #include <svx/svdograf.hxx>
20 #include <svx/fmview.hxx>
21 #include <svtools/grfmgr.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <sfx2/bindings.hxx>
24 #include <salhelper/thread.hxx>
25 #include <osl/file.hxx>
26 #include <osl/thread.hxx>
27 #include <osl/process.h>
28 #include <osl/time.h>
29 #include <svtools/filechangedchecker.hxx>
30 #include <unotools/ucbstreamhelper.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <boost/bind.hpp>
33 #include <boost/scoped_ptr.hpp>
35 #include <com/sun/star/system/SystemShellExecute.hpp>
36 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
38 using namespace css::uno;
39 using namespace css::system;
41 ExternalToolEdit::ExternalToolEdit()
45 ExternalToolEdit::~ExternalToolEdit()
49 void ExternalToolEdit::HandleCloseEvent(ExternalToolEdit* pData)
51 Graphic newGraphic;
53 //import the temp file image stream into the newGraphic
54 boost::scoped_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(pData->m_aFileName, StreamMode::READ));
55 if(pStream)
57 GraphicConverter::Import(*pStream, newGraphic);
59 // Now update the Graphic in the shell by re-reading from the newGraphic
60 pData->Update( newGraphic );
64 void ExternalToolEdit::StartListeningEvent()
66 //Start an event listener implemented via VCL timeout
67 assert(!m_pChecker.get());
68 m_pChecker.reset(new FileChangedChecker(
69 m_aFileName, ::boost::bind(&HandleCloseEvent, this)));
72 // self-destructing thread to make shell execute async
73 class ExternalToolEditThread
74 : public ::salhelper::Thread
76 private:
77 OUString const m_aFileName;
79 virtual void execute() SAL_OVERRIDE;
81 public:
82 ExternalToolEditThread(OUString const& rFileName)
83 : ::salhelper::Thread("ExternalToolEdit")
84 , m_aFileName(rFileName)
88 void ExternalToolEditThread::execute()
90 try
92 Reference<XSystemShellExecute> const xSystemShellExecute(
93 SystemShellExecute::create( ::comphelper::getProcessComponentContext()));
94 xSystemShellExecute->execute(m_aFileName, OUString(),
95 SystemShellExecuteFlags::URIS_ONLY);
97 catch (Exception const& e)
99 SAL_WARN("svx", "ExternalToolEditThread: exception: " << e.Message);
103 void ExternalToolEdit::Edit(GraphicObject const*const pGraphicObject)
105 //Get the graphic from the GraphicObject
106 const Graphic aGraphic = pGraphicObject->GetGraphic();
108 //get the Preferred File Extension for this graphic
109 OUString fExtension;
110 GraphicHelper::GetPreferredExtension(fExtension, aGraphic);
112 //Create the temp File
113 OUString aTempFileBase;
114 OUString aTempFileName;
116 osl::FileBase::RC rc =
117 osl::FileBase::createTempFile(nullptr, nullptr, &aTempFileBase);
118 if (osl::FileBase::E_None != rc)
120 SAL_WARN("svx", "ExternalToolEdit::Edit: cannot create temp file");
121 return;
124 // Move it to a file name with image extension properly set
125 aTempFileName = aTempFileBase + "." + OUString(fExtension);
126 // FIXME: this is pretty stupid, need a better osl temp file API
127 rc = osl::File::move(aTempFileBase, aTempFileName);
128 if (osl::FileBase::E_None != rc)
130 SAL_WARN("svx", "ExternalToolEdit::Edit: cannot move temp file");
131 return;
134 //Write Graphic to the Temp File
135 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
136 sal_uInt16 nFilter(rGraphicFilter.GetExportFormatNumberForShortName(fExtension));
138 OUString aFilter(rGraphicFilter.GetExportFormatShortName(nFilter));
140 // Write the Graphic to the file now
141 XOutBitmap::WriteGraphic(aGraphic, aTempFileName, aFilter, XOUTBMP_USE_NATIVE_IF_POSSIBLE | XOUTBMP_DONT_EXPAND_FILENAME);
143 // There is a possibility that sPath extension might have been changed if the
144 // provided extension is not writable
145 m_aFileName = aTempFileName;
147 //Create a thread
149 rtl::Reference<ExternalToolEditThread> const pThread(
150 new ExternalToolEditThread(m_aFileName));
151 pThread->launch();
153 StartListeningEvent();
156 SdrExternalToolEdit::SdrExternalToolEdit(
157 FmFormView *const pView, SdrObject *const pObj)
158 : m_pView(pView)
159 , m_pObj(pObj)
161 assert(m_pObj && m_pView);
162 StartListening(*m_pObj->GetModel());
166 void SdrExternalToolEdit::Notify(SfxBroadcaster & rBC, SfxHint const& rHint)
168 SdrHint const*const pSdrHint(dynamic_cast<SdrHint const*>(&rHint));
169 if (pSdrHint
170 && (HINT_MODELCLEARED == pSdrHint->GetKind()
171 || (pSdrHint->GetObject() == m_pObj
172 && HINT_OBJREMOVED == pSdrHint->GetKind())))
174 m_pView = 0;
175 m_pObj = 0;
176 m_pChecker.reset(); // avoid modifying deleted object
177 EndListening(rBC);
181 void SdrExternalToolEdit::Update(Graphic & rGraphic)
183 assert(m_pObj && m_pView); // timer should be deleted by Notify() too
184 SdrPageView *const pPageView = m_pView->GetSdrPageView();
185 if (pPageView)
187 SdrGrafObj *const pNewObj(static_cast<SdrGrafObj*>(m_pObj->Clone()));
188 assert(pNewObj);
189 OUString const description =
190 m_pView->GetDescriptionOfMarkedObjects() + " External Edit";
191 m_pView->BegUndo(description);
192 pNewObj->SetGraphicObject(rGraphic);
193 // set to new object before ReplaceObjectAtView() so that Notify() will
194 // not delete the running timer and crash
195 SdrObject *const pOldObj = m_pObj;
196 m_pObj = pNewObj;
197 m_pView->ReplaceObjectAtView(pOldObj, *pPageView, pNewObj);
198 m_pView->EndUndo();
202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */