dbus/qt/examples .cvsignore, NONE, 1.1 Makefile.am, NONE, 1.1 chat.cpp, NONE, 1.1 chat.h, NONE, 1.1 chatadaptor.cpp, NONE, 1.1 chatadaptor.h, NONE, 1.1 chatmainwindow.ui, NONE, 1.1 chatsetnickname.ui, NONE, 1.1 com.trolltech.ChatInterface.xml, NONE, 1.1 complexping.cpp, NONE, 1.1 complexping.h, NONE, 1.1 complexpong.cpp, NONE, 1.1 complexpong.h, NONE, 1.1 dbus.cpp, NONE, 1.1 hello.cpp, NONE, 1.1 ping-common.h, NONE, 1.1 ping.cpp, NONE, 1.1 pong.cpp, NONE, 1.1 pong.h, NONE, 1.1

Thiago J. Macieira thiago at kemper.freedesktop.org
Tue Mar 28 11:16:37 PST 2006


Update of /cvs/dbus/dbus/qt/examples
In directory kemper:/tmp/cvs-serv25972/qt/examples

Added Files:
	.cvsignore Makefile.am chat.cpp chat.h chatadaptor.cpp 
	chatadaptor.h chatmainwindow.ui chatsetnickname.ui 
	com.trolltech.ChatInterface.xml complexping.cpp complexping.h 
	complexpong.cpp complexpong.h dbus.cpp hello.cpp ping-common.h 
	ping.cpp pong.cpp pong.h 
Log Message:
	* configure.in qt/Makefile.am: add qt/examples
	* qt/examples: Add QtDBus example programs:
	  - hello: Hello, World
	  - ping: Simple method-calling program
	  - pong: Simple object-exporting program (not using adaptors)
	  - complexping: Interactive method-calling program 
		(also gets and sets properties).
	  - complexpong: Sample program exporting methods, signals and
		properties, using adaptors.
	  - dbus: Simple implementation of a generic method-calling
		program, similar to 'dbus-send', but with semantics
		similar to 'dcop'.
	  - chat: Simplistic chat program, implemented using signals
		and the system bus. Looks like IRC.


--- NEW FILE: .cvsignore ---
.deps
.libs
Makefile
Makefile.in
*.lo
*.la
*.bb
*.bbg
*.da
*.gcov
*.moc

--- NEW FILE: Makefile.am ---
if HAVE_QT
INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_QT_CFLAGS) -DDBUS_COMPILATION
LDADD = ../libdbus-qt4-1.la

if HAVE_QT_GUI
chat_LDADD = $(LDADD) $(DBUS_QT_GUI_LIBS)
dist_chat_SOURCES = chat.cpp chat.h chatadaptor.cpp
nodist_chat_SOURCES = chatinterface.cpp
chat.o: chatmainwindow.h chatsetnickname.h chatinterface.h chatadaptor.h chat.moc chatadaptor.moc
chatmainwindow.h: chatmainwindow.ui
chatsetnickname.h: chatsetnickname.ui
chatinterface.cpp chatinterface.h: com.trolltech.ChatInterface.xml
	../dbusidl2cpp -m -p chatinterface $?
	$(QT_MOC) -o chatinterface.moc chatinterface.h

CHAT=chat
endif


noinst_PROGRAMS = hello dbus ping pong complexping complexpong $(CHAT)
hello_SOURCES = hello.cpp
dbus_SOURCES = dbus.cpp

ping_SOURCES = ping.cpp
pong_SOURCES = pong.cpp pong.h
pong.o: pong.moc

complexping_SOURCES = complexping.cpp complexping.h
complexpong_SOURCES = complexpong.cpp complexpong.h
complexpong.o: complexpong.moc
complexping.o: complexping.moc

EXTRA_DIST = ping-common.h chatmainwindow.ui chatsetnickname.ui com.trolltech.ChatInterface.xml chatadaptor.h

CLEANFILES = chat.moc chatadaptor.moc complexping.moc complexpong.moc pong.moc \
	chatinterface.cpp chatinterface.h chatinterface.moc \
	chatmainwindow.h chatsetnickname.h

