Basic openoffice.org control, and listening for new presentation documents, still...
[kworship.git] / unipresent / openoffice.org / UpOoBackend.cpp
blob02820e01e24b2459e0a11d73e9056a969acfec34
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 /**
21 * @file UpOoBackend.cpp
22 * @brief OpenOffice.org presentation manager.
23 * @author James Hogan <james@albanarts.com>
26 #include "UpOoBackend.h"
27 #include "UpOoBridge.h"
28 #include "UpOoPresentation.h"
30 #include "compiler.h"
32 #include <KRun>
33 #include <KShell>
34 #include <KLocale>
35 #include <KGenericFactory>
37 #include <QThread>
39 #include <osl/file.hxx>
40 #include <osl/process.h>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/container/XEnumeration.hpp>
43 #include <com/sun/star/container/XEnumerationAccess.hpp>
44 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
45 #include <com/sun/star/document/XDocumentEventListener.hpp>
46 #include <com/sun/star/frame/XComponentLoader.hpp>
47 #include <com/sun/star/frame/XDesktop.hpp>
48 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
49 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
50 #include <com/sun/star/uno/XComponentContext.hpp>
51 #include <cppuhelper/implbase1.hxx>
53 using namespace com::sun::star::beans;
54 using namespace com::sun::star::container;
55 using namespace com::sun::star::document;
56 using namespace com::sun::star::frame;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::presentation;
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star;
61 using namespace rtl;
63 K_EXPORT_COMPONENT_FACTORY( unipresent_openoffice, KGenericFactory<UpOoBackend>("unipresent_openoffice") )
66 * Types
69 class UpOoBackend::DocumentEventListener : public ::cppu::WeakImplHelper1<XDocumentEventListener>
71 public:
73 * Constructors + destructor
76 /// Primary constructor.
77 DocumentEventListener(UpOoBackend* backend, const Reference<XDocumentEventBroadcaster>& broadcaster)
78 : m_backend(backend)
79 , m_broadcaster(broadcaster)
81 kdDebug() << __PRETTY_FUNCTION__;
84 /// Virtual destructor.
85 ~DocumentEventListener()
87 kdDebug() << __PRETTY_FUNCTION__;
88 if (m_broadcaster.is())
90 Reference<XDocumentEventListener> xRefListener = static_cast<XDocumentEventListener*>(this);
91 m_broadcaster->removeDocumentEventListener(xRefListener);
96 * Virtual functions
99 /// Main document event handler.
100 virtual void SAL_CALL documentEventOccured(const DocumentEvent& event)
101 throw(RuntimeException)
103 // Only handle new documents
104 // NOTE: OnCreate and OnLoadFinished can be used before the presentation is made visible
105 // OnNew and OnLoad are only after the presentation is made visible
106 if (event.EventName.equalsAscii("OnNew") ||
107 event.EventName.equalsAscii("OnLoad"))
109 // Specifically, only presentations
110 Reference<XPresentationSupplier> presentationDoc(event.Source, UNO_QUERY);
111 if (presentationDoc.is())
113 UpOoPresentation* newPresentation = new UpOoPresentation(presentationDoc.get(), m_backend);
114 m_backend->m_presentations.push_back(newPresentation);
115 emit m_backend->loadedPresentation(newPresentation);
120 /// Handle disposing.
121 virtual void SAL_CALL disposing(const lang::EventObject& event)
122 throw(RuntimeException)
124 kdDebug() << __PRETTY_FUNCTION__ << &event;
125 /// @todo check this behaviour is correct, is it the broadcaster that is being disposed of?
126 m_broadcaster = 0;
129 private:
131 * Variables
134 /// Backend object.
135 UpOoBackend* m_backend;
137 /// Broadcaster that this listener is registered with.
138 Reference<XDocumentEventBroadcaster> m_broadcaster;
142 * Constructors + destructor
145 /// Primary constructor.
146 UpOoBackend::UpOoBackend(QObject* parent, const QStringList& params)
147 : UpBackend(parent, params)
148 , m_bridge(0)
149 , m_globalDocumentEventListener()
150 , m_presentations()
152 updatePresentations();
155 /// Destructor.
156 UpOoBackend::~UpOoBackend()
158 delete m_bridge;
162 * General meta information
165 QString UpOoBackend::id() const
167 return "OpenOffice.org";
170 QString UpOoBackend::name() const
172 return i18n("OpenOffice.org");
175 QString UpOoBackend::description() const
177 return i18n("Controls a running OpenOffice.org presentation");
180 QStringList UpOoBackend::mimeTypes() const
182 /// @todo Find mime types from open office if possible
183 return QStringList()
184 << "application/vnd.oasis.opendocument.presentation"
188 QIcon UpOoBackend::icon() const
190 return QIcon();
194 * Activation
197 bool UpOoBackend::isActive()
199 /// @todo Gently try again
200 return (0 != m_bridge);
203 bool UpOoBackend::activate()
205 int tries = 0;
206 while (0 == m_bridge)
208 m_bridge = new UpOoBridge();
209 if (m_bridge->isValid())
211 activated();
213 updatePresentations();
214 return true;
216 else
218 delete m_bridge;
219 m_bridge = 0;
221 ++tries;
222 if (tries == 1)
224 // First try : start OpenOffice.org
225 bool starting = KRun::runCommand("openoffice.org " + KShell::quoteArg("-accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager"), 0);
226 if (!starting)
228 return false;
231 else if (tries > 10)
233 // Second try + : give up
234 return false;
236 /// @todo PORT
237 usleep(500000);
241 return (0 != m_bridge);
244 void UpOoBackend::deactivate()
246 if (0 != m_bridge)
248 delete m_bridge;
249 m_bridge = 0;
250 deactivated();
255 * Presentation management
258 QList<UpPresentation*> UpOoBackend::presentations()
260 return m_presentations;
263 bool UpOoBackend::openPresentation(const QUrl& url)
265 OUString urlString = OUString::createFromAscii(url.toString().toAscii());
267 if (activate())
269 Reference<XPropertySet> propertySet(m_bridge->serviceManager(), UNO_QUERY);
270 Reference<XComponentContext> componentContext;
271 propertySet->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= componentContext;
272 Reference<XMultiComponentFactory> componentFactoryServer = componentContext->getServiceManager();
274 Reference<XComponentLoader> componentLoader(componentFactoryServer->createInstanceWithContext(OUString::createFromAscii("com.sun.star.frame.Desktop"), componentContext), UNO_QUERY);
276 Reference<XComponent> newComponent = componentLoader->loadComponentFromURL(urlString, OUString::createFromAscii("_blank"), 0, Sequence< ::com::sun::star::beans::PropertyValue>() );
278 return true;
280 else
282 return false;
287 * Other interfaces
290 /// Update the list of presentations
291 void UpOoBackend::updatePresentations()
293 if (0 == m_bridge)
295 m_bridge = new UpOoBridge();
296 if (!m_bridge->isValid())
298 delete m_bridge;
299 m_bridge = 0;
303 if (0 != m_bridge && m_presentations.isEmpty())
305 // Find open documents.
306 Reference<XPropertySet> propertySet(m_bridge->serviceManager(), UNO_QUERY);
307 Reference<XComponentContext> componentContext;
308 propertySet->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= componentContext;
309 Reference<XMultiComponentFactory> componentFactoryServer = componentContext->getServiceManager();
311 Reference<XDesktop> desktop(componentFactoryServer->createInstanceWithContext(OUString::createFromAscii("com.sun.star.frame.Desktop"), componentContext), UNO_QUERY);
312 Reference<XEnumeration> documents = desktop->getComponents()->createEnumeration();
314 while (documents->hasMoreElements())
316 Reference<XPresentationSupplier> presentationSupplier;
317 documents->nextElement() >>= presentationSupplier;
318 if (0 != presentationSupplier.get())
320 m_presentations.push_back(new UpOoPresentation(presentationSupplier.get(), this));
324 // Add listener to global document events
325 Reference<XDocumentEventBroadcaster> broadcaster(componentFactoryServer->createInstanceWithContext(OUString::createFromAscii("com.sun.star.frame.GlobalEventBroadcaster"), componentContext), UNO_QUERY);
326 m_globalDocumentEventListener = new DocumentEventListener(this, broadcaster);
327 Reference<XDocumentEventListener> xRefListener = static_cast<XDocumentEventListener*>(m_globalDocumentEventListener.get());
328 broadcaster->addDocumentEventListener(xRefListener);