Qtopia Home - Classes - Hierachy - Annotated - Functions - Qt Embedded |

# Qtopia Data Linking (QDL)

- Introduction
- How it works
  - Enabling linking in a text field
  - Loading and saving links
  - Displaying and activating links
  - Enabling an application to be a QDL source

## Introduction

Qtopia Data Linking (QDL) provides an API for applications to link to each other's data. With QDL, a user may create a meeting event in the Calendar (Datebook) program and then link to each person that will be attending the meeting from their Contacts (Addressbook) application. Whenever the newly created event is viewed, hypertext links appear for each Contact that was linked and activating a link sends a message to the Contacts application to display that contact. A link is simply a reference to some data in an application.

## How it works

Data Linking begins with a text field widget such as a QLineEdit or QMultiLineEdit which has been enabled for linking. In QDL, this field is called the 'client' and it is represented by the class QDLWidgetClient.

From the client, the user is able to select an 'Insert Link' context menu option. This in turn launches a dialog which lists all the applications that provide a QDL service. The user chooses the application that has the data to which they would like to create a link. In QDL, this application is called the 'source'.

The client then sends a request for links to the selected source by calling QDLClient::requestLink(). Typically, the source application will present the user with a list of things to which they can create links, and the user selects the relevant items. Alternately, the source may carry out the 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.

The inserted links are displayed in the editing mode as superscript numbers to the right of a description for the link. These numbers are called link identifiers (LIDs). They act as markers to inform the user that the text to the left is internally marked as a link and is therefore special.

When the user actually views text containing links the link identifier markers are replaced with hypertext anchors. The links then effectively work like links on a standard webpage: when clicked/activated, they take you to whatever they reference.

### Enabling linking in a text field

To enable linking from a text field, you create a QDLWidgetClient with the text field as its parent.

        QMultiLineEdit *notesME = new QMultiLineEdit( parent );
        QDLWidgetClient *notesWC = new QDLWidgetClient( notesME, "qdlNotes" );
        //setup a standard context menu
        notesWC->setupStandardContextMenu();

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

### Loading and saving links

Most commonly, links in QDL are stored in PimRecord custom fields. However, in order that links for a set of clients can be stored anywhere, overloaded QDataStream insertion and extraction operators are provided for a QList of QDLClients.

Demonstrating the common case, the following would load 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 is exactly the same, except you call QDL::saveLinks().

For more information about the convenient loading and saving functions, see General QDL Usage .

### Displaying and activating links

The following code converts the superscript link identifiers in txt based on the links stored in rec.

        QDLClient *client = new QDLClient( 0, "qdlNotes" );
        QDL::loadLinks( rec.customField( QDL::DATA_KEY ), client );
        txt = QDL::lidsToAnchors( txt, client );
        delete client;

Note that the base class QDLClient was used instead of the subclass QDLWidgetClient. Unlike QDLWidgetClient, QDLClient is a stand-alone object for handling links.

To activate a link, you must have the href text for the link (eg the argument from QTextBrowser::setSource() ) and any QDLClient object that could potentially own the available link. Simply pass the href text and the QDLClient objects to QDL::activateLink() .

    MyTextBrowser::setSource( const QString &ahref )
    {
        QDL::activateLink( ahref, QDL::clients( this ) );
    }

### Enabling 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:

- QDLRequestLink(QString,QString)
- QDLActivateLink(QByteArray)

When enabling your application to be a QDL source, you must ensure that your application exists as part of the QDL Qtopia Service. See Services for more information.

For QDLRequestLink(QString,QString) the first argument is a unique ID that is used when responding to a communication from the client, and the second argument is a hint of the links in which the user is interested (eg. the start of someone's name.). The source responds to the client with the QCop message QDLProvideLink(QString,int...) where the first QString argument is the ID sent in the request, the second int argument is the number of QDLLinks being sent, and the third variable length parameter is the actual QDLLink object. Responses to a client are sent on the QCop channel specified by QDL::CLIENT_CHANNEL .

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

These messages should be handled in response to the QPEApplication::appMessage() signal. The following is an example of the typical handling of these messages:

    void MyApplication::appMessage( const QCString &msg, const QByteArray &data )
    {
        QDataStream stream( data );
        if( msg == "QDLRequestLink(QString,QString)" )
        {
            QCString clientID;
            QString hint;
            stream >> clientID >> hint;

            QDLHeartBeat hb( clientID ); //sends keep alive messages to the client

            MyDataSelector *selDlg = new MyDataSelector( (isVisible() ? this : 0 ) );
            selDlg->setFilter( hint );
            if( QPEApplication::execDialog( selDlg ) )
            {
                //User selected items to link to. Create the link data from
                //them and send it all back to the client.
                QCopEnvelope e( QDL::CLIENT_CHANNEL, "QDLProvideLink(QString,int,...)" );
                QValueList<MyData> selectedItems = selDlg->selected();
                e << selectedItems.count(); //how many links we have
                QValueList<MyData>::Iterator it;
                for( it = selectedItems.begin() ; it != selectedItems().end() ; ++it )
                {
                    QByteArray dataRef;
                    QDataStream refStream( dataRef, IO_WriteOnly );
                    refStream << (*it).uid().toString();
                    QDLLink newLink("myapplication", dataRef, (*it).name(), "MyAppIcon");
                    e << newLink;
                }
            }
            delete selDlg;
        }
        else if( msg == "QDLActivateLink(QByteArray)" )
        {
            QByteArray dataRef;
            stream >> dataRef;
            QDataStream refStream( dataRef, IO_ReadOnly );
            QString dataRefStr;
            refStream >> dataRefStr;
            displayItem( dataRefStr );//display the item specified by the dataRef
        }

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