%.moc: %.h
	$(QT_MOC) $< > $@
%.h: %.ui
	$(QT_UIC) -o $@ $?
endif


--- NEW FILE: chat.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include "chat.h"
#include <QtGui/QApplication>
#include <QtGui/QMessageBox>

#include "chatadaptor.h"
#include "chatinterface.h"

ChatMainWindow::ChatMainWindow()
    : m_nickname(QLatin1String("nickname"))
{
    setupUi(this);
    sendButton->setEnabled(false);

    connect(messageLineEdit, SIGNAL(textChanged(QString)),
            this, SLOT(textChangedSlot(QString)));
    connect(sendButton, SIGNAL(clicked(bool)), this, SLOT(sendClickedSlot()));
    connect(actionChangeNickname, SIGNAL(triggered(bool)), this, SLOT(changeNickname()));
    connect(actionAboutQt, SIGNAL(triggered(bool)), this, SLOT(aboutQt()));
    connect(qApp, SIGNAL(lastWindowClosed()), this, SLOT(exiting()));

    // add our D-Bus interface and connect to D-Bus
    new ChatInterfaceAdaptor(this);
    QDBus::systemBus().registerObject("/", this);

    com::trolltech::ChatInterface *iface;
    iface = QDBus::systemBus().findInterface<com::trolltech::ChatInterface>(QString(), QString());
    connect(iface, SIGNAL(message(QString,QString)), this, SLOT(messageSlot(QString,QString)));
    connect(iface, SIGNAL(action(QString,QString)), this, SLOT(actionSlot(QString,QString)));

    NicknameDialog dialog;
    dialog.cancelButton->setVisible(false);
    dialog.exec();
    m_nickname = dialog.nickname->text().trimmed();
    emit action(m_nickname, QLatin1String("joins the chat"));
}

ChatMainWindow::~ChatMainWindow()
{
}

void ChatMainWindow::rebuildHistory()
{
    QString history = m_messages.join( QLatin1String("\n" ) );
    chatHistory->setPlainText(history);
}

void ChatMainWindow::messageSlot(const QString &nickname, const QString &text)
{
    QString msg( QLatin1String("<%1> %2") );
    msg = msg.arg(nickname, text);
    m_messages.append(msg);

    if (m_messages.count() > 100)
        m_messages.removeFirst();
    rebuildHistory();
}

void ChatMainWindow::actionSlot(const QString &nickname, const QString &text)
{
    QString msg( QLatin1String("* %1 %2") );
    msg = msg.arg(nickname, text);
    m_messages.append(msg);

    if (m_messages.count() > 100)
        m_messages.removeFirst();
    rebuildHistory();
}

void ChatMainWindow::textChangedSlot(const QString &newText)
{
    sendButton->setEnabled(!newText.isEmpty());
}

void ChatMainWindow::sendClickedSlot()
{
    emit message(m_nickname, messageLineEdit->text());
    messageLineEdit->setText(QString());
}

void ChatMainWindow::changeNickname()
{
    NicknameDialog dialog(this);
    if (dialog.exec() == QDialog::Accepted) {
        QString old = m_nickname;
        m_nickname = dialog.nickname->text().trimmed();
        emit action(old, QString("is now known as %1").arg(m_nickname));
    }
}

void ChatMainWindow::aboutQt()
{
    QMessageBox::aboutQt(this);
}

void ChatMainWindow::exiting()
{
    emit action(m_nickname, QLatin1String("leaves the chat"));
}

NicknameDialog::NicknameDialog(QWidget *parent)
    : QDialog(parent)
{
    setupUi(this);
}

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    ChatMainWindow chat;
    chat.show();
    return app.exec();
}

#include "chat.moc"

--- NEW FILE: chat.h ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef CHAT_H
#define CHAT_H

#include <QtCore/QStringList>
#include <dbus/qdbus.h>
#include "chatmainwindow.h"
#include "chatsetnickname.h"

class ChatMainWindow: public QMainWindow, Ui::ChatMainWindow
{
    Q_OBJECT
    QString m_nickname;
    QStringList m_messages;
public:
    ChatMainWindow();
    ~ChatMainWindow();

