[Ktutorial-commits] SF.net SVN: ktutorial:[230] trunk/ktutorial/ktutorial-editor
Status: Alpha
Brought to you by:
danxuliu
From: <dan...@us...> - 2010-04-13 20:11:13
|
Revision: 230 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=230&view=rev Author: danxuliu Date: 2010-04-13 20:11:06 +0000 (Tue, 13 Apr 2010) Log Message: ----------- Add initial version of target application module to interact with the KTutorial editor support module in applications using KTutorial. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/targetapplication/ trunk/ktutorial/ktutorial-editor/src/targetapplication/CMakeLists.txt trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.cpp trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.h trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.cpp trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.h trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.cpp trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.h trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.cpp trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.h trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.cpp trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.h trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.cpp trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.h trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/ trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DBusExceptionTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DummyApplication.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/RemoteClassStubs.h trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/RemoteEditorSupportTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/RemoteEventSpyTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/RemoteObjectMapperTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/RemoteObjectTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/TargetApplicationStub.cpp trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/TargetApplicationTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-04-13 18:49:12 UTC (rev 229) +++ trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-04-13 20:11:06 UTC (rev 230) @@ -9,6 +9,11 @@ add_subdirectory(serialization) add_subdirectory(view) +if (QT_QTDBUS_FOUND) + add_definitions(-DQT_QTDBUS_FOUND) + add_subdirectory(targetapplication) +endif (QT_QTDBUS_FOUND) + set(ktutorial_editor_SRCS EditActions.cpp Exception.cpp @@ -28,6 +33,11 @@ ktutorial_editor_view ) +if (QT_QTDBUS_FOUND) + target_link_libraries(ktutorial_editor ktutorial_editor_targetapplication) +endif (QT_QTDBUS_FOUND) + + kde4_add_executable(ktutorial-editor main.cpp) target_link_libraries(ktutorial-editor ktutorial_editor) Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/CMakeLists.txt 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,12 @@ +set(ktutorial_editor_targetapplication_SRCS + DBusException.cpp + RemoteEditorSupport.cpp + RemoteEventSpy.cpp + RemoteObject.cpp + RemoteObjectMapper.cpp + TargetApplication.cpp +) + +kde4_add_library(ktutorial_editor_targetapplication ${ktutorial_editor_targetapplication_SRCS}) + +target_link_libraries(ktutorial_editor_targetapplication ktutorial_editor ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS}) Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/CMakeLists.txt ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "DBusException.h" + +//public: + +DBusException::DBusException(const QString& message): Exception(message) { +} + +DBusException::~DBusException() throw() { +} Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.h 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef DBUSEXCEPTION_H +#define DBUSEXCEPTION_H + +#include "../Exception.h" + +/** + * Thrown when a DBus error happened. + */ +class DBusException: public Exception { +public: + + explicit DBusException(const QString& message = QString()); + virtual ~DBusException() throw(); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/DBusException.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "RemoteEditorSupport.h" + +#include <QDBusReply> + +#include "RemoteEventSpy.h" +#include "RemoteObject.h" +#include "RemoteObjectMapper.h" + +//public: + +RemoteEditorSupport::RemoteEditorSupport(const QString& service, + RemoteObjectMapper* mapper): + QDBusAbstractInterface(service, "/ktutorial", + "org.kde.ktutorial.EditorSupport", + QDBusConnection::sessionBus(), 0), + mMapper(mapper), + mRemoteEventSpy(0) { +} + +RemoteEditorSupport::~RemoteEditorSupport() { + delete mRemoteEventSpy; +} + +RemoteObject* RemoteEditorSupport::mainWindow() throw (DBusException) { + QDBusReply<int> reply = call("mainWindowObjectId"); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } + + return mMapper->remoteObject(reply.value()); +} + +void RemoteEditorSupport::highlight(RemoteObject* remoteWidget) + throw (DBusException) { + QDBusReply<void> reply = call("highlight", remoteWidget->objectId()); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } +} + +void RemoteEditorSupport::stopHighlighting(RemoteObject* remoteWidget) + throw (DBusException) { + QDBusReply<void> reply = call("stopHighlighting", remoteWidget->objectId()); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } +} + +RemoteEventSpy* RemoteEditorSupport::enableEventSpy() throw (DBusException) { + if (mRemoteEventSpy) { + return mRemoteEventSpy; + } + + QDBusReply<void> reply = call("enableEventSpy"); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } + + mRemoteEventSpy = new RemoteEventSpy(service(), mMapper); + return mRemoteEventSpy; +} + +void RemoteEditorSupport::disableEventSpy() throw (DBusException) { + if (!mRemoteEventSpy) { + return; + } + + QDBusReply<void> reply = call("disableEventSpy"); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } + + delete mRemoteEventSpy; + mRemoteEventSpy = 0; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.h 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef REMOTEEDITORSUPPORT_H +#define REMOTEEDITORSUPPORT_H + +#include <QDBusAbstractInterface> + +#include "DBusException.h" + +class RemoteEventSpy; +class RemoteObject; +class RemoteObjectMapper; + +/** + * Proxy for the remote EditorSupport exposed by KTutorial editor support module + * in KTutorial library. + * RemoteEditorSupport represents a remote EditorSupport exposed through DBus. + * Its purpose is provide an API to use the remote EditorSupport like any other + * local object, hiding the DBus complexity behind it. + * + * RemoteEditorSupport makes DBus calls to "org.kde.ktutorial.EditorSupport" + * interface in the DBus service specified in the constructor. + * + * Although the idea is let other objects use it like a local object, it has to + * communicate with the remote EditorSupport through DBus anyway, so the methods + * may throw a DBusException if something goes wrong. + */ +class RemoteEditorSupport: public QDBusAbstractInterface { +Q_OBJECT +public: + + /** + * Creates a new RemoteEditorSupport to represent a remote EditorSupport in + * the given DBus service. + * + * @param service The DBus service name. + * @param mapper The RemoteObjectMapper to get RemoteObjects from. + */ + RemoteEditorSupport(const QString& service, RemoteObjectMapper* mapper); + + /** + * Destroys this RemoteEditorSupport. + * The RemoteEventSpy is also destroyed, if any. + */ + virtual ~RemoteEditorSupport(); + + /** + * Returns the RemoteObject that represents the main window of the + * application. + * + * @return The RemoteObject for the main window. + * @throws DBusException If a DBus error happens. + */ + RemoteObject* mainWindow() throw (DBusException); + + /** + * Highlights the widget represented by the given remote object. + * If the object does not represent a widget nothing is highlighted. + * + * @param remoteWidget The RemoteObject for the widget to highlight. + * @throws DBusException If a DBus error happens. + */ + void highlight(RemoteObject* remoteWidget) throw (DBusException); + + /** + * Stops highlighting the widget represented by the given remote object. + * If the object does not represent a widget no highlighting is stopped. + * + * @param remoteWidget The RemoteObject for the widget to stop highlighting. + * @throws DBusException If a DBus error happens. + */ + void stopHighlighting(RemoteObject* remoteWidget) throw (DBusException); + + /** + * Enables the EventSpy in the remote EditorSupport and returns a proxy for + * it. + * If the EventSpy was already enabled, the already created proxy is + * returned again. + * The RemoteEventSpy is destroyed when the EventSpy is disabled or this + * RemoteEditorSupport destroyed, so consider using QPointer to store it. + * + * @return A proxy for the remote EventSpy. + * @throws DBusException If a DBus error happens. + */ + RemoteEventSpy* enableEventSpy() throw (DBusException); + + /** + * Disables the EventSpy in the remote EditorSupport and destroys the proxy + * for it. + * + * @throws DBusException If a DBus error happens. + */ + void disableEventSpy() throw (DBusException); + +private: + + /** + * The mapper that associates a RemoteObject with its object id. + */ + RemoteObjectMapper* mMapper; + + /** + * The RemoteEventSpy, if enabled. + */ + RemoteEventSpy* mRemoteEventSpy; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEditorSupport.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "RemoteEventSpy.h" + +#include <QDBusInterface> + +#include "RemoteObjectMapper.h" + +//public: + +RemoteEventSpy::RemoteEventSpy(const QString& service, + RemoteObjectMapper* mapper): QObject(), + mMapper(mapper) { + + //RemoteEventSpy class can not inherit from QDBusInterface as that breaks + //the "magic" done by QDbusInterface (it redefines qt_metacall and things + //like that) and signals can not be connected so easily + QDBusInterface* interface = new QDBusInterface( + service, "/ktutorial/EventSpy", "org.kde.ktutorial.EventSpy", + QDBusConnection::sessionBus(), this); + connect(interface, SIGNAL(eventReceived(int, QString)), + this, SLOT(handleEventReceived(int, QString))); +} + +//private: + +void RemoteEventSpy::handleEventReceived(int objectId, + const QString& eventType) { + emit eventReceived(mMapper->remoteObject(objectId), eventType); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.h 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef REMOTEEVENTSPY_H +#define REMOTEEVENTSPY_H + +#include <QObject> + +class RemoteObject; +class RemoteObjectMapper; + +/** + * Proxy for the remote EventSpy exposed by KTutorial editor support module in + * KTutorial library. + * RemoteEventSpy represents a remote EventSpy exposed through DBus. Its purpose + * is provide an API to use the remote EventSpy like any other local object, + * hiding the DBus complexity behind it. + * + * RemoteEventSpy handles the eventReceived signal emitted by + * "org.kde.ktutorial.EventSpy" interface in the DBus service specified in the + * constructor and emits an equivalent signal replacing the object id with a + * RemoteObject proxy. + */ +class RemoteEventSpy: public QObject { +Q_OBJECT +public: + + /** + * Creates a new RemoteEventSpy to represent a remote EventSpy in the given + * DBus service. + * + * @param service The DBus service name. + * @param mapper The RemoteObjectMapper to get RemoteObjects from. + */ + RemoteEventSpy(const QString& service, RemoteObjectMapper* mapper); + +Q_SIGNALS: + + /** + * Emitted when the remote object receives an event. + * + * @param remoteObject The proxy for the real remote object. + * @param eventType The type of the event received. + */ + void eventReceived(RemoteObject* remoteObject, const QString& eventType); + +private: + + /** + * The mapper that associates a RemoteObject with its object id. + */ + RemoteObjectMapper* mMapper; + +private Q_SLOTS: + + /** + * Handles an event reception notified by the EventSpy. + * + * @param objectId The id of the remote object that received the event. + * @param eventType The type of the event received. + */ + void handleEventReceived(int objectId, const QString& eventType); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteEventSpy.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "RemoteObject.h" + +#include <QtDBus/QtDBus> + +#include "RemoteObjectMapper.h" + +//public: + +RemoteObject::RemoteObject(const QString& service, RemoteObjectMapper* mapper, + int objectId): + QDBusAbstractInterface(service, "/ktutorial/ObjectRegister", + "org.kde.ktutorial.ObjectRegister", + QDBusConnection::sessionBus(), 0), + mMapper(mapper), + mObjectId(objectId) { +} + +int RemoteObject::objectId() const { + return mObjectId; +} + +QString RemoteObject::name() throw (DBusException) { + QDBusReply<QString> reply = call("objectName", mObjectId); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } + + return reply.value(); +} + +QString RemoteObject::className() throw (DBusException) { + QDBusReply<QString> reply = call("className", mObjectId); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } + + return reply.value(); +} + +Q_DECLARE_METATYPE(QList<int>) + +QList<RemoteObject*> RemoteObject::children() throw (DBusException) { + qDBusRegisterMetaType< QList<int> >(); + + QDBusReply< QList<int> > reply = call("childObjectIds", mObjectId); + if (!reply.isValid()) { + throw DBusException(reply.error().message()); + } + + QList<RemoteObject*> children; + foreach (int childObjectId, reply.value()) { + children.append(mMapper->remoteObject(childObjectId)); + } + + return children; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.h 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef REMOTEOBJECT_H +#define REMOTEOBJECT_H + +#include <QDBusAbstractInterface> + +#include "DBusException.h" + +class RemoteObjectMapper; + +/** + * Proxy for remote objects exposed by KTutorial editor support module in + * KTutorial library. + * RemoteObject represents a remote object exposed by ObjectRegister in + * KTutorial library through DBus. Its purpose is provide an API to use the + * remote object like any other local object, hiding the DBus complexity behind + * it. + * + * To get the data, RemoteObject makes DBus calls to the + * "org.kde.ktutorial.ObjectRegistry" interface in the DBus service specified in + * the constructor. + * + * Although the idea is let other objects use it like a local object, it has to + * communicate with the remote ObjectRegistry through DBus anyway, so the + * methods may throw a DBusException if something goes wrong. + */ +class RemoteObject: public QDBusAbstractInterface { +Q_OBJECT +public: + + /** + * Creates a new RemoteObject to represent the remote object with the given + * id in the given DBus service name. + * + * @param service The DBus service name. + * @param mapper The RemoteObjectMapper to get RemoteObjects from. + * @param objectId The id of the remote object. + */ + RemoteObject(const QString& service, RemoteObjectMapper* mapper, + int objectId); + + /** + * Returns the id of the remote object. + * + * @return The id of the remote object. + */ + int objectId() const; + + /** + * Returns the object name. + * + * @return The object name. + * @throws DBusException If a DBus error happens. + */ + QString name() throw (DBusException); + + /** + * Returns the class name. + * + * @return The class name. + * @throws DBusException If a DBus error happens. + */ + QString className() throw (DBusException); + + /** + * Returns a list with the RemoteObjects that represent the children of this + * remote object. + * + * @return The child remote objects. + * @throws DBusException If a DBus error happens. + */ + QList<RemoteObject*> children() throw (DBusException); + +private: + + /** + * The mapper that associates a RemoteObject with its object id. + */ + RemoteObjectMapper* mMapper; + + /** + * The id of the remote object. + */ + int mObjectId; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObject.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "RemoteObjectMapper.h" + +#include <QHash> + +#include "RemoteObject.h" + +//public: + +RemoteObjectMapper::RemoteObjectMapper(const QString& service): + mService(service) { +} + +RemoteObjectMapper::~RemoteObjectMapper() { + qDeleteAll(mRemoteObjects); +} + +RemoteObject* RemoteObjectMapper::remoteObject(int objectId) { + if (mRemoteObjects.contains(objectId)) { + return mRemoteObjects.value(objectId); + } + + RemoteObject* remoteObject = new RemoteObject(mService, this, objectId); + mRemoteObjects.insert(objectId, remoteObject); + + return remoteObject; +} + +void RemoteObjectMapper::clear() { + qDeleteAll(mRemoteObjects); + mRemoteObjects.clear(); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.h 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef REMOTEOBJECTMAPPER_H +#define REMOTEOBJECTMAPPER_H + +#include <QHash> + +class RemoteObject; + +/** + * Map to get a RemoteObject from their objectId. + * The RemoteObjectMapper should be used to get all the RemoteObjects for its + * DBus service. It creates a new RemoteObject when there is no RemoteObject + * for the given id, or returns the previosly created one, depending on the + * case. + * + * The RemoteObjectMapper also has ownership of the RemoteObjects, so they are + * deleted when the mapper is cleared or destroyed. + */ +class RemoteObjectMapper { +public: + + /** + * Creates a new RemoteObjectMapper for the given DBus service name. + * + * @param service The DBus service name of the remote objects. + */ + RemoteObjectMapper(const QString& service); + + /** + * Destroys this RemoteObjectMapper. + * All the mapped RemoteObjects are also destroyed. + */ + ~RemoteObjectMapper(); + + /** + * Returns the RemoteObject associated with the given object id. + * The RemoteObject is destroyed when this RemoteObjectMapper is cleared or + * destroyed, so consider using QPointer to store it. + * + * @param objectId The id of the remote object. + * @return The RemoteObject. + */ + RemoteObject* remoteObject(int objectId); + + /** + * Destroys all the mapped RemoteObject. + */ + void clear(); + +private: + + /** + * The DBus service name of the remote objects. + */ + QString mService; + + /** + * All the RemoteObjects already requested since the last time this + * RemoteObjectMapper was cleared. + */ + QHash<int, RemoteObject*> mRemoteObjects; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/RemoteObjectMapper.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,174 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "TargetApplication.h" + +#include <QtDBus/QtDBus> + +#include <KProcess> +#include <KUrl> + +#include "RemoteEditorSupport.h" +#include "RemoteObjectMapper.h" + +//public: + +TargetApplication* TargetApplication::self() { + return sSelf; +} + +TargetApplication::~TargetApplication() { + if (mProcess) { + mProcess->kill(); + mProcess->waitForFinished(100); + } +} + +QString TargetApplication::targetApplicationFilePath() const { + return mTargetApplicationFilePath; +} + +void TargetApplication::setTargetApplicationFilePath( + const QString& targetApplicationFilePath) { + KUrl url(targetApplicationFilePath); + url.cleanPath(); + + if (url.isRelative()) { + mTargetApplicationFilePath = ""; + } else { + mTargetApplicationFilePath = url.toLocalFile(); + } +} + +RemoteEditorSupport* TargetApplication::remoteEditorSupport() { + return mRemoteEditorSupport; +} + +void TargetApplication::start() { + if (mProcess && mProcess->program()[0] == mTargetApplicationFilePath) { + return; + } + + if (!QDBusConnection::sessionBus().isConnected()) { + emit startFailed(NoDBusConnection); + return; + } + + if (mProcess) { + mProcess->kill(); + //Don't start the new target application until the old one is dead. + //It may freeze the editor GUI, but it is unlikely that a process gets + //enough time being killed to be noticed + mProcess->waitForFinished(-1); + } + + mProcess = new KProcess(this); + mProcess->setProgram(mTargetApplicationFilePath); + + mServiceName.clear(); + + QDBusConnectionInterface* interface = + QDBusConnection::sessionBus().interface(); + connect(interface, SIGNAL(serviceRegistered(QString)), + this, SLOT(checkNewService(QString))); + connect(interface, SIGNAL(serviceOwnerChanged(QString, QString, QString)), + this, SLOT(checkNewService(QString))); + + connect(mProcess, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(handleProcessError(QProcess::ProcessError))); + + connect(mProcess, SIGNAL(finished(int)), + this, SLOT(clean())); + + mServiceDiscoveryTimer.setInterval(3000); + mServiceDiscoveryTimer.setSingleShot(true); + connect(mProcess, SIGNAL(started()), + &mServiceDiscoveryTimer, SLOT(start())); + connect(&mServiceDiscoveryTimer, SIGNAL(timeout()), + this, SLOT(handleTargetApplicationDoesNotSupportKTutorial())); + + mProcess->start(); +} + +//private: + +TargetApplication* TargetApplication::sSelf = new TargetApplication(); + +TargetApplication::TargetApplication(): + mProcess(0), + mMapper(0), + mRemoteEditorSupport(0) { +} + +//private slots: + +void TargetApplication::checkNewService(const QString& service) { + QDBusInterface interface(service, "/ktutorial", + "org.kde.ktutorial.EditorSupport"); + if (!interface.isValid()) { + return; + } + + QDBusReply<QString> reply = interface.call("applicationFilePath"); + if (!reply.isValid()) { + return; + } + + if (reply.value() != mTargetApplicationFilePath) { + return; + } + + mServiceDiscoveryTimer.stop(); + + mServiceName = service; + mMapper = new RemoteObjectMapper(mServiceName); + mRemoteEditorSupport = new RemoteEditorSupport(mServiceName, mMapper); + + emit started(); + + disconnect(QDBusConnection::sessionBus().interface(), 0, this, 0); +} + +void TargetApplication::handleProcessError(QProcess::ProcessError error) { + if (error != QProcess::FailedToStart) { + return; + } + + mServiceDiscoveryTimer.stop(); + + emit startFailed(InvalidPath); +} + +void TargetApplication::handleTargetApplicationDoesNotSupportKTutorial() { + mProcess->kill(); + + emit startFailed(InvalidApplication); +} + +void TargetApplication::clean() { + //Don't delete it directly, as waitForFinished crashes somewhere internally + //due to an event problem + mProcess->deleteLater(); + mProcess = 0; + delete mRemoteEditorSupport; + mRemoteEditorSupport = 0; + delete mMapper; + mMapper = 0; + + emit finished(); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.h 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,238 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef TARGETAPPLICATION_H +#define TARGETAPPLICATION_H + +#include <QObject> +#include <QProcess> +#include <QTimer> + +class KProcess; +class RemoteEditorSupport; +class RemoteObjectMapper; + +/** + * Class to execute a target application and communicate with it through D-Bus. + * The target application is the application that the tutorial will be part of. + * Using TargetApplication class a new instance of a target application can be + * executed and, through D-Bus, KTutorial editor can communicate with it to + * introspect its structure. The target application must have KTutorial enabled + * in order to use the KTutorial editor support module. Applications that do not + * use KTutorial can not be introspected. + * + * Knowing the structure of the target application, KTutorial editor can provide + * valuable information to the tutorial author like the name of an object or its + * class, so the tutorial author can design the tutorial more easily. + * + * The TargetApplication can be started using method start(). The method returns + * immediately, and when the application is really running the started() signal + * is emitted. If the application could not be executed, or it was executed but + * other problem happened (for example, if the target application does not + * support KTutorial), startFailed(Error) signal is emitted instead. + * + * Once the target application has been started, remoteEditorSupport + * returns a RemoteEditorSupport connected to the remote + * "org.kde.ktutorial.EditorSupport" interface exposed by the target + * application. + * + * The target application will be killed when the TargetApplication is + * destroyed, or when the start method is called again after setting a different + * application file path. In any of those cases, or if the target application + * was closed externally (by the user), finished() signal is emitted. + */ +class TargetApplication: public QObject { +Q_OBJECT +public: + + /** + * The type of error that made starting the target application fail. + */ + enum Error { + + /** + * The application was started, but it does not support KTutorial. + */ + InvalidApplication, + + /** + * The application was not even started. + */ + InvalidPath, + + /** + * The application was started, but there is no D-Bus connection to + * communicate with it. + */ + NoDBusConnection + }; + + /** + * Returns the only instance of TargetApplication class. + * + * @return The TargetApplication instance. + */ + static TargetApplication* self(); + + /** + * Destroys this TargetApplication. + * If the target application is running, it is killed. + */ + virtual ~TargetApplication(); + + /** + * Returns the executable for the target application. + * + * @return The target application file path. + */ + QString targetApplicationFilePath() const; + + /** + * Sets the executable for the target application. + * The executable must be an absolute path. A relative path will be set as + * an empty string. If the path is absolute but contains "." and ".." + * components they are resolved and the clean path is set. + * + * @param applicationFilePath The target application file path. + */ + void setTargetApplicationFilePath(const QString& targetApplicationFilePath); + + /** + * Returns the RemoteEditorSupport for the target application. + * If the application is not running a null pointer is returned. + * + * @return The RemoteEditorSupport for the target application. + */ + RemoteEditorSupport* remoteEditorSupport(); + + /** + * Starts a new TargetApplication. + * When the target application is running, started() signal is emitted. If + * there is no application file path, the application file path is not valid + * or the application does not support KTutorial editor, startFailed(Error) + * signal is emitted instead. + * + * If the target application was already started nothing is done (even + * started() signal is not emitted). + */ + void start(); + +Q_SIGNALS: + + /** + * Emitted when the target application was started and there is a D-Bus + * connection to it. + */ + void started(); + + /** + * Emitted when the target application could not be started successfully. + * + * @param error The type of error that happened. + */ + void startFailed(TargetApplication::Error error); + + /** + * Emitted when the target application was finished for any reason. + */ + void finished(); + +private: + + /** + * The only instance of TargetApplication. + */ + static TargetApplication* sSelf; + + /** + * The executable for the target application. + */ + QString mTargetApplicationFilePath; + + /** + * The process executing the target application, if any. + */ + KProcess* mProcess; + + /** + * Timer to give time to "/ktutorial" object to appear in some new service + * of the bus. + * If the timer ends and the object was not found, the target application + * seems to not to support KTutorial editor. + */ + QTimer mServiceDiscoveryTimer; + + /** + * The D-Bus service name provided by the target application, if any. + */ + QString mServiceName; + + /** + * The mapper that associates RemoteObjects with their object id. + */ + RemoteObjectMapper* mMapper; + + /** + * The RemoteEditorSupport for the target application, if any. + */ + RemoteEditorSupport* mRemoteEditorSupport; + + /** + * Creats a new TargetApplication. + * Hidden to avoid classes other than TargetApplication itself to create + * objects of it. + */ + TargetApplication(); + +private Q_SLOTS: + + /** + * Checks if the new service found in the session bus is the one from the + * started target application. + * When the service is found, the target application has started from + * KTutorial editor point of view. Signal started() is emitted in that case. + * + * @param service The D-Bus service to check. + */ + void checkNewService(const QString& service); + + /** + * Checks if the process could not be started. + * Signal startFailed(Error), with InvalidPath, is emitted in that case. + * + * @param error The process error. + */ + void handleProcessError(QProcess::ProcessError error); + + /** + * Called when the time out to find the D-Bus service expired. + * Signal startFailed(Error), with InvalidApplication, is emitted in that + * case. + */ + void handleTargetApplicationDoesNotSupportKTutorial(); + + /** + * Called when the process has finished. + * The process, mapper and remote editor support are deleted, and the + * finished() signal is emitted. + */ + void clean(); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/targetapplication/TargetApplication.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-04-13 18:49:12 UTC (rev 229) +++ trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-04-13 20:11:06 UTC (rev 230) @@ -1,6 +1,9 @@ add_subdirectory(commands) add_subdirectory(data) add_subdirectory(serialization) +if (QT_QTDBUS_FOUND) + add_subdirectory(targetapplication) +endif (QT_QTDBUS_FOUND) add_subdirectory(view) # Used by kde4_add_unit_test to set the full path to test executables Added: trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/CMakeLists.txt 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,47 @@ +# Used by kde4_add_unit_test to set the full path to test executables +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${ktutorial-editor_SOURCE_DIR}/src/targetapplication ${KDE4_INCLUDES}) + +# Remote class stubs are QObjects, so moc files have to be generated for them +qt4_wrap_cpp(dbus_interface_stubs_MOC RemoteClassStubs.h) + +# Dummy application to be executed in TargetApplication test +add_executable(DummyApplication DummyApplication.cpp) +target_link_libraries(DummyApplication ${KDE4_KDEUI_LIBS} ${QT_QTDBUS_LIBRARY}) + +# Target application stub to be executed in TargetApplication test +add_executable(TargetApplicationStub TargetApplicationStub.cpp ${dbus_interface_stubs_MOC}) +target_link_libraries(TargetApplicationStub ${KDE4_KDEUI_LIBS} ${QT_QTDBUS_LIBRARY}) + +MACRO(UNIT_TESTS) + FOREACH(_className ${ARGN}) + set(_testName ${_className}Test) + kde4_add_unit_test(${_testName} TESTNAME ktutorial-editor-unit-${_testName} ${_testName}.cpp ${dbus_interface_stubs_MOC}) + target_link_libraries(${_testName} ktutorial_editor_targetapplication ${QT_QTTEST_LIBRARY}) + ENDFOREACH(_className) +ENDMACRO(UNIT_TESTS) + +unit_tests( + DBusException + RemoteEditorSupport + RemoteEventSpy + RemoteObject + RemoteObjectMapper + TargetApplication +) + +MACRO(MEM_TESTS) + FOREACH(_testname ${ARGN}) + add_test(ktutorial-editor-unit-mem-${_testname} ${CMAKE_CURRENT_SOURCE_DIR}/../runMemcheck.py ${CMAKE_CURRENT_BINARY_DIR}/${_testname}Test ${CMAKE_CURRENT_BINARY_DIR}) + ENDFOREACH(_testname) +ENDMACRO(MEM_TESTS) + +mem_tests( + DBusException + RemoteEditorSupport + RemoteEventSpy + RemoteObject + RemoteObjectMapper + TargetApplication +) Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/CMakeLists.txt ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DBusExceptionTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DBusExceptionTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DBusExceptionTest.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include <QtTest> + +#include "DBusException.h" + +class DBusExceptionTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + void testConstructorEmpty(); + +}; + +void DBusExceptionTest::testConstructor() { + DBusException exception(QString("The message")); + + QCOMPARE(exception.what(), "The message"); + QCOMPARE(exception.message(), QString("The message")); +} + +void DBusExceptionTest::testConstructorEmpty() { + DBusException exception; + + QCOMPARE(exception.what(), ""); + QCOMPARE(exception.message(), QString("")); +} + +QTEST_MAIN(DBusExceptionTest) + +#include "DBusExceptionTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DBusExceptionTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DummyApplication.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DummyApplication.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/targetapplication/DummyApplication.cpp 2010-04-13 20:11:06 UTC (rev 230) @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2010 by Daniel Calviño Sánchez * + * dan...@gm... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License a... [truncated message content] |