summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2015-01-16 23:56:09 +0100
committerMichael Stahl <mstahl@redhat.com>2015-01-17 01:03:30 +0100
commit5f6bdce0c0ac687f418821ce328f2987bf340cda (patch)
treee59f769e234d5feee4a54d60f8c2ac9e1a21f920 /svx
parent3b70717f02d5f2f255de078bd277e8662884bfb0 (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...) Change-Id: I35f187f0828097a05618dc1733dce819fc6bffc6
Diffstat (limited to 'svx')
-rw-r--r--svx/source/core/extedit.cxx97
1 files changed, 78 insertions, 19 deletions
diff --git a/svx/source/core/extedit.cxx b/svx/source/core/extedit.cxx
index 83cbbec6fcfb..7cc8b5f70211 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>
@@ -33,7 +39,6 @@ using namespace css::uno;
using namespace css::system;
ExternalToolEdit::ExternalToolEdit()
- : m_pGraphicObject(NULL)
{
}
@@ -56,35 +61,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
{
- osl_setThreadName("ExternalToolEdit");
+private:
+ OUString const m_aFileName;
- ExternalToolEdit* pData = (ExternalToolEdit*) pThreadData;
+ 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
@@ -117,8 +127,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: */