    void rebuildHistory();

signals:
    void message(const QString &nickname, const QString &text);
    void action(const QString &nickname, const QString &text);

private slots:
    void messageSlot(const QString &nickname, const QString &text);
    void actionSlot(const QString &nickname, const QString &text);
    void textChangedSlot(const QString &newText);
    void sendClickedSlot();
    void changeNickname();
    void aboutQt();
    void exiting();
};

class NicknameDialog: public QDialog, public Ui::NicknameDialog
{
    Q_OBJECT
public:
    NicknameDialog(QWidget *parent = 0);
};

#endif

--- NEW FILE: chatadaptor.cpp ---
/*
 * This file was generated by dbusidl2cpp version 0.3
 * when processing input file /home/tjmaciei/src/kde4/playground/libs/qt-dbus/examples/com.trolltech.ChatInterface.xml
 *
 * dbusidl2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved.
 *
 * This is an auto-generated file.
 */

#include "chatadaptor.h"
#include <QtCore/QMetaObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>

/*
 * Implementation of adaptor class ChatInterfaceAdaptor
 */

ChatInterfaceAdaptor::ChatInterfaceAdaptor(QObject *parent)
   : QDBusAbstractAdaptor(parent)
{
    // constructor
    setAutoRelaySignals(true);
}

ChatInterfaceAdaptor::~ChatInterfaceAdaptor()
{
    // destructor
}


#include "chatadaptor.moc"

--- NEW FILE: chatadaptor.h ---
/*
 * This file was generated by dbusidl2cpp version 0.3
 * when processing input file /home/tjmaciei/src/kde4/playground/libs/qt-dbus/examples/com.trolltech.ChatInterface.xml
 *
 * dbusidl2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved.
 *
 * This is an auto-generated file.
 */

#ifndef CHATADAPTOR_H_88051142890130
#define CHATADAPTOR_H_88051142890130

#include <QtCore/QObject>
#include <dbus/qdbus.h>
class QByteArray;
template<class T> class QList;
template<class Key, class Value> class QMap;
class QString;
class QStringList;
class QVariant;

/*
 * Adaptor class for interface com.trolltech.ChatInterface
 */
class ChatInterfaceAdaptor: public QDBusAbstractAdaptor
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.trolltech.ChatInterface")
public:
    ChatInterfaceAdaptor(QObject *parent);
    virtual ~ChatInterfaceAdaptor();

public: // PROPERTIES
public slots: // METHODS
signals: // SIGNALS
    void action(const QString &nickname, const QString &text);
    void message(const QString &nickname, const QString &text);
};

#endif

