From bcf1fe61797c9d4601a075c1fe3c8bcd33cf3c8f Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 21 Oct 2010 15:27:57 -0200 Subject: [PATCH] First commit Signed-off-by: Rodrigo Vivi --- debian/changelog | 5 + debian/compat | 1 + debian/control | 12 + debian/hide-caller-id.install | 3 + debian/rules | 91 ++++++ hide-caller-id.desktop | 11 + hide-caller-id.pro | 25 ++ hide-caller-id.pro.user | 189 +++++++++++ icons.qrc | 6 + icons/hidden.png | Bin 0 -> 18316 bytes icons/shown.png | Bin 0 -> 19510 bytes .../qmaemo5homescreenadaptor.cpp | 336 ++++++++++++++++++++ .../qmaemo5homescreenadaptor.h | 91 ++++++ .../qmaemo5homescreenadaptor.pri | 4 + src/idwidget.cpp | 42 +++ src/idwidget.h | 45 +++ src/main.cpp | 56 ++++ src/testwidget.h | 119 +++++++ src/tpsession.cpp | 147 +++++++++ src/tpsession.h | 36 +++ 20 files changed, 1219 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/hide-caller-id.install create mode 100755 debian/rules create mode 100644 hide-caller-id.desktop create mode 100644 hide-caller-id.pro create mode 100644 hide-caller-id.pro.user create mode 100644 icons.qrc create mode 100644 icons/hidden.png create mode 100644 icons/shown.png create mode 100644 qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.cpp create mode 100644 qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h create mode 100644 qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri create mode 100644 src/idwidget.cpp create mode 100644 src/idwidget.h create mode 100644 src/main.cpp create mode 100644 src/testwidget.h create mode 100644 src/tpsession.cpp create mode 100644 src/tpsession.h delete mode 100644 welcome diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..28f8adb --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +hide-caller-id (0.0.1) unstable; urgency=low + + * Initial Release. + + -- Rodrigo Vivi Wed, 20 Oct 2010 16:11:16 -0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +4 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..9964f4e --- /dev/null +++ b/debian/control @@ -0,0 +1,12 @@ +Source: hide-caller-id +Section: libs +Priority: optional +Maintainer: Rodrigo Vivi +Build-Depends: libqt4-dev (>= 4.6.1), libhildon1-dev, libhildondesktop1-dev +Standards-Version: 3.7.3 + +Package: hide-caller-id +Architecture: any +Section: devel +Depends: libqt4-core (>= 4.6.1), libqt4-gui (>= 4.6.1), qt4-homescreen-loader +Description: Hide Caller Id Homescreen Widget diff --git a/debian/hide-caller-id.install b/debian/hide-caller-id.install new file mode 100644 index 0000000..473ef24 --- /dev/null +++ b/debian/hide-caller-id.install @@ -0,0 +1,3 @@ +/usr/lib/hildon-desktop/hide-caller-id +/usr/share/applications/hildon-home/hide-caller-id.desktop + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..72fe66a --- /dev/null +++ b/debian/rules @@ -0,0 +1,91 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + + + + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + + touch configure-stamp + + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #docbook-to-man debian/hide-caller-id.sgml > hide-caller-id.1 + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + $(MAKE) clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/hide-caller-id + $(MAKE) INSTALL_ROOT="$(CURDIR)"/debian/hide-caller-id install + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + # dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb + # dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/hide-caller-id.desktop b/hide-caller-id.desktop new file mode 100644 index 0000000..d48de65 --- /dev/null +++ b/hide-caller-id.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Hide Caller Id +Comment=Hide caller id home desktop item +Type=qt +X-Path=hide-caller-id +X-Multiple-Instances=false +X-home-applet-minwidth=100 +X-home-applet-minheight=72 +Name[en_US]=Hide Caller Id +Exec=/usr/lib/hildon-desktop/hide-caller-id +Icon=hide-caller-id diff --git a/hide-caller-id.pro b/hide-caller-id.pro new file mode 100644 index 0000000..3efb72d --- /dev/null +++ b/hide-caller-id.pro @@ -0,0 +1,25 @@ +TEMPLATE = app + +SOURCES += src/main.cpp \ + src/tpsession.cpp \ + src/idwidget.cpp +HEADERS += \ + src/tpsession.h \ + src/idwidget.h + +include(qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri) + +desktop.path = /usr/share/applications/hildon-home +desktop.files = hide-caller-id.desktop + +target.path = /usr/lib/hildon-desktop +INSTALLS += target desktop + +unix { +INCLUDEPATH += /usr/include/telepathy-1.0 +INCLUDEPATH += /usr/include/QtDBus +LIBS += -ltelepathy-qt4 +} + +RESOURCES += \ + icons.qrc diff --git a/hide-caller-id.pro.user b/hide-caller-id.pro.user new file mode 100644 index 0000000..f3ac355 --- /dev/null +++ b/hide-caller-id.pro.user @@ -0,0 +1,189 @@ + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + Default + + + + ProjectExplorer.Project.Target.0 + + Maemo + + Qt4ProjectManager.Target.MaemoDeviceTarget + 0 + 0 + 0 + + + + qmake + + QtProjectManager.QMakeBuildStep + + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + + clean + + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /home/vivijim/pessoal/hide-caller-id-build-maemo + 8 + 9 + true + + + + + qmake + + QtProjectManager.QMakeBuildStep + + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + + clean + + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /home/vivijim/pessoal/hide-caller-id-build-maemo + 8 + 9 + true + + 2 + + + + true + Packaging for Maemo + + Qt4ProjectManager.MaemoPackageCreationStep + + + Deploy to Maemo device + + Qt4ProjectManager.MaemoDeployStep + false + 1 + + /home/vivijim/pessoal/hide-caller-id-build-maemo/hide-caller-id_0.0.1_armel.deb + + + 192.168.2.15 + + + + + + 2010-10-20T16:44:03 + + + 2 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy to Maemo device + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + hide-caller-id + + Qt4ProjectManager.MaemoRunConfiguration + + 1 + + hide-caller-id.pro + + false + + 3768 + true + false + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {751d2bf9-42aa-4f49-99ea-c989cc8805f2} + + + ProjectExplorer.Project.Updater.FileVersion + 8 + + diff --git a/icons.qrc b/icons.qrc new file mode 100644 index 0000000..d509e05 --- /dev/null +++ b/icons.qrc @@ -0,0 +1,6 @@ + + + icons/shown.png + icons/hidden.png + + diff --git a/icons/hidden.png b/icons/hidden.png new file mode 100644 index 0000000000000000000000000000000000000000..fa2f3d0ad8ff1cdd1b68c0b25f6c82d22fa6305f GIT binary patch literal 18316 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 bFG>dhHrNJO5L3!r00000NkvXXu0mjfL0y`) literal 0 HcmV?d00001 diff --git a/icons/shown.png b/icons/shown.png new file mode 100644 index 0000000000000000000000000000000000000000..68d6fd1af960619766a971cefdba0a71e3046c58 GIT binary patch literal 19510 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⪼iV&Ix41&Pn2Yr4V;6a}O0q+l( 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 +#include + +#include +#include +#include +#include + +#include +#include +#include + +static QCoreApplication::EventFilter oldEventFilter; +static QList allDesktopItems; + +static Atom atomByName(const char *name) +{ + Atom atom = XInternAtom(QX11Info::display(), name, False); + if (!atom) + qWarning("Unable to obtain %s atom. This class requires a running Hildon session.", name); + + return atom; +} + +enum HomescreenAtoms +{ + HildonAppletId = 0, + NetWmWindowType = 1, + Utf8String = 2, + HildonTypeHomeApplet = 3, + HildonAppletSettings = 4, + HildonAppletShowSettings = 5, + HildonAppletOnCurrentDesktop = 6, + EnumCount = 7 +}; + +static Atom hsAtoms[EnumCount] = { 0, 0, 0, 0, 0, 0, 0 }; + +static void initAtoms() +{ + hsAtoms[HildonAppletId] = atomByName("_HILDON_APPLET_ID"); + hsAtoms[NetWmWindowType] = atomByName("_NET_WM_WINDOW_TYPE"); + hsAtoms[Utf8String] = atomByName("UTF8_STRING"); + hsAtoms[HildonTypeHomeApplet] = atomByName("_HILDON_WM_WINDOW_TYPE_HOME_APPLET"); + hsAtoms[HildonAppletSettings] = atomByName("_HILDON_APPLET_SETTINGS"); + hsAtoms[HildonAppletShowSettings] = atomByName("_HILDON_APPLET_SHOW_SETTINGS"); + hsAtoms[HildonAppletOnCurrentDesktop] = atomByName("_HILDON_APPLET_ON_CURRENT_DESKTOP"); +} + +/*! \class QMaemo5HomescreenAdaptor + + \brief The QMaemo5HomescreenAdaptor flags a top-level QWidget as homescreen widget + + QMaemo5HomescreenAdaptor is used in conjunction with the Qt for Maemo homescreen + loader. It evaluates the two command line arguments "-plugin-id" and "-write-pipe" + to set up a Qt top-level widget as Maemo 5 homescreen widget. + + Note: By default, the widget will have a black background. In order to make the + widget transparent, set the Qt::WA_TranslucentBackground widget attribute. + + Example: + + \code + QLabel *label = new QLabel("Hello Homescreen"); + new QMaemo5HomescreenAdaptor(label); + label->show(); + \endcode + + Maemo 5 supports homescreen widgets with settings dialogs. To use it, set + the settingsAvailable() property and show a settings dialog when the + settingsRequested() signal is emitted. + + Maemo 5 supports more than one homescreen. In order to determine whether + the homescreen widget is on the currently visible homescreen, connect to + the homescreenChanged() signal. +*/ + +/*! \property QMaemo5HomescreenAdaptor::settingsAvailable + + Set this property to true if the widget can make use of a settings dialog, + otherwise to false. When this property is set to true, the Maemo 5 homescreen + renders a small settings icon on top of the homescreen widget when the + user enters the desktop menu. When the user clicks that settings icon, the + settingsRequested() signal is emitted. + + The default is false. + + \sa settingsRequested() + */ + +/*! \fn void settingsRequested() + + This signal is emitted every time the homescreen widget's settings icon is + invoked by the user. Note that this icon is only visible when the settingsAvailable() + property is set. + + \sa settingsAvailable() + */ + +/*! \fn void homescreenChanged(bool isOnCurrentHomescreen) + + This is signal is emitted when current homescreen changes and the homescreen + widget becomes visible or invisible. The \a isOnCurrentHomescreen argument + indicates whether the homescreen widget is on the current homescreen or not. + + This signal can be used to start/stop background processing in order to save + battery life. + */ + +/*! + Constructs a new QMaemo5HomescreenAdaptor for the given \a widget. + + Note: The widget must be a top-level widget, and must not be reparented + during the lifetime of this adaptor. + + Note: \a widget is also the parent of this class, if the widget is destroyed, + so is this adaptor. + */ +QMaemo5HomescreenAdaptor::QMaemo5HomescreenAdaptor(QWidget *widget) + : QObject(widget), + hasSettings(false) +{ + Q_ASSERT(widget->isWindow()); + + if (!hsAtoms[0]) + initAtoms(); + + Display *display = QX11Info::display(); + + const QStringList args = QApplication::arguments(); + + // parse the command line arguments. + int idx; + if ((idx = args.indexOf(QLatin1String("-plugin-id"))) != -1) { + appletId = args.value(idx + 1); + const QByteArray pluginId = appletId.toUtf8(); + if (!pluginId.isEmpty()) { + XChangeProperty(display, + widget->winId(), + hsAtoms[HildonAppletId], + hsAtoms[Utf8String], 8, PropModeReplace, + reinterpret_cast(pluginId.constData()), + pluginId.length()); + } + } + if ((idx = args.indexOf(QLatin1String("-write-pipe"))) != -1) { + bool ok; + int sockId = args.value(idx + 1).toInt(&ok); + if (ok) { + socketNotifier = new QSocketNotifier(sockId, QSocketNotifier::Exception, this); + connect(socketNotifier, SIGNAL(activated(int)), this, SLOT(socketException())); + } + } + + // set the X11 atoms to flag our widget as homescreen widget + if (!appletId.isEmpty()) { + XChangeProperty(display, + widget->winId(), + hsAtoms[NetWmWindowType], + XA_ATOM, 32, PropModeReplace, + reinterpret_cast(&hsAtoms[HildonTypeHomeApplet]), + 1); + + updateStatus(); + + // --- make this window a child of root + XSetTransientForHint(display, widget->winId(), + RootWindow(display, widget->x11Info().screen())); + + // --- add an x11 event filter + if (!oldEventFilter) + oldEventFilter = QCoreApplication::instance()->setEventFilter(applicationEventFilter); + + allDesktopItems.append(this); + + // --- set WM input hints indicating that we don't want focus events + XWMHints *h = XGetWMHints(display, widget->winId()); + XWMHints wm_hints; + if (!h) { + memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy + h = &wm_hints; + } + h->flags |= InputHint; + h->input = False; + + XSetWMHints(display, widget->winId(), h); + if (h != &wm_hints) + XFree(h); + + widget->setMouseTracking(true); + } +} + +QMaemo5HomescreenAdaptor::~QMaemo5HomescreenAdaptor() +{ + allDesktopItems.removeOne(this); +} + +/*! \internal */ +void QMaemo5HomescreenAdaptor::updateStatus() +{ + if (appletId.isEmpty()) + return; + + Display *display = QX11Info::display(); + + // Set or remove settings property + if (hasSettings) + XChangeProperty(display, + appletWidget()->winId(), + hsAtoms[HildonAppletSettings], + XA_CARDINAL, 32, PropModeReplace, + (const unsigned char *) &(hasSettings), 1); + else + XDeleteProperty(display, + appletWidget()->winId(), + hsAtoms[HildonAppletSettings]); +} + +/*! \internal */ +void QMaemo5HomescreenAdaptor::socketException() +{ + socketNotifier->setEnabled(false); + appletWidget()->close(); +} + +bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event) +{ + return QCoreApplication::sendSpontaneousEvent(receiver, event); +} + + + +/*! \internal */ +bool QMaemo5HomescreenAdaptor::applicationEventFilter(void *message, long *result) +{ + static QPointer lastMouseWidget; + bool retval = false; + + if (oldEventFilter) + retval = oldEventFilter(message, result); + + if (allDesktopItems.isEmpty()) + return retval; + + XEvent *ev = reinterpret_cast(message); + + // Generate a mouse release for a leave Notify (as we don't get the mouse release from X11) + if (ev->type == ButtonPress) { + QPoint globalPos( ev->xbutton.x_root, ev->xbutton.y_root); + QWidget *widget = QWidget::find((WId)ev->xany.window); + if (widget) { + lastMouseWidget = widget->childAt(widget->mapFromGlobal(globalPos)); + if (!lastMouseWidget) + lastMouseWidget = widget; + } + + } else if (ev->type == ButtonRelease) { + lastMouseWidget = 0; + + } else if (ev->type == LeaveNotify) { + if (lastMouseWidget) { + // create a mouse up event that lies in Nirvana. + QPoint pos(-1000, -1000); + QMouseEvent e(QEvent::MouseButtonRelease, pos, pos, Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + qt_sendSpontaneousEvent(lastMouseWidget, &e); + lastMouseWidget = 0; + } + + } else if (ev->type == ClientMessage) { + XClientMessageEvent *cm = (XClientMessageEvent *)message; + if (cm->message_type == hsAtoms[HildonAppletShowSettings]) { + for (int i = 0; i < allDesktopItems.count(); ++i) { + if (allDesktopItems.at(i)->appletWidget()->winId() == ev->xproperty.window) { + emit allDesktopItems.at(i)->settingsRequested(); + retval = true; + } + } + } + } else if (ev->type == PropertyNotify) { + if (ev->xproperty.atom == hsAtoms[HildonAppletOnCurrentDesktop]) { + for (int i = 0; i < allDesktopItems.count(); ++i) { + if (allDesktopItems.at(i)->appletWidget()->winId() == ev->xproperty.window) { + emit allDesktopItems.at(i)->homescreenChanged(ev->xproperty.window == 0); + retval = true; + } + } + } + } + + return retval; +} + diff --git a/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h new file mode 100644 index 0000000..9270649 --- /dev/null +++ b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMAEMO5HOMESCREENADAPTOR_H +#define QMAEMO5HOMESCREENADAPTOR_H + +#include +#include +#include + +class QWidget; +class QSocketNotifier; + +class QMaemo5HomescreenAdaptor : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool settingsAvailable READ settingsAvailable WRITE setSettingsAvailable) + +public: + QMaemo5HomescreenAdaptor(QWidget *widget); + ~QMaemo5HomescreenAdaptor(); + + inline void setSettingsAvailable(bool available) + { + hasSettings = available; + updateStatus(); + } + + inline bool settingsAvailable() const + { + return hasSettings; + } + +Q_SIGNALS: + void settingsRequested(); + void homescreenChanged(bool isOnCurrentHomescreen); + +private Q_SLOTS: + void socketException(); + +private: + inline QWidget *appletWidget() const { return static_cast(parent()); } + + void updateStatus(); + + static bool applicationEventFilter(void *message, long *result); + + bool hasSettings; + QString appletId; + QSocketNotifier *socketNotifier; +}; + +#endif diff --git a/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri new file mode 100644 index 0000000..73d41c3 --- /dev/null +++ b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri @@ -0,0 +1,4 @@ +HEADERS += $$PWD/qmaemo5homescreenadaptor.h +SOURCES += $$PWD/qmaemo5homescreenadaptor.cpp + +INCLUDEPATH += $$PWD diff --git a/src/idwidget.cpp b/src/idwidget.cpp new file mode 100644 index 0000000..08fac3f --- /dev/null +++ b/src/idwidget.cpp @@ -0,0 +1,42 @@ +#include "idwidget.h" + +IdWidget::IdWidget(tpSession *tp) + : QPushButton() +{ + this->tp = tp; + setAttribute(Qt::WA_TranslucentBackground); + QObject::connect(this, SIGNAL(clicked()), this, SLOT(changeState())); + QObject::connect(tp, SIGNAL(privacyUpdated(bool)), this, SLOT(setButtonState(bool))); + pHidden = new QPixmap(":/icons/hidden.png"); + pShown = new QPixmap(":/icons/shown.png"); +} + +void IdWidget::setButtonState(bool showId) +{ + QPixmap *pixmap; + this->showId = showId; + + if(showId) { + pixmap = pShown; + setText("Id Shown"); + } + else { + pixmap = pHidden; + setText("Id Hidden"); + } + + QIcon icon(*pixmap); + QSize iconSize(pixmap->width(), pixmap->height()); + setIconSize(iconSize); + setIcon(icon); +} + +void IdWidget::changeState() +{ + if(showId) { + tp->setPrivacy(false); + } + else { + tp->setPrivacy(true); + } +} diff --git a/src/idwidget.h b/src/idwidget.h new file mode 100644 index 0000000..7e8840d --- /dev/null +++ b/src/idwidget.h @@ -0,0 +1,45 @@ +#ifndef IDWIDGET_H +#define IDWIDGET_H + +#include +#include +#include +#include "tpsession.h" + +class IdWidget : public QPushButton +{ + Q_OBJECT + +private: + + bool showId; + tpSession *tp; + QPixmap *pHidden; + QPixmap *pShown; + +public: + IdWidget(tpSession *tp); + + QSize sizeHint() const + { + return QSize(200, 75); + } + +public slots: + void changeState(); + void setButtonState(bool showId); + +protected: + void paintEvent(QPaintEvent *event) + { + QPainter p(this); + p.setBrush(QColor(0, 0, 0, 128)); + p.setPen(Qt::NoPen); + p.drawRoundedRect(rect(), 25, 25); + p.end(); + + QPushButton::paintEvent(event); + } +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fe54766 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file was based on one of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmaemo5homescreenadaptor.h" +#include "idwidget.h" +#include "tpsession.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + IdWidget *idWidget = new IdWidget(new tpSession()); + QMaemo5HomescreenAdaptor *adaptor = new QMaemo5HomescreenAdaptor(idWidget); + adaptor->setSettingsAvailable(false); + idWidget->show(); + + app.exec(); +} diff --git a/src/testwidget.h b/src/testwidget.h new file mode 100644 index 0000000..0fadaff --- /dev/null +++ b/src/testwidget.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IDWIDGET_H +#define IDWIDGET_H + +#include +#include +#include +#include "tpsession.h" + +class IdWidget : public QPushButton +{ + Q_OBJECT + +public: + + bool showId; + tpSession* tp; + + IdWidget() + : QPushButton() + { + setAttribute(Qt::WA_TranslucentBackground); + QPixmap* pixmap = new QPixmap("/usr/share/vivi/shown.png"); + showId = TRUE; + setText("Id Shown"); + QIcon icon(*pixmap); + QSize iconSize(pixmap->width(), pixmap->height()); + setIconSize(iconSize); + setIcon(icon); + QObject::connect(this, SIGNAL(clicked()), this, SLOT(changeState())); + } + + IdWidget(tpSession tp) + { + this->tp = tp; + } + + QSize sizeHint() const + { + return 1.2 * QPushButton::sizeHint(); + } + +public slots: + + void changeState() + { + QPixmap* pixmap; + if(showId) { + pixmap = new QPixmap("/usr/share/vivi/hidden.png"); + showId = FALSE; + setText("Id Hidden"); + tp->setPrivacy(true); + } + else { + pixmap = new QPixmap("/usr/share/vivi/shown.png"); + showId = TRUE; + setText("Id Shown"); + tp->setPrivacy(false); + } + QIcon icon(*pixmap); + QSize iconSize(pixmap->width(), pixmap->height()); + setIconSize(iconSize); + setIcon(icon); + } + +protected: + void paintEvent(QPaintEvent *event) + { + QPainter p(this); + p.setBrush(QColor(0, 0, 0, 128)); + p.setPen(Qt::NoPen); + p.drawRoundedRect(rect(), 25, 25); + p.end(); + + QPushButton::paintEvent(event); + } +}; + +#endif diff --git a/src/tpsession.cpp b/src/tpsession.cpp new file mode 100644 index 0000000..5ad4311 --- /dev/null +++ b/src/tpsession.cpp @@ -0,0 +1,147 @@ +#include "tpsession.h" + +#include +#include +#include +#include +#include +#include +#include + +tpSession::tpSession() +{ + QDBusConnection bus = QDBusConnection::sessionBus(); + mAM = AccountManager::create(bus, + AccountFactory::create(bus, Account::FeatureCore), + ConnectionFactory::create(bus, Connection::FeatureCore), + ChannelFactory::create(bus)); + + connect(mAM->becomeReady(), + SIGNAL(finished(Tp::PendingOperation *)), + SLOT(onAMReady(Tp::PendingOperation *))); +} + +void tpSession::onAMReady(Tp::PendingOperation *op) +{ + if (op->isError()) { + qWarning() << "error making AM ready"; + return; + } + + mAccount = mAM->accountForPath("/org/freedesktop/Telepathy/Account/ring/tel/ring"); + if (!mAccount) { + qWarning() << "no account for ring found"; + return; + } + + //connect(mAccount->baseInterface(), SIGNAL(AccountPropertyChanged(const QVariantMap&)), this, SLOT(onPrivacyChanged(const QVariantMap&))); + if (!mAccount->haveConnection()) { + connect(mAccount.data(), + SIGNAL(haveConnectionChanged(bool)), + SLOT(onAccountHaveConnectionChanged(bool))); + } else { + mConnection = mAccount->connection(); + retrievePrivacy(); + } +} + +void tpSession::onPropertyChanged(const QVariantMap& properties) +{ + qDebug() << "TODO: change state when Privacy has been updated by someone else" << properties; +} + +void tpSession::onAccountHaveConnectionChanged(bool haveConnection) +{ + if (haveConnection) { + mConnection = mAccount->connection(); + retrievePrivacy(); + } +} + +void tpSession::onSetPrivacyFinished(Tp::PendingOperation *op) +{ + if (op->isError()) { + qWarning() << "unable to set com.nokia.Telepathy.Connection.Interface.GSM.Privacy"; + return; + } + + qDebug() << "com.nokia.Telepathy.Connection.Interface.GSM.Privacy property set"; + emit privacyUpdated(showId); +} + +void tpSession::onGotPrivacy(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + + if (reply.isError()) { + qWarning() << "unable to get com.nokia.Telepathy.Connection.Interface.GSM.Privacy"; + return; + } + + // Don't ask me why, but no-id == showId and id == hide it. + if(qdbus_cast(reply.value()) == QVariant("no-id")) + showId = true; + else + showId = false; + emit privacyUpdated(showId); + + qDebug() << "com.nokia.Telepathy.Connection.Interface.GSM.Privacy property set"; +} + +void tpSession::retrievePrivacy() +{ + if (!mConnection) { + qWarning() << "Account Manager connection unavailable"; + return; + } + + if (!mConnection->hasInterface("com.nokia.Telepathy.Connection.Interface.GSM")) { + qWarning() << "connection does not have interface GSM"; + return; + } + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher( + mConnection->propertiesInterface()->Get( + QLatin1String("com.nokia.Telepathy.Connection.Interface.GSM"), + QLatin1String("Privacy")), this); + + connect(watcher, + SIGNAL(finished(QDBusPendingCallWatcher *)), + SLOT(onGotPrivacy(QDBusPendingCallWatcher *))); + + qDebug() << "com.nokia.Telepathy.Connection.Interface.GSM.Privacy retrieved"; +} + +void tpSession::setPrivacy(bool value) +{ + showId = value; + + if (!mConnection) { + qWarning() << "Account Manager connection unavailable"; + return; + } + + if (!mConnection->hasInterface("com.nokia.Telepathy.Connection.Interface.GSM")) { + qWarning() << "connection does not have interface GSM"; + return; + } + + PendingVoid *call; + // Don't ask me why, but no-id == showId and id == hide it. + if(value) + call = new PendingVoid( + mConnection->propertiesInterface()->Set( + QLatin1String("com.nokia.Telepathy.Connection.Interface.GSM"), + QLatin1String("Privacy"), QDBusVariant("no-id")), + this); + else + call = new PendingVoid( + mConnection->propertiesInterface()->Set( + QLatin1String("com.nokia.Telepathy.Connection.Interface.GSM"), + QLatin1String("Privacy"), QDBusVariant("id")), + this); + + connect(call, + SIGNAL(finished(Tp::PendingOperation*)), + SLOT(onSetPrivacyFinished(Tp::PendingOperation*))); +} diff --git a/src/tpsession.h b/src/tpsession.h new file mode 100644 index 0000000..9281e13 --- /dev/null +++ b/src/tpsession.h @@ -0,0 +1,36 @@ +#ifndef TPSESSION_H +#define TPSESSION_H + +#include +#include + +using namespace Tp; + +class tpSession : public QObject +{ + Q_OBJECT + +public: + tpSession(); + ~tpSession() {} + void setPrivacy(bool showId); + void retrievePrivacy(); + +private Q_SLOTS: + void onAMReady(Tp::PendingOperation *op); + void onAccountHaveConnectionChanged(bool value); + void onSetPrivacyFinished(Tp::PendingOperation *op); + void onGotPrivacy(QDBusPendingCallWatcher *op); + void onPropertyChanged(const QVariantMap& properties); + +private: + AccountManagerPtr mAM; + AccountPtr mAccount; + ConnectionPtr mConnection; + bool showId; + +signals: + void privacyUpdated(bool showId); +}; + +#endif // TPSESSION_H diff --git a/welcome b/welcome deleted file mode 100644 index e69de29..0000000 -- 1.7.9.5