Home · All Classes · Main Classes · Deprecated |
Application extensions are plug-ins that can be embedded into an application extension area. They can be run either in the same process as the application or a separate process in the application extension runner. An application extension can optionally have a UI.
To develop application extensions, you need:
From the developer's point of view, an application extension consists of a shared library, a desktop entry file, and possibly resources (such as images). All the contents are packaged into a Debian package so that the application extensions can be installed to devices.
An application extension is implemented as a Qt plug-in. It is recommended that the shared library name should include the related application and the extension name (for example, libmyapplication-myextension.so). The interface class used as the base class of all application extensions is MApplicationExtensionInterface
. The interface provides a method for initialising the plug-in, which must be implemented by the application extension:
bool MApplicationExtensionInterface::initialize(const QString &interface)
The extension gets the name of the interface as a parameter. The extension can use this information, but does not need it for any purpose. The boolean return value should indicate whether the initialisation was successful or not.
The interface also has a method for returning the widget used for the UI of the application extension:
QGraphicsWidget *widget()
In this method you need to return a pointer to the QGraphicsWidget
of your application extension. In case a UI is not required, this method can be left out. Note: The ownership of the QGraphicsWidget
is left to the application extension, so you should destroy the widget yourself in the destructor of the extension.
To use application extensions of a particular interface in an application, an instance of MApplicationExtensionArea
is created:
new MApplicationExtensionArea(interface, parent);
where interface refers to the interface implemented by the extensions in the area and parent is the parent QGraphicsItem. The area is only populated after init() is called.
Note: To be able to dynamically type cast from MApplicationExtensionInterface to a interface subclass implemented in extension, "-Wl,-E" flags are needed in executables linker flags ('QMAKE_LFLAGS += -Wl,-E'), see GCC faq about dynamic cast and shared libs
To define which extensions can be loaded in the same process as the extension area and which extensions run in separate processes, use setInProcessFilter() and setOutOfProcessFilter() before calling init(). Since these methods take QRegExp objects as their parameter, you can, for example, use QRegExp("$^") to allow no extensions, QRegExp("/test(1|A).desktop$") to allow extensions test1.desktop and testA.desktop and QRegExp() to allow all extensions.
Application extensions and applications that use them are developed differently depending on whether they are run in-process or out-of-process.
In-process extensions:
Out-of-process extensions:
// demoextensioninterface.h #ifndef DEMOEXTENSIONINTERFACE_H #define DEMOEXTENSIONINTERFACE_H #include <mapplicationextensioninterface.h> class DemoExtensionInterface : public MApplicationExtensionInterface { Q_INTERFACES(MApplicationExtensionInterface) public: virtual void demoExtensionSpecificOperation() = 0; }; Q_DECLARE_INTERFACE(DemoExtensionInterface, "com.meego.DemoExtensionInterface/1.0") #endif
// demoextension.h #ifndef DEMOEXTENSION_H_ #define DEMOEXTENSION_H_ #include <QObject> #include <MApplicationExtensionInterface> class MButton; class DemoApplicationExtension : public QObject, public DemoExtensionInterface { Q_OBJECT Q_INTERFACES(DemoExtensionInterface MApplicationExtensionInterface) public: DemoApplicationExtension(); virtual ~DemoApplicationExtension(); virtual void demoExtensionSpecificOperation(); virtual bool initialize(const QString &interface); virtual MWidget *widget(); private: MButton *button; }; #endif
Note: The Q_INTERFACES list must include both the demo-specific interface DemoExtensionInterface and the base interface MApplicationExtensionInterface.
// demoextension.cpp #include <MButton> #include "demoextension.h" #include <MLibrary> M_LIBRARY Q_EXPORT_PLUGIN2(demoextension, DemoApplicationExtension) DemoApplicationExtension::DemoApplicationExtension() : button(0) { } DemoApplicationExtension::~DemoApplicationExtension() { delete button; } void DemoApplicationExtension::demoExtensionSpecificOperation() { // do something specific to the demo extension interface } bool DemoApplicationExtension::initialize(const QString &) { button = new MButton("Hello World"); return true; } MWidget *DemoApplicationExtension::widget() { return button; }
In an application that wants to use the extensions implementing the com.meego.DemoExtensionInterface/1.0 defined above, the application should create the following application extension area:
//demoapp.pro
...
TEMPLATE = app
QMAKE_LFLAGS = -Wl,-E,--as-needed
...
#include <MApplicationExtensionArea> #include <demoextensioninterface.h> ... void DemoApp::createExtensionArea() { MApplicationExtensionArea *extensionArea = new MApplicationExtensionArea("com.meego.DemoApplicationExtensionInterface/1.0"); extensionArea->setInProcessFilter(QRegExp("/demoapp-demoextension2?\\.desktop$")); extensionArea->init(); layout->addItem(extensionArea); // Listen to signals about new and removed extensions connect(area, SIGNAL(extensionInstantiated(MApplicationExtensionInterface*)), this, SLOT(addExtension(MApplicationExtensionInterface*))); connect(area, SIGNAL(extensionRemoved(MApplicationExtensionInterface*)), this, SLOT(removeExtension(MApplicationExtensionInterface*))); } void DemoApp::addExtension(MApplicationExtensionInterface *extension) { DemoExtensionInterface *demoExtension = dynamic_cast<DemoExtensionInterface *>(extension); if (demoExtension) { // do some extension interface specific things with the extension demoExtension->demoExtensionSpecificOperation(); } } ...
Application extension must have a .desktop file written according to freedesktop.org desktop entry specification. It is recommended to name the file in a similar manner as the shared library (for example, myapplication-myextension.desktop). The keys
Type
and Name
are required as specified in the desktop entry specification. The type must be X-MeeGoApplicationExtension
. The Exec
key is optionally used to specify a runner binary (usually mapplicationextensionrunner) which is launched in a separate process to run the application extension binary. If the key is not used, the application extension runs inside the host process.
Application extensions extend the specification by defining a new type MApplicationExtension and the following new keys which are placed into the X-MeeGoApplicationExtension group:
Key | Description | Value Type | Required |
---|---|---|---|
Interface | Defines the name of the interface implemented by this extension. | string | YES |
Extension | Defines the application extension binary. This binary needs to be located in the directory /usr/lib/meegotouch/applicationextensions/ . | string | YES |
Identifier | Defines an identifier for the application extension. The identifier is used, for example, for defining the application extension specific style resource locations when the extension is run out-of-process. | string (can contain characters [a-zA-Z0-9_-]) | NO |
The following example illustrates an application extension desktop file:
[Desktop Entry] Type=X-MeeGoApplicationExtension Name=ExampleExtension Exec=mapplicationextensionrunner [X-MeeGoApplicationExtension] Interface=com.meego.DemoExtensionInterface/1.0 Extension=libdemoapplication-demoextension.so
Application extension widgets are reparented to an MContainer by default. MContainer can include optional application extension information on its title bar, such as icon, title and additional informative text. If you do not want an application extension to reside in a container, set the container-mode property of the application extension area to false:
MApplicationExtensionAreaStyle { container-mode: false; }
Use following properties and signals in your application extension widget class to provide container information:
Q_PROPERTY(QString applicationExtensionIcon READ icon WRITE setIcon) Q_PROPERTY(QString applicationExtensionTitle READ title WRITE setTitle) Q_PROPERTY(QString applicationExtensionText READ text WRITE setText) signals: // change icon in MContainer void applicationExtensionIconChanged(QString newIcon); // change title in MContainer void applicationExtensionTitleChanged(QString newTitle); // change additional text in MContainer void applicationExtensionTextChanged(QString newText);
The property and signal names must be as stated above. The property access function names can differ.
Every application extension has an application extension identifier string that uniquely identifies the application extension.
The application extension identifier is determined like this:
Identifier
) is specified in the X-MeeGoApplicationExtension
group of the Application extension desktop file desktop file (and it is valid), that is usedlibexampleapplicationextension.so
, the identifier is exampleapplicationextension.Application extensions can define their own styles just like any other application in the MeeGo Touch world.
Styling is done with style sheets and images in the usual way. The only important thing with application extensions is the location of the style resources.
When the application extension is run out-of-process, the resource location is constructed from the application extension identifier. The application extension identifier is used as the application name in the directory name.
When the application extension is run in-process, the resource location is constructed from the library name.
For more information about the directory locations, see Theme directory structure.
You can modify the layout orientation of the application extension area with the layout-orientation style parameter:
MApplicationExtensionAreaStyle { layout-orientation: horizontal; }
The meegotouch-dev-tools
package includes a tool called mapplicationextensiontester
. This tool can be used to test application extensions that have an UI. The tool loads application extensions implementing a specified interface to a window where you can interact with it and visually check the results. It is also easy to run the extension in a debugger with this tool.
To load an application extension with the tool, use the following command:
mapplicationextensiontester <interfacename>
where <interfacename> is the interface that the loaded extensions must implement.
Note that the application extensions must be installed to the system before mapplicationextensiontester
can use them.
Copyright © 2010 Nokia Corporation | MeeGo Touch |