--- NEW FILE: chatmainwindow.ui ---
<ui version="4.0" >
 <author></author>
 <comment></comment>
 <exportmacro></exportmacro>
 <class>ChatMainWindow</class>
 <widget class="QMainWindow" name="ChatMainWindow" >
  <property name="geometry" >
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle" >
   <string>QtDBus Chat</string>
  </property>
  <widget class="QWidget" name="centralwidget" >
   <layout class="QHBoxLayout" >
    <property name="margin" >
     <number>9</number>
    </property>
    <property name="spacing" >
     <number>6</number>
    </property>
    <item>
     <layout class="QVBoxLayout" >
      <property name="margin" >
       <number>0</number>
      </property>
      <property name="spacing" >
       <number>6</number>
      </property>
      <item>
       <widget class="QTextBrowser" name="chatHistory" >
        <property name="acceptDrops" >
         <bool>false</bool>
        </property>
        <property name="toolTip" >
         <string>Messages sent and received from other users</string>
        </property>
        <property name="acceptRichText" >
         <bool>true</bool>
        </property>
       </widget>
      </item>
      <item>
       <layout class="QHBoxLayout" >
        <property name="margin" >
         <number>0</number>
        </property>
        <property name="spacing" >
         <number>6</number>
        </property>
        <item>
         <widget class="QLabel" name="label" >
          <property name="text" >
           <string>Message:</string>
          </property>
          <property name="buddy" >
           <cstring>messageLineEdit</cstring>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QLineEdit" name="messageLineEdit" />
        </item>
        <item>
         <widget class="QPushButton" name="sendButton" >
          <property name="sizePolicy" >
           <sizepolicy>
            <hsizetype>1</hsizetype>
            <vsizetype>0</vsizetype>
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="toolTip" >
           <string>Sends a message to other people</string>
          </property>
          <property name="whatsThis" >
           <string/>
          </property>
          <property name="text" >
           <string>Send</string>
          </property>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar" >
   <property name="geometry" >
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>31</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuQuit" >
    <property name="title" >
     <string>Help</string>
    </property>
    <addaction name="actionAboutQt" />
   </widget>
   <widget class="QMenu" name="menuFile" >
    <property name="title" >
     <string>File</string>
    </property>
    <addaction name="actionChangeNickname" />
    <addaction name="separator" />
    <addaction name="actionQuit" />
   </widget>
   <addaction name="menuFile" />
   <addaction name="menuQuit" />
  </widget>
  <widget class="QStatusBar" name="statusbar" />
  <action name="actionQuit" >
   <property name="text" >
    <string>Quit</string>
   </property>
   <property name="shortcut" >
    <string>Ctrl+Q</string>
   </property>
  </action>
  <action name="actionAboutQt" >
   <property name="icon" >
    <iconset/>
   </property>
   <property name="text" >
    <string>About Qt...</string>
   </property>
  </action>
  <action name="actionChangeNickname" >
   <property name="text" >
    <string>Change nickname...</string>
   </property>
   <property name="shortcut" >
    <string>Ctrl+N</string>
   </property>
  </action>
 </widget>
 <pixmapfunction></pixmapfunction>
 <tabstops>
  <tabstop>chatHistory</tabstop>
  <tabstop>messageLineEdit</tabstop>
  <tabstop>sendButton</tabstop>
 </tabstops>
 <resources/>
 <connections>
  <connection>
   <sender>messageLineEdit</sender>
   <signal>returnPressed()</signal>
   <receiver>sendButton</receiver>
   <slot>animateClick()</slot>
   <hints>
    <hint type="sourcelabel" >
     <x>299</x>
     <y>554</y>
    </hint>
    <hint type="destinationlabel" >
     <x>744</x>
     <y>551</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>actionQuit</sender>
   <signal>triggered(bool)</signal>
   <receiver>ChatMainWindow</receiver>
   <slot>close()</slot>
   <hints>
    <hint type="sourcelabel" >
     <x>-1</x>
     <y>-1</y>
    </hint>
    <hint type="destinationlabel" >
     <x>399</x>
     <y>299</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

--- NEW FILE: chatsetnickname.ui ---
<ui version="4.0" >
 <author></author>
 <comment></comment>
 <exportmacro></exportmacro>
 <class>NicknameDialog</class>
 <widget class="QDialog" name="NicknameDialog" >
  <property name="geometry" >
   <rect>
    <x>0</x>
    <y>0</y>
    <width>396</width>
    <height>105</height>
   </rect>
  </property>
  <property name="sizePolicy" >
   <sizepolicy>
    <hsizetype>1</hsizetype>
    <vsizetype>1</vsizetype>
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="windowTitle" >
   <string>Set nickname</string>
  </property>
  <layout class="QVBoxLayout" >
   <property name="margin" >
    <number>9</number>
   </property>
   <property name="spacing" >
    <number>6</number>
   </property>
   <item>
    <layout class="QVBoxLayout" >
     <property name="margin" >
      <number>0</number>
     </property>
     <property name="spacing" >
      <number>6</number>
     </property>
     <item>
      <widget class="QLabel" name="label" >
       <property name="sizePolicy" >
        <sizepolicy>
         <hsizetype>1</hsizetype>
         <vsizetype>1</vsizetype>
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text" >
        <string>New nickname:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLineEdit" name="nickname" />
     </item>
    </layout>
   </item>
   <item>
    <layout class="QHBoxLayout" >
     <property name="margin" >
      <number>0</number>
     </property>
     <property name="spacing" >
      <number>6</number>
     </property>
     <item>
      <spacer>
       <property name="orientation" >
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" >
        <size>
         <width>131</width>
         <height>31</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="okButton" >
       <property name="text" >
        <string>OK</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="cancelButton" >
       <property name="text" >
        <string>Cancel</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer>
       <property name="orientation" >
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" >
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <pixmapfunction></pixmapfunction>
 <resources/>
 <connections>
  <connection>
   <sender>okButton</sender>
   <signal>clicked()</signal>
   <receiver>NicknameDialog</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel" >
     <x>278</x>
     <y>253</y>
    </hint>
    <hint type="destinationlabel" >
     <x>96</x>
     <y>254</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>cancelButton</sender>
   <signal>clicked()</signal>
   <receiver>NicknameDialog</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel" >
     <x>369</x>
     <y>253</y>
    </hint>
    <hint type="destinationlabel" >
     <x>179</x>
     <y>282</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

