summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2015-01-16 23:56:09 +0100
committerAndras Timar <andras.timar@collabora.com>2015-01-24 16:54:41 +0100
commitafb670be78890117dfc76d7f17880a3fd4317839 (patch)
tree0c04ba7768b95d79c352e1cfab35d94689d046fd /svx
parent43232c398e75df015f8c12687e780fd412370c0a (diff)
rhbz#1136013: svx: try to make the ExternalToolEdit not crash all the time
This thing was starting a timer that re-starts itself forever, and when the file it was watching changed, it would just assume the drawing objects were still there (and the document, for that matter...) (cherry picked from commit 5f6bdce0c0ac687f418821ce328f2987bf340cda) Conflicts: sc/source/ui/drawfunc/graphsh.cxx sd/source/ui/inc/DrawViewShell.hxx sd/source/ui/view/drviews2.cxx svx/source/core/extedit.cxx sw/source/core/uibase/shells/grfsh.cxx Converted to C++98. Change-Id: I35f187f0828097a05618dc1733dce819fc6bffc6 Reviewed-on: https://gerrit.libreoffice.org/13994 Tested-by: Caolán McNamara <caolanm@redhat.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svx')
-rw-r--r--svx/source/core/extedit.cxx97
1 files changed, 79 insertions, 18 deletions
diff --git a/svx/source/core/extedit.cxx b/svx/source/core/extedit.cxx
index 24e93f9d42aa..fba280d50bef 100644
--- a/svx/source/core/extedit.cxx
+++ b/svx/source/core/extedit.cxx
@@ -7,15 +7,21 @@
* 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/cvtgrf.hxx>
#include <vcl/graphicfilter.hxx>
#include <svx/xoutbmp.hxx>
-#include <svx/extedit.hxx>
#include <svx/graphichelper.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/fmview.hxx>
+#include <svtools/grfmgr.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>
@@ -32,7 +38,6 @@ using namespace css::uno;
using namespace css::system;
ExternalToolEdit::ExternalToolEdit()
- : m_pGraphicObject(NULL)
{
}
@@ -57,33 +62,40 @@ void ExternalToolEdit::HandleCloseEvent(ExternalToolEdit* pData)
}
}
-IMPL_LINK (ExternalToolEdit, StartListeningEvent, void*, pEvent)
+void ExternalToolEdit::StartListeningEvent()
{
//Start an event listener implemented via VCL timeout
- ExternalToolEdit* pData = ( ExternalToolEdit* )pEvent;
-
- new FileChangedChecker(pData->m_aFileName, ::boost::bind(&HandleCloseEvent, pData));
-
- return 0;
+ assert(!m_pChecker.get());
+ m_pChecker.reset(new FileChangedChecker(
+ m_aFileName, ::boost::bind(&HandleCloseEvent, this)));
}
-void ExternalToolEdit::threadWorker(void* pThreadData)
+// self-destructing thread to make shell execute async
+class ExternalToolEditThread
+ : public ::salhelper::Thread
{
- ExternalToolEdit* pData = (ExternalToolEdit*) pThreadData;
+private:
+ OUString const m_aFileName;
+
+ virtual void execute() SAL_OVERRIDE;
- // Make an asynchronous call to listen to the event of temporary image file
- // getting changed
- Application::PostUserEvent( LINK( NULL, ExternalToolEdit, StartListeningEvent ), pThreadData);
+public:
+ ExternalToolEditThread(OUString const& rFileName)
+ : ::salhelper::Thread("ExternalToolEdit")
+ , m_aFileName(rFileName)
+ {}
+};
+void ExternalToolEditThread::execute()
+{
Reference<XSystemShellExecute> xSystemShellExecute(
SystemShellExecute::create( ::comphelper::getProcessComponentContext() ) );
- xSystemShellExecute->execute( pData->m_aFileName, OUString(), SystemShellExecuteFlags::URIS_ONLY );
+ xSystemShellExecute->execute(m_aFileName, OUString(), SystemShellExecuteFlags::URIS_ONLY);
}
-void ExternalToolEdit::Edit( GraphicObject* pGraphicObject )
+void ExternalToolEdit::Edit(GraphicObject const*const pGraphicObject)
{
//Get the graphic from the GraphicObject
- m_pGraphicObject = pGraphicObject;
const Graphic aGraphic = pGraphicObject->GetGraphic();
//get the Preferred File Extension for this graphic
@@ -116,8 +128,57 @@ void ExternalToolEdit::Edit( GraphicObject* pGraphicObject )
//Create a thread
- // Create the data that is needed by the thread later
- osl_createThread(ExternalToolEdit::threadWorker, this);
+ 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
+ && (HINT_MODELCLEARED == pSdrHint->GetKind()
+ || (pSdrHint->GetObject() == m_pObj
+ && HINT_OBJREMOVED == pSdrHint->GetKind())))
+ {
+ m_pView = 0;
+ m_pObj = 0;
+ 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: */