Home · All Classes · Annotated · Functions

Qtopia Data Linking (QDL)

Introduction

Qtopia Data Linking (QDL) provides an API to associate data items across applications. A QDLLink is conceptually the same as an ordinary anchor on a webpage or as information which uniquely references an object in the same application, or another Qtopia application. When the user clicks the link the referenced object is accessed. For example, using QDL a user can create a meeting event in Calendar and a link to each person attending the meeting from Contacts. When the event is viewed, hypertext links appear for each linked contact. Activating a link sends a message to the Contacts application to display that contact.

How it Works

The linking process begins when the user edits a QDL enabled text field. These text fields are called the client in QDL and interface through an associated QDLWidgetClient object for QDL operations.

The user selects an Insert Link context menu option in the text field which is connected to the QDLClient::requestLink() slot. This displays a dialog listing all applications providing a QDL service, known as QDL sources. The user then selects an application which contains the data they wish to link to.

QDLClient::requestLink() then sends a request for links over QCop to the selected source. Typically, the source application will present the user with a list of items available for linking and the user then selects the desired items from the list. However, the source may carry out any specific processing required to determine the set of links.

Once a source has determined the items to be linked it creates links for all of the items and sends them back to the client. The client receives the links and inserts them into the text.

Links are edited and viewed as hypertext anchors. The links work like links on a standard webpage - clicking them accesses the object they refer to.

Enable Linking in a Text Field

To enable linking from a text field, create a QDLWidgetClient with the text field as its parent, for example:

        QTextEdit *notesTE = new QTextEdit( parent );
        QDLWidgetClient *notesWC = new QDLWidgetClient( notesTE );
    #ifdef QTOPIA_PHONE
        //setup a standard context menu item on phone
        notesWC->setupStandardContextMenu();
    #endif

QDLWidgetClient::setupStandardContextMenu() automatically creates an Insert Link menu item and connects it to QDLWidgetClient::requestLink().

Load and Save Links

Links in QDL are commonly stored in PimRecord custom fields. However, overloaded QDataStream insertion and extraction operators are provided for a QList of QDLClients to permit links to be stored in a user-defined location.

For example: the following loads all links from a PimRecord rec into all QDL clients that are children of parent.

        QDL::loadLinks( rec.customField( QDL::DATA_KEY ), QDL::clients( parent ) );

Saving links is exactly the same, except QDL::saveLinks() is called.

Display and Activate Links

The following describes the method used to display and activate links.

  1. Load the links stored in the PimRecord rec.
               QDLClient *client = new QDLClient( 0 );
               QDL::loadLinks( rec.customField( QDL::DATA_KEY ), client );
    
               // Display the links, and when finished cleanup by deleting the QDLClient
               ...
    
               delete client;

    Note: The base class QDLClient is used instead of the subclass QDLWidgetClient. Unlike QDLWidgetClient, QDLClient is a standalone object for handling links.

  2. Activate a link.

Enable an Application to be a QDL Source

A source is a Qtopia application that provides the QDL Service and responds to particular QCop messages. The two messages a source must respond to are:

When enabling an application as a QDL source, the application must exist as part of the QDL Qtopia Service. See Qtopia Services for more information.

For QDLActivateLink the only argument is the data reference to activate.

For QDLRequestLink(QString,QString) the first argument is a unique identifier used when responding to the client's request, and the second argument is a hint for which links the user might be interested in (eg. the start of a person's name).

The source responds to the client with the QCop message QDLProvideLink(QString,int,...) where the first QString argument is the identifier sent in the request, the second int argument is the number of QDLLinks being sent, and the third variable length parameter is a series of QDLLink objects. Responses to a client are sent on the QCop channel specified by QDL::CLIENT_CHANNEL .

These messages should be handled by inheriting the QDLService class. The following is an example of the typical handling of these messages:

    class MyApplicationQdlService : public QDLService
    {
        Q_OBJECT

    public:
        MyApplicationQdlService( QObject *parent = 0 ) : QDLService( parent ) {};
        ~MyApplicationQdlService() {};

    public slots:
        void activateLink( const QByteArray& dataRef );
        void requestLinks( const QString& id, const QString& hint );

    signals:
        void qdlActivateLink( const QByteArray& dataRef );
        void qdlRequestLinks( const QString& id, const QString& hint );
    };

    void MyApplicationQdlService::activateLink( const QByteArray& dataRef )
    {
        emit( qdlActivateLink( dataRef ) );
    }

    void MyApplicationQdlService::requestLinks( const QString& id, const QString& hint )
    {
        emit( qdlRequestLinks( id, hint ) );
    }


    class MyApplication : public QMainWindow
    {
        Q_OBJECT

        ...

    public slots:

        ...

        void qdlActivateLink( const QByteArray& dataRef );
        void qdlRequestLinks( const QString& id, const QString& hint );

        ...

    private:

        ...
        MyApplicationQdlService* qdlService;
    };

    void MyApplication::someInitializationMethod()
    {
        ...

        qdlService = new MyApplicationQdlService(this);
        connect( qdlService,
                 SIGNAL( qdlActivateLink( const QByteArray& ) ),
                 this,
                 SLOT( qdlActivateLink( const QByteArray& ) ) );
        connect( qdlService,
                 SIGNAL( qdlRequestLinks( const QString&, const QString& ) ),
                 this,
                 SLOT( qdlRequestLinks( const QString& , const QString& ) ) );

        ...
    }

    void MyApplication::qdlRequestLinks( const QString& clientID, const QString& hint )
    {
        QDLHeartBeat hb( clientID ); //sends keep alive messages to the client

        MyDataSelector *selDlg = new MyDataSelector( (isVisible() ? this : 0 ) );
        selDlg->setFilter( hint );
        if( QtopiaApplication::execDialog( selDlg ) )
        {
            //User selected items to link to. Create the link data from them
            QList<MyData> selectedItems = selDlg->selected();
            QList<QDLLink> links;
            QList<MyData>::Iterator it;
            for( it = selectedItems.begin() ; it != selectedItems().end() ; ++it )
            {
                QByteArray dataRef;
                QDataStream refStream( dataRef, IO_WriteOnly );
                refStream << (*it).uid().toString(); // a unique reference to this data item
                links.push_back( QDLLink( "myapplication", dataRef, (*it).name(), "MyAppIcon") );
            }

            // Send the selected links back to the client
            QCopEnvelope e( QDL::CLIENT_CHANNEL, "QDL::provideLinks(QString,QList<QDLLink>)" );
            e << clientID;
            e << links;
        }

        delete selDlg;
    }

    void MyApplication::qdlActivateLink( const QByteArray& dataRef )
    {
        QDataStream refStream( dataRef );
        QString dataRefStr;
        refStream >> dataRefStr;
        displayItem( dataRefStr );//display the item specified by the dataRef
    }

See also QDL, QDLLink, QDLClient, QDLService, and QDLHeartBeat.


Copyright © 2006 Trolltech Trademarks
Qtopia 4.1.7