--- NEW FILE: com.trolltech.ChatInterface.xml ---
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="com.trolltech.ChatInterface">
    <signal name="message">
      <arg name="nickname" type="s" direction="out"/>
      <arg name="text" type="s" direction="out"/>
    </signal>
    <signal name="action">
      <arg name="nickname" type="s" direction="out"/>
      <arg name="text" type="s" direction="out"/>
    </signal>
  </interface>
</node>


--- NEW FILE: complexping.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <stdio.h>

#include <dbus/qdbus.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QDebug>
#include <QtCore/QProcess>

#include "ping-common.h"
#include "complexping.h"

void Ping::start(const QString &name, const QString &oldValue, const QString &newValue)
{
    Q_UNUSED(oldValue);

    if (name != SERVICE_NAME || newValue.isEmpty())
        return;

    // open stdin for reading
    qstdin.open(stdin, QIODevice::ReadOnly);

    // find our remote
    iface = QDBus::sessionBus().findInterface(SERVICE_NAME, "/");
    if (!iface) {
        fprintf(stderr, "%s\n",
                qPrintable(QDBus::sessionBus().lastError().message()));
        QCoreApplication::instance()->quit();
    }

    connect(iface, SIGNAL(aboutToQuit()), QCoreApplication::instance(), SLOT(quit()));

    while (true) {
        qDebug() << "Ready";

        QString line = QString::fromLocal8Bit(qstdin.readLine()).trimmed();
        if (line.isEmpty()) {
            iface->call("quit");
            return;
        } else if (line == "value") {
            QVariant reply = iface->property("value");
            if (!reply.isNull())
                qDebug() << "value =" << reply.toString();
        } else if (line.startsWith("value=")) {
            iface->setProperty("value", line.mid(6));            
        } else {
            QDBusReply<QVariant> reply = iface->call("query", line);
            if (reply.isSuccess())
                qDebug() << "Reply was:" << reply.value();
        }

        if (iface->lastError().isValid())
            fprintf(stderr, "Call failed: %s\n", qPrintable(iface->lastError().message()));
    }
}    

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    Ping ping;
    ping.connect(QDBus::sessionBus().busService(),
                 SIGNAL(nameOwnerChanged(QString,QString,QString)),
                 SLOT(start(QString,QString,QString)));

    QProcess pong;
    pong.start("./complexpong");

    app.exec();
}

#include "complexping.moc"

--- NEW FILE: complexping.h ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef COMPLEXPING_H
#define COMPLEXPING_H

#include <QtCore/QObject>

class Ping: public QObject
{
    Q_OBJECT
public slots:
    void start(const QString &, const QString &, const QString &);
public:
    QFile qstdin;
    QDBusInterface *iface;
};

#endif

--- NEW FILE: complexpong.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <stdio.h>

#include <dbus/qdbus.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>

#include "ping-common.h"
#include "complexpong.h"

// the property
QString Pong::value() const
{
    return m_value;
}

void Pong::setValue(const QString &newValue)
{
    m_value = newValue;
}

void Pong::quit()
{
    QTimer::singleShot(0, QCoreApplication::instance(), SLOT(quit()));
}

QVariant Pong::query(const QString &query)
{
    QString q = query.toLower();
    if (q == "hello")
        return "World";
    if (q == "ping")
        return "Pong";
    if (q == "the answer to life, the universe and everything")
        return 42;
    if (q.indexOf("unladen swallow") != -1) {
        if (q.indexOf("european") != -1)
            return 11.0;
        return QByteArray("african or european?");
    }

    return "Sorry, I don't know the answer";
}

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QDBusBusService *bus = QDBus::sessionBus().busService();

    QObject obj;
    Pong *pong = new Pong(&obj);
    pong->connect(&app, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit()));
    pong->setProperty("value", "initial value");
    QDBus::sessionBus().registerObject("/", &obj);

    if (bus->requestName(SERVICE_NAME, QDBusBusService::AllowReplacingName) !=
        QDBusBusService::PrimaryOwnerReply)
        exit(1);
    
    app.exec();
    return 0;
}

#include "complexpong.moc"

--- NEW FILE: complexpong.h ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef COMPLEXPONG_H
#define COMPLEXPONG_H

#include <QtCore/QObject>

class Pong: public QDBusAbstractAdaptor
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.ComplexPong.Pong")
    Q_PROPERTY(QString value READ value WRITE setValue);
public:
    QString m_value;
    QString value() const;
    void setValue(const QString &newValue);

    Pong(QObject *obj) : QDBusAbstractAdaptor(obj)
    { }
signals:
    void aboutToQuit();
public slots:
    QVariant query(const QString &query);
    Q_ASYNC void quit();
};

#endif

--- NEW FILE: dbus.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <stdio.h>

#include <dbus/qdbus.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/qmetaobject.h>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>

Q_DECLARE_METATYPE(QVariant)
QDBusConnection *connection;

void listObjects(const QString &service, const QString &path)
{
    QDBusInterface *iface = connection->findInterface(service, path.isEmpty() ? "/" : path,
                                                     "org.freedesktop.DBus.Introspectable");
    QDBusReply<QString> xml = iface->call("Introspect");

    if (xml.isError())
        return;                 // silently

    QDomDocument doc;
    doc.setContent(xml);
    QDomElement node = doc.documentElement();
    QDomElement child = node.firstChildElement();
    while (!child.isNull()) {
        if (child.tagName() == QLatin1String("node")) {
            QString sub = path + '/' + child.attribute("name");
            printf("%s\n", qPrintable(sub));
            listObjects(service, sub);
        }
        child = child.nextSiblingElement();
    }

    delete iface;
}

void listInterface(const QString &service, const QString &path, const QString &interface)
{
    QDBusInterface *iface = connection->findInterface(service, path, interface);
    const QMetaObject *mo = iface->metaObject();

    // properties
    for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i) {
        QMetaProperty mp = mo->property(i);
        printf("property ");

        if (mp.isReadable() && mp.isWritable())
            printf("readwrite");
        else if (mp.isReadable())
            printf("read");
        else
            printf("write");

        printf(" %s %s.%s\n", mp.typeName(), qPrintable(interface), mp.name());
    }

    // methods (signals and slots)
    for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
        QMetaMethod mm = mo->method(i);

        QByteArray signature = mm.signature();
        signature.truncate(signature.indexOf('('));
        printf("%s %s%s%s %s.%s(",
               mm.methodType() == QMetaMethod::Signal ? "signal" : "method",
               mm.tag(), *mm.tag() ? " " : "",
               *mm.typeName() ? mm.typeName() : "void",
               qPrintable(interface), signature.constData());

        QList<QByteArray> types = mm.parameterTypes();
        QList<QByteArray> names = mm.parameterNames();
        bool first = true;
        for (int i = 0; i < types.count(); ++i) {
            printf("%s%s",
                   first ? "" : ", ",
                   types.at(i).constData());
            if (!names.at(i).isEmpty())
                printf(" %s", names.at(i).constData());
            first = false;
        }
        printf(")\n");
    }
    delete iface;
}

void listAllInterfaces(const QString &service, const QString &path)
{
    QDBusInterface *iface = connection->findInterface(service, path,
                                                     "org.freedesktop.DBus.Introspectable");
    QDBusReply<QString> xml = iface->call("Introspect");

    if (xml.isError())
        return;                 // silently

    QDomDocument doc;
    doc.setContent(xml);
    QDomElement node = doc.documentElement();
    QDomElement child = node.firstChildElement();
    while (!child.isNull()) {
        if (child.tagName() == QLatin1String("interface")) {
            listInterface(service, path, child.attribute("name"));
        }
        child = child.nextSiblingElement();
    }

    delete iface;
}

QDBusInterface *findMember(const QString &service, const QString &path, const QString &member)
{
    QDBusInterface *iface = connection->findInterface(service, path,
                                                     "org.freedesktop.DBus.Introspectable");
    QDBusReply<QString> xml = iface->call("Introspect");

    if (xml.isError())
        return 0;

    QDomDocument doc;
    doc.setContent(xml);
    QDomElement node = doc.documentElement();
    QDomElement child = node.firstChildElement("interface");
    while (!child.isNull()) {
        QDomElement subchild = child.firstChildElement("method");
        while (!subchild.isNull()) {
            if (subchild.attribute("name") == member) {
                QDBusInterface *retval;
                retval = connection->findInterface(service, path, child.attribute("name"));
                delete iface;
                return retval;
            }
            subchild = subchild.nextSiblingElement("method");
        }

        child = child.nextSiblingElement("interface");
    }

    delete iface;
    return 0;
}

QStringList readList(int &argc, const char *const *&argv)
{
    --argc;
    ++argv;

    QStringList retval;
    while (argc && QLatin1String(argv[0]) != ")")
        retval += QString::fromLocal8Bit(argv[0]);

    return retval;
}

void placeCall(const QString &service, const QString &path, const QString &interface,
               const QString &member, int argc, const char *const *argv)
{
    QDBusInterface *iface;
    if (interface.isEmpty())
        iface = findMember(service, path, member);
    else
        iface = connection->findInterface(service, path, interface);

    if (!iface) {
        fprintf(stderr, "Interface '%s' not available in object %s at %s\n",
                qPrintable(interface), qPrintable(path), qPrintable(service));
        exit(1);
    }

    const QMetaObject *mo = iface->metaObject();
    QByteArray match = member.toLatin1();
    match += '(';

    int midx;
    for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
        QMetaMethod mm = mo->method(i);
        QByteArray signature = mm.signature();
        if (signature.startsWith(match)) {
            midx = i;
            break;
        }
    }

    if (midx == -1) {
        fprintf(stderr, "Cannot find '%s.%s' in object %s at %s\n",
                qPrintable(interface), qPrintable(member), qPrintable(path),
                qPrintable(service));
        exit(1);
    }

    QMetaMethod mm = iface->metaObject()->method(midx);
    QList<QByteArray> types = mm.parameterTypes();

    QVariantList params;
    for (int i = 0; argc && i < types.count(); ++i) {
        int id = QVariant::nameToType(types.at(i));
        if (id == QVariant::UserType || id == QVariant::Map) {
            fprintf(stderr, "Sorry, can't pass arg of type %s yet\n",
                    types.at(i).constData());
            exit(1);
        }

        Q_ASSERT(id);

        QVariant p;
        if ((id == QVariant::List || id == QVariant::StringList) && QLatin1String("(") == argv[0])
            p = readList(argc, argv);
        else
            p = QString::fromLocal8Bit(argv[0]);

        p.convert( QVariant::Type(id) );
        params += p;
        --argc;
        ++argv;
    }
    if (params.count() != types.count()) {
        fprintf(stderr, "Invalid number of parameters\n");
        exit(1);
    }

    QDBusMessage reply = iface->callWithArgs(member, params);
    if (reply.type() == QDBusMessage::ErrorMessage) {
        QDBusError err = reply;
        printf("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message()));
        exit(2);
    } else if (reply.type() != QDBusMessage::ReplyMessage) {
        fprintf(stderr, "Invalid reply type %d\n", int(reply.type()));
        exit(1);
    }
    
    foreach (QVariant v, reply) {
        if (v.userType() == qMetaTypeId<QVariant>())
            v = qvariant_cast<QVariant>(v);
        printf("%s\n", qPrintable(v.toString()));
    }

    delete iface;
    exit(0);
}

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    if (argc >= 1 && qstrcmp(argv[1], "--system") == 0) {
        connection = &QDBus::systemBus();
        --argc;
        ++argv;
    } else
        connection = &QDBus::sessionBus();

    QDBusBusService *bus = connection->busService();

    if (argc == 1) {
        QStringList names = bus->ListNames();
        foreach (QString name, names)
            printf("%s\n", qPrintable(name));
        exit(0);
    }
    
    QString service = QLatin1String(argv[1]);
    if (!QDBusUtil::isValidBusName(service)) {
        fprintf(stderr, "Service '%s' is not a valid name.\n", qPrintable(service));
        exit(1);
    }
    if (!bus->NameHasOwner(service)) {
        fprintf(stderr, "Service '%s' does not exist.\n", qPrintable(service));
        exit(1);
    }

    if (argc == 2) {
        printf("/\n");
        listObjects(service, QString());
        exit(0);
    }

    QString path = QLatin1String(argv[2]);
    if (!QDBusUtil::isValidObjectPath(path)) {
        fprintf(stderr, "Path '%s' is not a valid path name.\n", qPrintable(path));
        exit(1);
    }
    if (argc == 3) {
        listAllInterfaces(service, path);
        exit(0);
    }

    QString interface = QLatin1String(argv[3]);
    QString member;
    int pos = interface.lastIndexOf(QLatin1Char('.'));
    if (pos == -1) {
        member = interface;
        interface.clear();
    } else {
        member = interface.mid(pos + 1);
        interface.truncate(pos);
    }

    placeCall(service, path, interface, member, argc - 4, argv + 4);
}


--- NEW FILE: hello.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <stdio.h>

#include <dbus/qdbus.h>
#include <QtCore/QCoreApplication>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    printf("Hello, World\n");
    return 0;
}

--- NEW FILE: ping-common.h ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#define SERVICE_NAME            "com.trolltech.QtDBus.PingExample"

--- NEW FILE: ping.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <stdio.h>

#include <dbus/qdbus.h>
#include <QtCore/QCoreApplication>

#include "ping-common.h"

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QDBusInterface *iface = QDBus::sessionBus().findInterface(SERVICE_NAME, "/");
    if (iface) {
        QDBusReply<QString> reply = iface->call("ping", argc > 1 ? argv[1] : "");
        if (reply.isSuccess()) {
            printf("Reply was: %s\n", qPrintable(reply.value()));
            return 0;
        }

        fprintf(stderr, "Call failed: %s\n", qPrintable(reply.error().message()));
        return 1;
    }

    fprintf(stderr, "%s\n",
            qPrintable(QDBus::sessionBus().lastError().message()));
    return 1;
}

--- NEW FILE: pong.cpp ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <stdio.h>

#include <dbus/qdbus.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>

#include "ping-common.h"
#include "pong.h"

QString Pong::ping(const QString &arg)
{
    QTimer::singleShot(0, QCoreApplication::instance(), SLOT(quit()));
    return QString("ping(\"%1\") got called").arg(arg);
}

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QDBusBusService *bus = QDBus::sessionBus().busService();
    if (bus->requestName(SERVICE_NAME, QDBusBusService::AllowReplacingName) !=
        QDBusBusService::PrimaryOwnerReply)
        exit(1);

    Pong pong;
    QDBus::sessionBus().registerObject("/", &pong, QDBusConnection::ExportSlots);
    
    app.exec();
    return 0;
}

#include "pong.moc"

--- NEW FILE: pong.h ---
/* -*- C++ -*-
 *
 * Copyright (C) 2006 Trolltech AS. All rights reserved.
 *    Author: Thiago Macieira <thiago.macieira at trolltech.com>
 *
 * 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 2 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, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef PONG_H
#define PONG_H

#include <QtCore/QObject>

class Pong: public QObject
{
    Q_OBJECT
public slots:
    Q_SCRIPTABLE QString ping(const QString &arg);
};

#endif



More information about the dbus-commit mailing list