telephony-service-0.1+14.04.20140415/0000755000015301777760000000000012323310021017400 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/tools/0000755000015301777760000000000012323310021020540 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/tools/ofono-setup0000755000015301777760000000204312323307402022754 0ustar pbusernogroup00000000000000#!/bin/sh # do not wait for a network connection to launch the connection managers dconf write /org/gnome/empathy/use-conn false 2>&1 > /dev/null # check if there is a tp-ofono account already # for now assume that if there is at least one account, the system is properly configured. mc-tool show ofono/ofono/account0 2>&1 > /dev/null # if there is not, create one and enable it if [ $? -eq 1 ]; then # get the modems from ofono MODEMS=`/usr/share/ofono/scripts/list-modems | grep --binary-files=text "^\[" | sed 's,^\[ \(.*\) \],\1,g'` INDEX=0 # and for each modem found create a telepathy account for modem in $MODEMS; do ACCOUNT="account$INDEX" echo "creating ofono/ofono/$ACCOUNT" mc-tool add ofono/ofono $ACCOUNT string:modem-objpath=$modem echo "enabling ofono/ofono/$ACCOUNT" mc-tool enable ofono/ofono/$ACCOUNT mc-tool auto-connect ofono/ofono/$ACCOUNT INDEX=$((INDEX+1)) done fi echo 'ofono accounts initialized' telephony-service-0.1+14.04.20140415/tools/CMakeLists.txt0000644000015301777760000000010412323307402023304 0ustar pbusernogroup00000000000000install(PROGRAMS ofono-setup DESTINATION ${CMAKE_INSTALL_BINDIR}) telephony-service-0.1+14.04.20140415/approver/0000755000015301777760000000000012323310021021236 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/approver/approver.h0000644000015301777760000000466212323307402023266 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef APPROVER_H #define APPROVER_H #include #include #include #include #include #include #include #include class Approver : public QObject, public Tp::AbstractClientApprover { Q_OBJECT public: Approver(); ~Approver(); Tp::ChannelClassSpecList channelFilters() const; void addDispatchOperation(const Tp::MethodInvocationContextPtr<> &context, const Tp::ChannelDispatchOperationPtr &dispatchOperation); Tp::ChannelDispatchOperationPtr dispatchOperation(Tp::PendingOperation *op); void onApproved(Tp::ChannelDispatchOperationPtr dispatchOp); void onHangUpAndApproved(Tp::ChannelDispatchOperationPtr dispatchOp); void onRejected(Tp::ChannelDispatchOperationPtr dispatchOp); protected: Tp::ChannelDispatchOperationPtr dispatchOperationForIncomingCall(); private Q_SLOTS: void processChannels(); void onChannelReady(Tp::PendingOperation *op); void onClaimFinished(Tp::PendingOperation* op); void onHangupFinished(Tp::PendingOperation* op); void onCallStateChanged(Tp::CallState state); void closeSnapDecision(); void onHangupAndAcceptCallRequested(); void onAcceptCallRequested(); void onRejectCallRequested(); void updateNotification(const QtContacts::QContact &contact); private: QList mDispatchOps; QMap mChannels; NotifyNotification* mPendingSnapDecision; QString mDefaultTitle; QString mDefaultIcon; QString mCachedBody; }; #endif // APPROVER_H ././@LongLink0000000000000000000000000000016300000000000011215 Lustar 00000000000000telephony-service-0.1+14.04.20140415/approver/org.freedesktop.Telepathy.Client.TelephonyServiceApprover.service.intelephony-service-0.1+14.04.20140415/approver/org.freedesktop.Telepathy.Client.TelephonyServiceAppro0000644000015301777760000000023512323307402033737 0ustar pbusernogroup00000000000000[D-BUS Service] Name=org.freedesktop.Telepathy.Client.TelephonyServiceApprover Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-approver telephony-service-0.1+14.04.20140415/approver/50-com.canonical.TelephonyServiceApprover.pkla0000644000015301777760000000027212323307402032055 0ustar pbusernogroup00000000000000[Allow LightDM to read TelephonyServiceApprover fields] Identity=unix-user:lightdm Action=com.canonical.TelephonyServiceApprover.ReadAny ResultAny=no ResultInactive=yes ResultActive=yes telephony-service-0.1+14.04.20140415/approver/Approver.xml0000644000015301777760000000241112323307402023565 0ustar pbusernogroup00000000000000 An interface to the phone approver application. telephony-service-0.1+14.04.20140415/approver/main.cpp0000644000015301777760000000374712323307402022712 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include "applicationutils.h" #include "approver.h" #include "telepathyhelper.h" #include #include #include #include #include namespace C { #include } int main(int argc, char **argv) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("telephony-service-approver"); C::bindtextdomain( "telephony-service", "/usr/share/locale" ); C::textdomain("telephony-service"); notify_init(C::gettext("Telephony Service Approver")); Tp::registerTypes(); // check if there is already an instance of the approver running if (ApplicationUtils::checkApplicationRunning(TP_QT_IFACE_CLIENT + ".TelephonyServiceApprover")) { qDebug() << "Found another instance of the approver. Quitting."; return 1; } // register the approver Approver *approver = new Approver(); TelepathyHelper::instance()->registerClient(approver, "TelephonyServiceApprover"); TelepathyHelper::instance()->registerChannelObserver("TelephonyServiceObserver"); return app.exec(); } telephony-service-0.1+14.04.20140415/approver/CMakeLists.txt0000644000015301777760000000346312323307402024015 0ustar pbusernogroup00000000000000 set(qt_SRCS approver.cpp approverdbus.cpp ) set(approver_SRCS main.cpp ${qt_SRCS}) qt5_add_dbus_adaptor(approver_SRCS Approver.xml approver/approverdbus.h ApproverDBus) include_directories( ${TP_QT5_INCLUDE_DIRS} ${NOTIFY_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_CURRENT_BINARY_DIR} ) link_directories(${MESSAGING_MENU_LIBRARY_DIRS}) add_executable(telephony-service-approver ${approver_SRCS} ${approver_HDRS}) qt5_use_modules(telephony-service-approver Contacts Core DBus Gui Multimedia Qml) target_link_libraries(telephony-service-approver ${TP_QT5_LIBRARIES} ${NOTIFY_LIBRARIES} telephonyservice ) configure_file(org.freedesktop.Telepathy.Client.TelephonyServiceApprover.service.in org.freedesktop.Telepathy.Client.TelephonyServiceApprover.service) install(TARGETS telephony-service-approver RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.TelephonyServiceApprover.service DESTINATION share/dbus-1/services) install(FILES TelephonyServiceApprover.client DESTINATION share/telepathy/clients) install(FILES 50-com.canonical.TelephonyServiceApprover.pkla DESTINATION "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1/localauthority/10-vendor.d") install(FILES com.canonical.TelephonyServiceApprover.policy DESTINATION share/polkit-1/actions) install(FILES com.canonical.TelephonyServiceApprover.xml DESTINATION share/dbus-1/interfaces) # Create accountsservice symlink for above dbus interface install(CODE " execute_process(COMMAND mkdir -p \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/share/accountsservice/interfaces\") execute_process(COMMAND ln -sf ../../dbus-1/interfaces/com.canonical.TelephonyServiceApprover.xml \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/share/accountsservice/interfaces\") ") telephony-service-0.1+14.04.20140415/approver/com.canonical.TelephonyServiceApprover.policy0000644000015301777760000000126412323307402032205 0ustar pbusernogroup00000000000000 no yes yes no no no telephony-service-0.1+14.04.20140415/approver/approverdbus.h0000644000015301777760000000261212323307402024135 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Ugo Riboni * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef APPROVERDBUS_H #define APPROVERDBUS_H #include #include #include "chatmanager.h" /** * DBus interface for the phone approver */ class ApproverDBus : public QObject, protected QDBusContext { Q_OBJECT public: ApproverDBus(QObject* parent=0); ~ApproverDBus(); bool connectToBus(); public Q_SLOTS: Q_NOREPLY void HangUpAndAcceptCall(); Q_NOREPLY void AcceptCall(); Q_NOREPLY void RejectCall(); Q_SIGNALS: void hangUpAndAcceptCallRequested(); void acceptCallRequested(); void rejectCallRequested(); }; #endif // APPROVERDBUS_H telephony-service-0.1+14.04.20140415/approver/TelephonyServiceApprover.client0000644000015301777760000000137312323307402027462 0ustar pbusernogroup00000000000000[org.freedesktop.Telepathy.Client] Interfaces=org.freedesktop.Telepathy.Client.Approver; [org.freedesktop.Telepathy.Client.Approver.ApproverChannelFilter 0] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Call1 org.freedesktop.Telepathy.Channel.TargetHandleType u=1 org.freedesktop.Telepathy.Channel.Type.Call1.InitialAudio b=true [org.freedesktop.Telepathy.Client.Approver.ApproverChannelFilter 1] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=1 [org.freedesktop.Telepathy.Client.Approver.Capabilities] org.freedesktop.Telepathy.Channel.Type.Call1/audio=true org.freedesktop.Telepathy.Channel.Type.Call1/audio/speex=true telephony-service-0.1+14.04.20140415/approver/approver.cpp0000644000015301777760000004335012323307402023616 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "approver.h" #include "approverdbus.h" #include "applicationutils.h" #include "callnotification.h" #include "chatmanager.h" #include "config.h" #include "contactutils.h" #include "greetercontacts.h" #include "ringtone.h" #include "callmanager.h" #include "callentry.h" #include #include #include #include #include #include #include #include #include namespace C { #include } #define TELEPHONY_SERVICE_HANDLER TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler" QTCONTACTS_USE_NAMESPACE Approver::Approver() : Tp::AbstractClientApprover(channelFilters()), mPendingSnapDecision(NULL) { mDefaultTitle = C::gettext("Unknown caller"); mDefaultIcon = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); ApproverDBus *dbus = new ApproverDBus(); connect(dbus, SIGNAL(acceptCallRequested()), SLOT(onAcceptCallRequested())); connect(dbus, SIGNAL(rejectCallRequested()), SLOT(onRejectCallRequested())); dbus->connectToBus(); if (GreeterContacts::isGreeterMode()) { connect(GreeterContacts::instance(), SIGNAL(contactUpdated(QtContacts::QContact)), this, SLOT(updateNotification(QtContacts::QContact))); } } Approver::~Approver() { } Tp::ChannelClassSpecList Approver::channelFilters() const { Tp::ChannelClassSpecList specList; specList << Tp::ChannelClassSpec::audioCall(); specList << Tp::ChannelClassSpec::textChat(); return specList; } Tp::ChannelDispatchOperationPtr Approver::dispatchOperation(Tp::PendingOperation *op) { Tp::ChannelPtr channel = mChannels[op]; QString accountId = channel->property("accountId").toString(); Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { if (dispatchOperation->account()->uniqueIdentifier() == accountId) { return dispatchOperation; } } return Tp::ChannelDispatchOperationPtr(); } void Approver::addDispatchOperation(const Tp::MethodInvocationContextPtr<> &context, const Tp::ChannelDispatchOperationPtr &dispatchOperation) { bool willHandle = false; QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { // Call Channel Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (!callChannel.isNull()) { Tp::PendingReady *pr = callChannel->becomeReady(Tp::Features() << Tp::CallChannel::FeatureCore << Tp::CallChannel::FeatureCallState); mChannels[pr] = callChannel; connect(pr, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onChannelReady(Tp::PendingOperation*))); callChannel->setProperty("accountId", QVariant(dispatchOperation->account()->uniqueIdentifier())); willHandle = true; continue; } // Text Channel Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if (!textChannel.isNull()) { // right now we are not using any of the text channel's features in the approver // so no need to call becomeReady() on it. willHandle = true; } } if (willHandle) { mDispatchOps.append(dispatchOperation); } context->setFinished(); // check if we need to approve channels already or if we should wait. processChannels(); } class EventData { public: Approver* self; Tp::ChannelDispatchOperationPtr dispatchOp; Tp::ChannelPtr channel; }; void action_accept(NotifyNotification *notification, char *action, gpointer data) { Q_UNUSED(notification); Q_UNUSED(action); EventData* eventData = (EventData*) data; Approver* approver = (Approver*) eventData->self; if (NULL != approver) { approver->onApproved((Tp::ChannelDispatchOperationPtr) eventData->dispatchOp); } } void action_hangup_and_accept(NotifyNotification *notification, char *action, gpointer data) { Q_UNUSED(notification); Q_UNUSED(action); EventData *eventData = (EventData*) data; Approver *approver = (Approver*) eventData->self; if (approver != NULL) { approver->onHangUpAndApproved((Tp::ChannelDispatchOperationPtr) eventData->dispatchOp); } } void action_reject(NotifyNotification *notification, char *action, gpointer data) { Q_UNUSED(notification); Q_UNUSED(action); EventData* eventData = (EventData*) data; Approver* approver = (Approver*) eventData->self; if (NULL != approver) { approver->onRejected((Tp::ChannelDispatchOperationPtr) eventData->dispatchOp); } } void delete_event_data(gpointer data) { if (NULL != data) delete (EventData*) data; } void Approver::updateNotification(const QContact &contact) { if (!mPendingSnapDecision) return; QString displayLabel = ContactUtils::formatContactName(contact); QString avatar = contact.detail().imageUrl().toEncoded(); if (displayLabel.isEmpty()) { displayLabel = mDefaultTitle; } if (avatar.isEmpty()) { avatar = mDefaultIcon; } notify_notification_update(mPendingSnapDecision, displayLabel.toStdString().c_str(), mCachedBody.toStdString().c_str(), avatar.toStdString().c_str()); GError *error = NULL; if (!notify_notification_show(mPendingSnapDecision, &error)) { qWarning() << "Failed to show snap decision:" << error->message; g_error_free (error); } } void Approver::onChannelReady(Tp::PendingOperation *op) { Tp::PendingReady *pr = qobject_cast(op); if (!pr || !mChannels.contains(pr)) { qWarning() << "PendingOperation is not a PendingReady:" << op; return; } Tp::ChannelPtr channel = mChannels[pr]; Tp::ContactPtr contact = channel->initiatorContact(); Tp::ChannelDispatchOperationPtr dispatchOp = dispatchOperation(op); if (!dispatchOp) { return; } Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (!callChannel) { return; } bool isIncoming = channel->initiatorContact() != dispatchOp->connection()->selfContact(); if (isIncoming && !callChannel->isRequested() && callChannel->callState() == Tp::CallStateInitialised) { callChannel->setRinging(); } else { onApproved(dispatchOp); return; } connect(channel.data(), SIGNAL(callStateChanged(Tp::CallState)), SLOT(onCallStateChanged(Tp::CallState))); NotifyNotification* notification; /* initial notification */ EventData* data = new EventData(); data->self = this; data->dispatchOp = dispatchOp; data->channel = channel; if (!contact->id().isEmpty()) { if (contact->id().startsWith("x-ofono-private")) { mCachedBody = QString::fromUtf8(C::gettext("Calling from private number")); } else if (contact->id().startsWith("x-ofono-unknown")) { mCachedBody = QString::fromUtf8(C::gettext("Calling from unknown number")); } else { mCachedBody = QString::fromUtf8(C::gettext("Calling from %1")).arg(contact->id()); } } else { mCachedBody = C::gettext("Caller number is not available"); } notification = notify_notification_new (mDefaultTitle.toStdString().c_str(), mCachedBody.toStdString().c_str(), mDefaultIcon.toStdString().c_str()); notify_notification_set_hint_string(notification, "x-canonical-snap-decisions", "true"); notify_notification_set_hint_string(notification, "x-canonical-private-button-tint", "true"); QString acceptTitle = CallManager::instance()->hasCalls() ? C::gettext("Hold + Answer") : C::gettext("Accept"); notify_notification_add_action (notification, "action_accept", acceptTitle.toLocal8Bit().data(), action_accept, data, delete_event_data); // FIXME: uncomment this code once snap decisions support more than two actions and stacked buttons /* if (CallManager::instance()->hasCalls()) { notify_notification_add_action (notification, "action_hangup_and_accept", C::gettext("End + Answer"), action_hangup_and_accept, data, delete_event_data); } */ notify_notification_add_action (notification, "action_decline_1", C::gettext("Decline"), action_reject, data, delete_event_data); mPendingSnapDecision = notification; if (GreeterContacts::isGreeterMode()) { GreeterContacts::instance()->setContactFilter(QContactPhoneNumber::match(contact->id())); } else { // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(contact->id())); // lambda function to update the notification QObject::connect(request, &QContactAbstractRequest::resultsAvailable, [this, request]() { if (request && request->contacts().size() > 0) { // use the first match QContact contact = request->contacts().at(0); updateNotification(contact); // Also notify greeter via AccountsService GreeterContacts::emitContact(contact); } }); request->setManager(ContactUtils::sharedManager()); request->start(); } GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show snap decision:" << error->message; g_error_free (error); } // play a ringtone Ringtone::instance()->playIncomingCallSound(); mChannels.remove(pr); } void Approver::onApproved(Tp::ChannelDispatchOperationPtr dispatchOp) { closeSnapDecision(); // forward the channel to the handler dispatchOp->handleWith(TELEPHONY_SERVICE_HANDLER); // and then launch the dialer-app ApplicationUtils::openUrl(QUrl("application:///dialer-app.desktop")); mDispatchOps.removeAll(dispatchOp); } void Approver::onHangUpAndApproved(Tp::ChannelDispatchOperationPtr dispatchOp) { closeSnapDecision(); // hangup existing calls if (CallManager::instance()->foregroundCall()) { CallManager::instance()->foregroundCall()->endCall(); } // forward the channel to the handler dispatchOp->handleWith(TELEPHONY_SERVICE_HANDLER); // and then launch the dialer-app ApplicationUtils::openUrl(QUrl("application:///dialer-app.desktop")); mDispatchOps.removeAll(dispatchOp); } void Approver::onRejected(Tp::ChannelDispatchOperationPtr dispatchOp) { Tp::PendingOperation *claimop = dispatchOp->claim(); // assume there is just one channel in the dispatchOp for calls mChannels[claimop] = dispatchOp->channels().first(); connect(claimop, SIGNAL(finished(Tp::PendingOperation*)), this, SLOT(onClaimFinished(Tp::PendingOperation*))); Ringtone::instance()->stopIncomingCallSound(); } Tp::ChannelDispatchOperationPtr Approver::dispatchOperationForIncomingCall() { Tp::ChannelDispatchOperationPtr callDispatchOp; // find the call channel in the dispatch operations Q_FOREACH(Tp::ChannelDispatchOperationPtr dispatchOp, mDispatchOps) { Q_FOREACH(Tp::ChannelPtr channel, dispatchOp->channels()) { Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); // FIXME: maybe we need to check the call state too? if (!callChannel.isNull()) { callDispatchOp = dispatchOp; break; } } if (!callDispatchOp.isNull()) { break; } } return callDispatchOp; } void Approver::processChannels() { Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { // approve only text channels Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if (textChannel.isNull()) { continue; } if (dispatchOperation->possibleHandlers().contains(TELEPHONY_SERVICE_HANDLER)) { dispatchOperation->handleWith(TELEPHONY_SERVICE_HANDLER); mDispatchOps.removeAll(dispatchOperation); } // FIXME: this shouldn't happen, but in any case, we need to check what to do when // the phone app client is not available } } } void Approver::onClaimFinished(Tp::PendingOperation* op) { if(!op || op->isError()) { qDebug() << "onClaimFinished() error"; // TODO do something return; } Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(mChannels[op]); if (callChannel) { Tp::PendingOperation *hangupop = callChannel->hangup(Tp::CallStateChangeReasonUserRequested, TP_QT_ERROR_REJECTED, QString()); CallNotification::instance()->showNotificationForCall(QStringList() << callChannel->targetContact()->id(), CallNotification::CallRejected); mChannels[hangupop] = callChannel; connect(hangupop, SIGNAL(finished(Tp::PendingOperation*)), this, SLOT(onHangupFinished(Tp::PendingOperation*))); } } void Approver::onHangupFinished(Tp::PendingOperation* op) { if(!op || op->isError()) { qDebug() << "onHangupFinished() error"; // TODO do something return; } // FIXME: we do not call requestClose() here because // the channel will be forced to close without emiting the proper // stateChanged() signals. This would cause the app // not to register call events as it would never receive the // "ended" state. Better to check how other connection // managers deal with this case. mDispatchOps.removeAll(dispatchOperation(op)); mChannels.remove(op); } void Approver::onCallStateChanged(Tp::CallState state) { Tp::CallChannel *channel = qobject_cast(sender()); if (!channel) { return; } Tp::ChannelDispatchOperationPtr dispatchOperation; Q_FOREACH(const Tp::ChannelDispatchOperationPtr &otherDispatchOperation, mDispatchOps) { Q_FOREACH(const Tp::ChannelPtr &otherChannel, otherDispatchOperation->channels()) { if (otherChannel.data() == channel) { dispatchOperation = otherDispatchOperation; } } } if(dispatchOperation.isNull()) { return; } if (state == Tp::CallStateEnded) { mDispatchOps.removeAll(dispatchOperation); // remove all channels and pending operations Q_FOREACH(const Tp::ChannelPtr &otherChannel, dispatchOperation->channels()) { Tp::PendingOperation* op = mChannels.key(otherChannel); if(op) { mChannels.remove(op); } } closeSnapDecision(); } else if (state == Tp::CallStateActive) { onApproved(dispatchOperation); } } void Approver::closeSnapDecision() { if (mPendingSnapDecision != NULL) { notify_notification_close(mPendingSnapDecision, NULL); mPendingSnapDecision = NULL; } Ringtone::instance()->stopIncomingCallSound(); } void Approver::onHangupAndAcceptCallRequested() { if (!mPendingSnapDecision) { return; } Tp::ChannelDispatchOperationPtr callDispatchOp = dispatchOperationForIncomingCall(); if (!callDispatchOp.isNull()) { onHangUpAndApproved(callDispatchOp); } } void Approver::onAcceptCallRequested() { if (!mPendingSnapDecision) { return; } Tp::ChannelDispatchOperationPtr callDispatchOp = dispatchOperationForIncomingCall(); if (!callDispatchOp.isNull()) { onApproved(callDispatchOp); } } void Approver::onRejectCallRequested() { if (!mPendingSnapDecision) { return; } Tp::ChannelDispatchOperationPtr callDispatchOp = dispatchOperationForIncomingCall(); if (!callDispatchOp.isNull()) { onRejected(callDispatchOp); } } telephony-service-0.1+14.04.20140415/approver/approverdbus.cpp0000644000015301777760000000316312323307402024472 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Ugo Riboni * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "approverdbus.h" #include "approveradaptor.h" // Qt #include static const char* DBUS_SERVICE = "com.canonical.Approver"; static const char* DBUS_OBJECT_PATH = "/com/canonical/Approver"; ApproverDBus::ApproverDBus(QObject* parent) : QObject(parent) { } ApproverDBus::~ApproverDBus() { } bool ApproverDBus::connectToBus() { bool ok = QDBusConnection::sessionBus().registerService(DBUS_SERVICE); if (!ok) { return false; } new TelephonyServiceApproverAdaptor(this); QDBusConnection::sessionBus().registerObject(DBUS_OBJECT_PATH, this); return true; } void ApproverDBus::HangUpAndAcceptCall() { Q_EMIT hangUpAndAcceptCallRequested(); } void ApproverDBus::AcceptCall() { Q_EMIT acceptCallRequested(); } void ApproverDBus::RejectCall() { Q_EMIT rejectCallRequested(); } telephony-service-0.1+14.04.20140415/approver/com.canonical.TelephonyServiceApprover.xml0000644000015301777760000000116312323307402031504 0ustar pbusernogroup00000000000000 telephony-service-0.1+14.04.20140415/icons/0000755000015301777760000000000012323310021020513 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/0000755000015301777760000000000012323310021024110 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/0000755000015301777760000000000012323310021025433 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/22/0000755000015301777760000000000012323310021025656 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/22/indicator-call.svg0000644000015301777760000000545212323307402031303 0ustar pbusernogroup00000000000000 image/svg+xml telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/24/0000755000015301777760000000000012323310021025660 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/24/indicator-call.svg0000644000015301777760000000546312323307402031307 0ustar pbusernogroup00000000000000 image/svg+xml telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/16/0000755000015301777760000000000012323310021025661 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-light/status/16/indicator-call.svg0000644000015301777760000000547112323307402031307 0ustar pbusernogroup00000000000000 image/svg+xml telephony-service-0.1+14.04.20140415/icons/hicolor/0000755000015301777760000000000012323310021022152 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/hicolor/48x48/0000755000015301777760000000000012323310021022751 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/hicolor/48x48/apps/0000755000015301777760000000000012323310021023714 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/hicolor/48x48/apps/telephony-service-message.png0000644000015301777760000000271612323307402031530 0ustar pbusernogroup00000000000000PNG  IHDR66EjtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp !9/@IDATxKAw%CP"(Ʈ]ZXAV9K:ѱ[tԿޤDB C {&tvsZuf߾3;%M57S7dY8F;PB" ; &tiZ(ȋbZZ8p8d(7~^CcGҺ269"ub.I~8v0Fh!A*zhv 1 ̧Z'`4^D51P_Z,Pw$!TNDig΃3C/6>ZnثA;{E|S W3vM3ʷ9qXVƋ/FK`qA4XX FrΡ>P 298Һ ;Pq umntVt-F-dahP*,X@}&m(dEY*hFqU̯PW9 ࡙fQ} ("B ($ Pvy@1("Bv"_BPZ$s9`دKIENDB`telephony-service-0.1+14.04.20140415/icons/hicolor/48x48/apps/telephony-service-call.png0000644000015301777760000000354112323307402031014 0ustar pbusernogroup00000000000000PNG  IHDR66EjtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp {QIDATxܚkHA24 "'EDe IY臤 ЇHzD/"`}H"IJ@KIF !3uˌx<̜h4j[(2D8턺O ōBN` 0`X&,U5[0[bh``^N bYu1On`5Ϫb5n69ˍ:E Up ڏzú*샚 i1s| ڀ T.W3tX*Miv\ZsQjx؉(Cm0EE)ITnTkAq@6e]\` GNlpCcݐ&DAvFV(Cc&xAiVhDPVVo76J]/_z̃drkϋQտdrK+dzPrO,>/gud9cKy;e'XJyP9T vPd l,WΗP8kDEzh|/[A~ z4Ex-* c}N\OB. 1;h|,s}nx$!ٲ:#Q^ Pվ} .CЛM] 0F { OBG}KYy2,r^|mL6 Z gc KޮIENDB`telephony-service-0.1+14.04.20140415/icons/CMakeLists.txt0000644000015301777760000000022712323307402023265 0ustar pbusernogroup00000000000000set(icon_DIRS hicolor ubuntu-mono-dark ubuntu-mono-light ) install(DIRECTORY ${icon_DIRS} DESTINATION ${CMAKE_INSTALL_DATADIR}/icons) telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/0000755000015301777760000000000012323310021023722 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/0000755000015301777760000000000012323310021025245 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/22/0000755000015301777760000000000012323310021025470 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/22/indicator-call.svg0000644000015301777760000000547212323307402031117 0ustar pbusernogroup00000000000000 image/svg+xml telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/24/0000755000015301777760000000000012323310021025472 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/24/indicator-call.svg0000644000015301777760000000547212323307402031121 0ustar pbusernogroup00000000000000 image/svg+xml telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/16/0000755000015301777760000000000012323310021025473 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/icons/ubuntu-mono-dark/status/16/indicator-call.svg0000644000015301777760000000551212323307402031115 0ustar pbusernogroup00000000000000 image/svg+xml telephony-service-0.1+14.04.20140415/cmake/0000755000015301777760000000000012323310021020460 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/cmake/modules/0000755000015301777760000000000012323310021022130 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/cmake/modules/FindLcov.cmake0000644000015301777760000000172012323307402024647 0ustar pbusernogroup00000000000000# - Find lcov # Will define: # # LCOV_EXECUTABLE - the lcov binary # GENHTML_EXECUTABLE - the genhtml executable # # Copyright (C) 2010 by Johannes Wienke # # 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, 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. # INCLUDE(FindPackageHandleStandardArgs) FIND_PROGRAM(LCOV_EXECUTABLE lcov) FIND_PROGRAM(GENHTML_EXECUTABLE genhtml) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lcov DEFAULT_MSG LCOV_EXECUTABLE GENHTML_EXECUTABLE) # only visible in advanced view MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE) telephony-service-0.1+14.04.20140415/cmake/modules/EnableCoverageReport.cmake0000644000015301777760000001531112323307402027202 0ustar pbusernogroup00000000000000# - Creates a special coverage build type and target on GCC. # # Defines a function ENABLE_COVERAGE_REPORT which generates the coverage target # for selected targets. Optional arguments to this function are used to filter # unwanted results using globbing expressions. Moreover targets with tests for # the source code can be specified to trigger regenerating the report if the # test has changed # # ENABLE_COVERAGE_REPORT(TARGETS target... [FILTER filter...] [TESTS test targets...]) # # To generate a coverage report first build the project with # CMAKE_BUILD_TYPE=coverage, then call make test and afterwards make coverage. # # The coverage report is based on gcov. Depending on the availability of lcov # a HTML report will be generated and/or an XML report of gcovr is found. # The generated coverage target executes all found solutions. Special targets # exist to create e.g. only the xml report: coverage-xml. # # Copyright (C) 2010 by Johannes Wienke # # 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, 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. # INCLUDE(ParseArguments) FIND_PACKAGE(Lcov) FIND_PACKAGE(gcovr) FUNCTION(ENABLE_COVERAGE_REPORT) # argument parsing PARSE_ARGUMENTS(ARG "FILTER;TARGETS;TESTS" "" ${ARGN}) SET(COVERAGE_RAW_FILE "${CMAKE_BINARY_DIR}/coverage.raw.info") SET(COVERAGE_FILTERED_FILE "${CMAKE_BINARY_DIR}/coverage.info") SET(COVERAGE_REPORT_DIR "${CMAKE_BINARY_DIR}/coveragereport") SET(COVERAGE_XML_FILE "${CMAKE_BINARY_DIR}/coverage.xml") SET(COVERAGE_XML_COMMAND_FILE "${CMAKE_BINARY_DIR}/coverage-xml.cmake") # decide if there is any tool to create coverage data SET(TOOL_FOUND FALSE) IF(LCOV_FOUND OR GCOVR_FOUND) SET(TOOL_FOUND TRUE) ENDIF() IF(NOT TOOL_FOUND) MESSAGE(STATUS "Cannot enable coverage targets because neither lcov nor gcovr are found.") ENDIF() STRING(TOLOWER "${CMAKE_BUILD_TYPE}" COVERAGE_BUILD_TYPE) IF(CMAKE_COMPILER_IS_GNUCXX AND TOOL_FOUND AND "${COVERAGE_BUILD_TYPE}" MATCHES "coverage") MESSAGE(STATUS "Coverage support enabled for targets: ${ARG_TARGETS}") # create coverage build type SET(CMAKE_CXX_FLAGS_COVERAGE ${CMAKE_CXX_FLAGS_DEBUG} PARENT_SCOPE) SET(CMAKE_C_FLAGS_COVERAGE ${CMAKE_C_FLAGS_DEBUG} PARENT_SCOPE) SET(CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES} coverage PARENT_SCOPE) # instrument targets SET_TARGET_PROPERTIES(${ARG_TARGETS} PROPERTIES COMPILE_FLAGS --coverage LINK_FLAGS --coverage) # html report IF (LCOV_FOUND) MESSAGE(STATUS "Enabling HTML coverage report") # set up coverage target ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_RAW_FILE} COMMAND ${LCOV_EXECUTABLE} -c -d ${CMAKE_BINARY_DIR} -o ${COVERAGE_RAW_FILE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Collecting coverage data" DEPENDS ${ARG_TARGETS} ${ARG_TESTS} VERBATIM) # filter unwanted stuff LIST(LENGTH ARG_FILTER FILTER_LENGTH) IF(${FILTER_LENGTH} GREATER 0) SET(FILTER COMMAND ${LCOV_EXECUTABLE}) FOREACH(F ${ARG_FILTER}) SET(FILTER ${FILTER} -r ${COVERAGE_FILTERED_FILE} ${F}) ENDFOREACH() SET(FILTER ${FILTER} -o ${COVERAGE_FILTERED_FILE}) ELSE() SET(FILTER "") ENDIF() ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_FILTERED_FILE} COMMAND ${LCOV_EXECUTABLE} -e ${COVERAGE_RAW_FILE} "${CMAKE_SOURCE_DIR}*" -o ${COVERAGE_FILTERED_FILE} ${FILTER} DEPENDS ${COVERAGE_RAW_FILE} COMMENT "Filtering recorded coverage data for project-relevant entries" VERBATIM) ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_REPORT_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_REPORT_DIR} COMMAND ${GENHTML_EXECUTABLE} --legend --show-details -t "${PROJECT_NAME} test coverage" -o ${COVERAGE_REPORT_DIR} ${COVERAGE_FILTERED_FILE} DEPENDS ${COVERAGE_FILTERED_FILE} COMMENT "Generating HTML coverage report in ${COVERAGE_REPORT_DIR}" VERBATIM) ADD_CUSTOM_TARGET(coverage-html DEPENDS ${COVERAGE_REPORT_DIR}) ENDIF() # xml coverage report IF(GCOVR_FOUND) MESSAGE(STATUS "Enabling XML coverage report") # gcovr cannot write directly to a file so the execution needs to # be wrapped in a cmake file that generates the file output FILE(WRITE ${COVERAGE_XML_COMMAND_FILE} "SET(ENV{LANG} en)\n") FILE(APPEND ${COVERAGE_XML_COMMAND_FILE} "EXECUTE_PROCESS(COMMAND \"${GCOVR_EXECUTABLE}\" -x -r \"${CMAKE_SOURCE_DIR}\" OUTPUT_FILE \"${COVERAGE_XML_FILE}\" WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")\n") ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_XML_FILE} COMMAND ${CMAKE_COMMAND} ARGS -P ${COVERAGE_XML_COMMAND_FILE} COMMENT "Generating coverage XML report" VERBATIM) ADD_CUSTOM_TARGET(coverage-xml DEPENDS ${COVERAGE_XML_FILE}) ENDIF() # provide a global coverage target executing both steps if available SET(GLOBAL_DEPENDS "") IF(LCOV_FOUND) LIST(APPEND GLOBAL_DEPENDS ${COVERAGE_REPORT_DIR}) ENDIF() IF(GCOVR_FOUND) LIST(APPEND GLOBAL_DEPENDS ${COVERAGE_XML_FILE}) ENDIF() IF(LCOV_FOUND OR GCOVR_FOUND) ADD_CUSTOM_TARGET(coverage DEPENDS ${GLOBAL_DEPENDS}) ENDIF() ENDIF() ENDFUNCTION() telephony-service-0.1+14.04.20140415/cmake/modules/Findgcovr.cmake0000644000015301777760000000170212323307402025064 0ustar pbusernogroup00000000000000# - Find gcovr scrip # Will define: # # GCOVR_EXECUTABLE - the gcovr script # # Uses: # # GCOVR_ROOT - root to search for the script # # Copyright (C) 2011 by Johannes Wienke # # 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, 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. # INCLUDE(FindPackageHandleStandardArgs) FIND_PROGRAM(GCOVR_EXECUTABLE gcovr HINTS ${GCOVR_ROOT} "${GCOVR_ROOT}/bin") FIND_PACKAGE_HANDLE_STANDARD_ARGS(gcovr DEFAULT_MSG GCOVR_EXECUTABLE) # only visible in advanced view MARK_AS_ADVANCED(GCOVR_EXECUTABLE) telephony-service-0.1+14.04.20140415/cmake/modules/ParseArguments.cmake0000644000015301777760000000340612323307402026106 0ustar pbusernogroup00000000000000# Parse arguments passed to a function into several lists separated by # upper-case identifiers and options that do not have an associated list e.g.: # # SET(arguments # hello OPTION3 world # LIST3 foo bar # OPTION2 # LIST1 fuz baz # ) # PARSE_ARGUMENTS(ARG "LIST1;LIST2;LIST3" "OPTION1;OPTION2;OPTION3" ${arguments}) # # results in 7 distinct variables: # * ARG_DEFAULT_ARGS: hello;world # * ARG_LIST1: fuz;baz # * ARG_LIST2: # * ARG_LIST3: foo;bar # * ARG_OPTION1: FALSE # * ARG_OPTION2: TRUE # * ARG_OPTION3: TRUE # # taken from http://www.cmake.org/Wiki/CMakeMacroParseArguments MACRO(PARSE_ARGUMENTS prefix arg_names option_names) SET(DEFAULT_ARGS) FOREACH(arg_name ${arg_names}) SET(${prefix}_${arg_name}) ENDFOREACH(arg_name) FOREACH(option ${option_names}) SET(${prefix}_${option} FALSE) ENDFOREACH(option) SET(current_arg_name DEFAULT_ARGS) SET(current_arg_list) FOREACH(arg ${ARGN}) SET(larg_names ${arg_names}) LIST(FIND larg_names "${arg}" is_arg_name) IF (is_arg_name GREATER -1) SET(${prefix}_${current_arg_name} ${current_arg_list}) SET(current_arg_name ${arg}) SET(current_arg_list) ELSE (is_arg_name GREATER -1) SET(loption_names ${option_names}) LIST(FIND loption_names "${arg}" is_option) IF (is_option GREATER -1) SET(${prefix}_${arg} TRUE) ELSE (is_option GREATER -1) SET(current_arg_list ${current_arg_list} ${arg}) ENDIF (is_option GREATER -1) ENDIF (is_arg_name GREATER -1) ENDFOREACH(arg) SET(${prefix}_${current_arg_name} ${current_arg_list}) ENDMACRO(PARSE_ARGUMENTS) telephony-service-0.1+14.04.20140415/Ubuntu/0000755000015301777760000000000012323310021020662 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/0000755000015301777760000000000012323310021022631 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/qmldir.in0000644000015301777760000000006412323307402024462 0ustar pbusernogroup00000000000000module Ubuntu.Telephony plugin telephonyservice-qml telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/conversationfeeditem.cpp0000644000015301777760000000445412323307402027572 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "conversationfeeditem.h" ConversationFeedItem::ConversationFeedItem(QObject *parent) : QObject(parent), mIncoming(false), mNewItem(false) { } ConversationFeedItem::~ConversationFeedItem() { } QString ConversationFeedItem::contactId() const { return mContactId; } void ConversationFeedItem::setContactId(const QString &value) { mContactId = value; Q_EMIT contactIdChanged(); } QString ConversationFeedItem::contactAlias() const { return mContactAlias; } void ConversationFeedItem::setContactAlias(const QString &value) { mContactAlias = value; Q_EMIT contactAliasChanged(); } QUrl ConversationFeedItem::contactAvatar() const { return mContactAvatar; } void ConversationFeedItem::setContactAvatar(const QUrl &value) { mContactAvatar = value; Q_EMIT contactAvatarChanged(); } bool ConversationFeedItem::incoming() const { return mIncoming; } void ConversationFeedItem::setIncoming(bool value) { mIncoming = value; Q_EMIT incomingChanged(); } bool ConversationFeedItem::newItem() const { return mNewItem; } void ConversationFeedItem::setNewItem(bool value) { mNewItem = value; Q_EMIT newItemChanged(); } QDateTime ConversationFeedItem::timestamp() const { return mTimestamp; } void ConversationFeedItem::setTimestamp(const QDateTime &value) { mTimestamp = value; Q_EMIT timestampChanged(); } void ConversationFeedItem::setPhoneNumber(const QString &phone) { mPhoneNumber = phone; Q_EMIT phoneNumberChanged(); } QString ConversationFeedItem::phoneNumber() { return mPhoneNumber; } telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/components.cpp0000644000015301777760000000500712323307402025535 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "components.h" #include "telepathyhelper.h" #include "callentry.h" #include "callmanager.h" #include "ussdmanager.h" #include "channelobserver.h" #include "chatmanager.h" #include "contactwatcher.h" #include #include #include void Components::initializeEngine(QQmlEngine *engine, const char *uri) { Q_ASSERT(engine); Q_UNUSED(uri); // Initialize telepathy types Tp::registerTypes(); //Tp::enableDebug(true); Tp::enableWarnings(true); mRootContext = engine->rootContext(); Q_ASSERT(mRootContext); connect(TelepathyHelper::instance(), SIGNAL(accountReady()), SLOT(onAccountReady())); mRootContext->setContextProperty("telepathyHelper", TelepathyHelper::instance()); mRootContext->setContextProperty("chatManager", ChatManager::instance()); mRootContext->setContextProperty("callManager", CallManager::instance()); mRootContext->setContextProperty("ussdManager", USSDManager::instance()); } void Components::registerTypes(const char *uri) { // @uri Telephony qmlRegisterUncreatableType(uri, 0, 1, "TelepathyHelper", "This is a singleton helper class"); qmlRegisterUncreatableType(uri, 0, 1, "CallEntry", "Objects of this type are created in CallManager and made available to QML for usage"); qmlRegisterType(uri, 0, 1, "ContactWatcher"); } void Components::onAccountReady() { // QTimer::singleShot() is used here to make sure the slots are executed in the correct thread. If we call the slots directly // the items created for those models will be on the wrong thread. //QTimer::singleShot(0, TelepathyLogReader::instance(), SLOT(fetchLog())); } telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/contactwatcher.cpp0000644000015301777760000001600012323307402026354 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "contactwatcher.h" #include "contactutils.h" #include "phoneutils.h" #include #include #include #include #include #include namespace C { #include } ContactWatcher::ContactWatcher(QObject *parent) : QObject(parent), mInteractive(true) { connect(ContactUtils::sharedManager(), SIGNAL(contactsAdded(QList)), SLOT(onContactsAdded(QList))); connect(ContactUtils::sharedManager(), SIGNAL(contactsChanged(QList)), SLOT(onContactsChanged(QList))); connect(ContactUtils::sharedManager(), SIGNAL(contactsRemoved(QList)), SLOT(onContactsRemoved(QList))); } void ContactWatcher::searchByPhoneNumber(const QString &phoneNumber) { QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(phoneNumber)); connect(request, SIGNAL(stateChanged(QContactAbstractRequest::State)), SLOT(onRequestStateChanged(QContactAbstractRequest::State))); connect(request, SIGNAL(resultsAvailable()), SLOT(resultsAvailable())); request->setManager(ContactUtils::sharedManager()); request->start(); } QString ContactWatcher::contactId() const { return mContactId; } QString ContactWatcher::avatar() const { return mAvatar; } QString ContactWatcher::alias() const { return mAlias; } QString ContactWatcher::phoneNumber() const { return mPhoneNumber; } QList ContactWatcher::phoneNumberSubTypes() const { return mPhoneNumberSubTypes; } QList ContactWatcher::phoneNumberContexts() const { return mPhoneNumberContexts; } void ContactWatcher::setPhoneNumber(const QString &phoneNumber) { const bool isPrivate = phoneNumber.startsWith("x-ofono-private"); const bool isUnknown = phoneNumber.startsWith("x-ofono-unknown"); mPhoneNumber = phoneNumber; mInteractive = true; Q_EMIT phoneNumberChanged(); if (mPhoneNumber.isEmpty() || isPrivate || isUnknown) { mAlias.clear(); mContactId.clear(); mAvatar.clear(); mPhoneNumberSubTypes.clear(); mPhoneNumberContexts.clear(); mInteractive = false; if (isPrivate) { mAlias = C::gettext("Private Number"); } else if (isUnknown) { mAlias = C::gettext("Unknown Number"); } Q_EMIT contactIdChanged(); Q_EMIT avatarChanged(); Q_EMIT aliasChanged(); Q_EMIT phoneNumberSubTypesChanged(); Q_EMIT phoneNumberContextsChanged(); Q_EMIT isUnknownChanged(); Q_EMIT interactiveChanged(); return; } Q_EMIT interactiveChanged(); searchByPhoneNumber(mPhoneNumber); } bool ContactWatcher::isUnknown() const { return mContactId.isEmpty(); } bool ContactWatcher::interactive() const { return mInteractive; } void ContactWatcher::onContactsAdded(QList ids) { // ignore this signal if we have a contact already // or if we have no phone number set if (!mContactId.isEmpty() || mPhoneNumber.isEmpty()) { return; } searchByPhoneNumber(mPhoneNumber); } void ContactWatcher::onContactsChanged(QList ids) { // check for changes even if we have this contact already, // as the number might have changed, thus invalidating the current contact if (!mPhoneNumber.isEmpty()) { searchByPhoneNumber(mPhoneNumber); } } void ContactWatcher::onContactsRemoved(QList ids) { bool currentContactRemoved = false; Q_FOREACH (const QContactId &contactId, ids) { if(contactId.toString() == mContactId) { currentContactRemoved = true; break; } } // if the current contact got removed, clear it before trying to search for a new one if (currentContactRemoved) { mAlias.clear(); mContactId.clear(); mAvatar.clear(); mPhoneNumberSubTypes.clear(); mPhoneNumberContexts.clear(); Q_EMIT contactIdChanged(); Q_EMIT avatarChanged(); Q_EMIT aliasChanged(); Q_EMIT phoneNumberSubTypesChanged(); Q_EMIT phoneNumberContextsChanged(); Q_EMIT isUnknownChanged(); if (!mPhoneNumber.isEmpty()) { searchByPhoneNumber(mPhoneNumber); } } } void ContactWatcher::resultsAvailable() { QContactFetchRequest *request = qobject_cast(sender()); if (request && request->contacts().size() > 0) { // use the first match QContact contact = request->contacts().at(0); mContactId = contact.id().toString(); mAvatar = QContactAvatar(contact.detail(QContactDetail::TypeAvatar)).imageUrl().toString(); mAlias = ContactUtils::formatContactName(contact); Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) { if (PhoneUtils::comparePhoneNumbers(phoneNumber.number(), mPhoneNumber)) { mPhoneNumberSubTypes = phoneNumber.subTypes(); mPhoneNumberContexts = phoneNumber.contexts(); } } Q_EMIT contactIdChanged(); Q_EMIT avatarChanged(); Q_EMIT aliasChanged(); Q_EMIT phoneNumberSubTypesChanged(); Q_EMIT phoneNumberContextsChanged(); Q_EMIT isUnknownChanged(); } } void ContactWatcher::onRequestStateChanged(QContactAbstractRequest::State state) { QContactFetchRequest *request = qobject_cast(sender()); if (request && state == QContactAbstractRequest::FinishedState) { request->deleteLater(); // if we got no results and we had a contact previously, we need to clear the data if (request->contacts().isEmpty() && !mContactId.isEmpty()) { mAlias.clear(); mContactId.clear(); mAvatar.clear(); mPhoneNumberSubTypes.clear(); mPhoneNumberContexts.clear(); Q_EMIT contactIdChanged(); Q_EMIT avatarChanged(); Q_EMIT aliasChanged(); Q_EMIT phoneNumberSubTypesChanged(); Q_EMIT phoneNumberContextsChanged(); Q_EMIT isUnknownChanged(); } } } telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/tests/0000755000015301777760000000000012323310021023773 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/tests/CMakeLists.txt0000644000015301777760000000174112323307402026547 0ustar pbusernogroup00000000000000include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/Ubuntu/Telephony ) macro(generate_tests) foreach(test ${ARGN}) add_executable(${test} ${test}.cpp) qt5_use_modules(${test} Contacts Core DBus Qml Test) target_link_libraries(${test} telephonyservice-qml ) add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test} -platform offscreen -xunitxml -o ${CMAKE_BINARY_DIR}/test_${test}.xml) endforeach(test) endmacro(generate_tests) generate_tests( ContactWatcherTest ) file(GLOB QML_TESTS *.qml) # make the files visible on qtcreator add_custom_target(telephonyservice_QMLTESTS ALL SOURCES ${QML_TESTS}) # FIXME: those tests are disabled because qmltestrunner is crashing on armhf. # They should be re-enabled once the problem is found and fixed. #add_test(qmltests qmltestrunner -input ${CMAKE_CURRENT_SOURCE_DIR} -import ${CMAKE_BINARY_DIR} -xunitxml -o ${CMAKE_BINARY_DIR}/test_qmltests.xml) telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/tests/tst_contextProperties.qml0000644000015301777760000000223512323307402031154 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Telephony 0.1 TestCase { id: contextPropertiesTest name: "ContextPropertiesTest" function test_telepathyHelper() { verify(telepathyHelper != undefined, "telepathyHelper is not defined"); } function test_chatManager() { verify(chatManager != undefined, "chatManager is not defined"); } function test_callManager() { verify(callManager != undefined, "callManager is not defined"); } } telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/tests/ContactWatcherTest.cpp0000644000015301777760000004036512323307402030271 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include #include "contactwatcher.h" #include "contactutils.h" #include #include #include QTCONTACTS_USE_NAMESPACE class ContactWatcherTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testPhoneNumber(); void testMatchExistingContact(); void testMatchNewContact(); void testMatchContactChanged(); void testClearAfterContactChanged(); void testContactRemoval(); void testClearPhoneNumber(); void testInteractiveProperty_data(); void testInteractiveProperty(); private: QContact createContact(const QString &firstName, const QString &lastName, const QString &avatarUrl, const QStringList &phoneNumbers, const QList &subTypes, const QList &contexts); void clearManager(); QContactManager *mManager; }; void ContactWatcherTest::initTestCase() { // instanciate the shared manager using the memory backend mManager = ContactUtils::sharedManager("memory"); } void ContactWatcherTest::testPhoneNumber() { QString phoneNumber("123456"); ContactWatcher watcher; QSignalSpy spy(&watcher, SIGNAL(phoneNumberChanged())); watcher.setPhoneNumber(phoneNumber); QCOMPARE(spy.count(), 1); QCOMPARE(watcher.phoneNumber(), phoneNumber); } void ContactWatcherTest::testMatchExistingContact() { QString phoneNumber("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << phoneNumber, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged())); QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // set the phone number and wait for the match to happen watcher.setPhoneNumber(phoneNumber); // contact fetching is asynchronous so use QTRY_COMPARE for the first signal spy // for the subsequent ones it is fine to use just QCOMPARE QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(contextsSpy.count(), 1); QCOMPARE(subTypesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly set QCOMPARE(watcher.contactId(), contact.id().toString()); QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact)); QCOMPARE(watcher.avatar(), contact.detail().imageUrl().toString()); QCOMPARE(watcher.phoneNumberContexts(), contact.detail().contexts()); QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail().subTypes()); QCOMPARE(watcher.isUnknown(), false); clearManager(); } void ContactWatcherTest::testMatchNewContact() { QString phoneNumber("1234567"); ContactWatcher watcher; QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged())); QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); watcher.setPhoneNumber(phoneNumber); // now create the contact and wait to see if it gets matched QContact contact = createContact("FirstName", "LastName", "file://some_file", // just to make it a little more complicated, use a prefixed phone number QStringList() << phoneNumber.prepend("+1"), QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); // contact fetching is asynchronous so use QTRY_COMPARE for the first signal spy // for the subsequent ones it is fine to use just QCOMPARE QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(contextsSpy.count(), 1); QCOMPARE(subTypesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly set QCOMPARE(watcher.contactId(), contact.id().toString()); QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact)); QCOMPARE(watcher.avatar(), contact.detail().imageUrl().toString()); QCOMPARE(watcher.phoneNumberContexts(), contact.detail().contexts()); QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail().subTypes()); QCOMPARE(watcher.isUnknown(), false); clearManager(); } void ContactWatcherTest::testMatchContactChanged() { QString phoneNumber("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << "456456456", // a different phone number QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; watcher.setPhoneNumber(phoneNumber); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged())); QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // now modify the contact´s phone number so that it matches QContactPhoneNumber number = contact.detail(); number.setNumber(phoneNumber); contact.saveDetail(&number); mManager->saveContact(&contact); // contact fetching is asynchronous so use QTRY_COMPARE for the first signal spy // for the subsequent ones it is fine to use just QCOMPARE QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(contextsSpy.count(), 1); QCOMPARE(subTypesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly set QCOMPARE(watcher.contactId(), contact.id().toString()); QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact)); QCOMPARE(watcher.avatar(), contact.detail().imageUrl().toString()); QCOMPARE(watcher.phoneNumberContexts(), contact.detail().contexts()); QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail().subTypes()); QCOMPARE(watcher.isUnknown(), false); clearManager(); } void ContactWatcherTest::testClearAfterContactChanged() { // after modifying a contact, if the phone number doesn´t match anymore, the data should be cleared // verify that this happens, but first we need to make sure the match actually happened QString phoneNumber("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << phoneNumber, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); // set the phone number and wait for the match to happen watcher.setPhoneNumber(phoneNumber); // at this point we just need to make sure the contactId is correct, the other fields // are tested in a separate test QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(watcher.contactId(), contact.id().toString()); contactIdSpy.clear(); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged())); QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // now modify the contact´s phone number so that it doesn´t match anymore QContactPhoneNumber number = contact.detail(); number.setNumber("43345476"); contact.saveDetail(&number); mManager->saveContact(&contact); QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(contextsSpy.count(), 1); QCOMPARE(subTypesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly cleared QCOMPARE(watcher.contactId(), QString("")); QCOMPARE(watcher.alias(), QString("")); QCOMPARE(watcher.avatar(), QString("")); QCOMPARE(watcher.phoneNumberContexts().count(), 0); QCOMPARE(watcher.phoneNumberSubTypes().count(), 0); QCOMPARE(watcher.isUnknown(), true); clearManager(); } void ContactWatcherTest::testContactRemoval() { // after removing a contact, the contact match should be cleared // verify that this happens, but first we need to make sure the match actually happened QString phoneNumber("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << phoneNumber, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); // set the phone number and wait for the match to happen watcher.setPhoneNumber(phoneNumber); // at this point we just need to make sure the contactId is correct, the other fields // are tested in a separate test QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(watcher.contactId(), contact.id().toString()); contactIdSpy.clear(); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged())); QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // now remove the contact mManager->removeContact(contact.id()); QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(contextsSpy.count(), 1); QCOMPARE(subTypesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly cleared QCOMPARE(watcher.contactId(), QString("")); QCOMPARE(watcher.alias(), QString("")); QCOMPARE(watcher.avatar(), QString("")); QCOMPARE(watcher.phoneNumberContexts().count(), 0); QCOMPARE(watcher.phoneNumberSubTypes().count(), 0); QCOMPARE(watcher.isUnknown(), true); clearManager(); } void ContactWatcherTest::testClearPhoneNumber() { // clearing a phone number should trigger the contact data to be cleared too // after removing a contact, the contact match should be cleared // verify that this happens, but first we need to make sure the match actually happened QString phoneNumber("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << phoneNumber, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); // set the phone number and wait for the match to happen watcher.setPhoneNumber(phoneNumber); // at this point we just need to make sure the contactId is correct, the other fields // are tested in a separate test QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(watcher.contactId(), contact.id().toString()); contactIdSpy.clear(); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged())); QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // now clear the phone number watcher.setPhoneNumber(""); QCOMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(contextsSpy.count(), 1); QCOMPARE(subTypesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly cleared QCOMPARE(watcher.contactId(), QString("")); QCOMPARE(watcher.alias(), QString("")); QCOMPARE(watcher.avatar(), QString("")); QCOMPARE(watcher.phoneNumberContexts().count(), 0); QCOMPARE(watcher.phoneNumberSubTypes().count(), 0); QCOMPARE(watcher.isUnknown(), true); clearManager(); } void ContactWatcherTest::testInteractiveProperty_data() { QTest::addColumn("phoneNumber"); QTest::addColumn("interactive"); QTest::newRow("valid phone number") << "98765432" << true; QTest::newRow("ofono private phone number") << "x-ofono-private" << false; QTest::newRow("ofono unknown number") << "x-ofono-unknown" << false; QTest::newRow("empty phone number") << "" << false; } void ContactWatcherTest::testInteractiveProperty() { QFETCH(QString, phoneNumber); QFETCH(bool, interactive); ContactWatcher watcher; QSignalSpy spy(&watcher, SIGNAL(interactiveChanged())); watcher.setPhoneNumber(phoneNumber); QCOMPARE(spy.count(), 1); QCOMPARE(watcher.interactive(), interactive); } QContact ContactWatcherTest::createContact(const QString &firstName, const QString &lastName, const QString &avatarUrl, const QStringList &phoneNumbers, const QList &subTypes, const QList &contexts) { QContact contact; // Name QContactName name; name.setFirstName(firstName); name.setLastName(lastName); contact.saveDetail(&name); // Avatar QContactAvatar avatar; avatar.setImageUrl(avatarUrl); contact.saveDetail(&avatar); Q_FOREACH(const QString &phoneNumber, phoneNumbers) { QContactPhoneNumber number; number.setNumber(phoneNumber); number.setSubTypes(subTypes); number.setContexts(contexts); contact.saveDetail(&number); } mManager->saveContact(&contact); return contact; } void ContactWatcherTest::clearManager() { Q_FOREACH(QContact contact, mManager->contacts()) { mManager->removeContact(contact.id()); } } QTEST_MAIN(ContactWatcherTest) #include "ContactWatcherTest.moc" telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/conversationfeeditem.h0000644000015301777760000000514112323307402027231 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CONVERSATIONFEEDITEM_H #define CONVERSATIONFEEDITEM_H #include #include #include class ConversationFeedItem : public QObject { Q_OBJECT Q_PROPERTY(QString contactId READ contactId WRITE setContactId NOTIFY contactIdChanged) Q_PROPERTY(QString contactAlias READ contactAlias WRITE setContactAlias NOTIFY contactAliasChanged) Q_PROPERTY(QUrl contactAvatar READ contactAvatar WRITE setContactAvatar NOTIFY contactAvatarChanged) Q_PROPERTY(bool incoming READ incoming WRITE setIncoming NOTIFY incomingChanged) Q_PROPERTY(bool newItem READ newItem WRITE setNewItem NOTIFY newItemChanged) Q_PROPERTY(QDateTime timestamp READ timestamp WRITE setTimestamp NOTIFY timestampChanged) Q_PROPERTY(QString phoneNumber READ phoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged) public: explicit ConversationFeedItem(QObject *parent = 0); virtual ~ConversationFeedItem(); QString contactId() const; void setContactId(const QString &value); QString contactAlias() const; void setContactAlias(const QString &value); QUrl contactAvatar() const; void setContactAvatar(const QUrl &value); bool incoming() const; void setIncoming(bool value); bool newItem() const; void setNewItem(bool value); QDateTime timestamp() const; void setTimestamp(const QDateTime &value); void setPhoneNumber(const QString &phone); QString phoneNumber(); Q_SIGNALS: void contactIdChanged(); void contactAliasChanged(); void contactAvatarChanged(); void incomingChanged(); void newItemChanged(); void timestampChanged(); void phoneNumberChanged(); private: QString mContactId; QString mContactAlias; QUrl mContactAvatar; bool mIncoming; bool mNewItem; QDateTime mTimestamp; QString mPhoneNumber; }; #endif // CONVERSATIONFEEDITEM_H telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/CMakeLists.txt0000644000015301777760000000125612323307402025406 0ustar pbusernogroup00000000000000# QML plugin set(plugin_SRCS contactwatcher.cpp components.cpp ) include_directories( ${TP_QT5_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libtelephonyservice ) add_library(telephonyservice-qml SHARED ${plugin_SRCS} ${plugin_HDRS}) qt5_use_modules(telephonyservice-qml Contacts Core Qml Quick) target_link_libraries(telephonyservice-qml ${TP_QT5_LIBRARIES} telephonyservice ) configure_file(qmldir.in ${CMAKE_CURRENT_BINARY_DIR}/qmldir) set(PLUGIN_DIR ${QT_INSTALL_QML}/Ubuntu/Telephony) install(TARGETS telephonyservice-qml DESTINATION ${PLUGIN_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir DESTINATION ${PLUGIN_DIR}) add_subdirectory(tests) telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/components.h0000644000015301777760000000236712323307402025210 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef COMPONENTS_H #define COMPONENTS_H #include #include class Components : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void initializeEngine(QQmlEngine *engine, const char *uri); void registerTypes(const char *uri); private Q_SLOTS: void onAccountReady(); private: QQmlContext *mRootContext; }; #endif // COMPONENTS_H telephony-service-0.1+14.04.20140415/Ubuntu/Telephony/contactwatcher.h0000644000015301777760000000541112323307402026025 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CONTACTWATCHER_H #define CONTACTWATCHER_H #include #include #include QTCONTACTS_USE_NAMESPACE class ContactWatcher : public QObject { Q_OBJECT Q_PROPERTY(QString contactId READ contactId NOTIFY contactIdChanged) Q_PROPERTY(QString avatar READ avatar NOTIFY avatarChanged) Q_PROPERTY(QString alias READ alias NOTIFY aliasChanged) Q_PROPERTY(QString phoneNumber READ phoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged) Q_PROPERTY(QList phoneNumberSubTypes READ phoneNumberSubTypes NOTIFY phoneNumberSubTypesChanged) Q_PROPERTY(QList phoneNumberContexts READ phoneNumberContexts NOTIFY phoneNumberContextsChanged) Q_PROPERTY(bool isUnknown READ isUnknown NOTIFY isUnknownChanged) Q_PROPERTY(bool interactive READ interactive NOTIFY interactiveChanged) public: explicit ContactWatcher(QObject *parent = 0); QString contactId() const; QString avatar() const; QString alias() const; QString phoneNumber() const; void setPhoneNumber(const QString &phoneNumber); QList phoneNumberSubTypes() const; QList phoneNumberContexts() const; bool isUnknown() const; bool interactive() const; Q_SIGNALS: void contactIdChanged(); void avatarChanged(); void aliasChanged(); void phoneNumberChanged(); void phoneNumberSubTypesChanged(); void phoneNumberContextsChanged(); void isUnknownChanged(); void interactiveChanged(); protected Q_SLOTS: void onContactsAdded(QList ids); void onContactsChanged(QList ids); void onContactsRemoved(QList ids); void onRequestStateChanged(QContactAbstractRequest::State state); void resultsAvailable(); private: void searchByPhoneNumber(const QString &phoneNumber); QString mContactId; QString mAvatar; QString mAlias; QString mPhoneNumber; QList mPhoneNumberSubTypes; QList mPhoneNumberContexts; bool mInteractive; }; #endif // CONTACTWATCHER_H telephony-service-0.1+14.04.20140415/Ubuntu/CMakeLists.txt0000644000015301777760000000003412323307402023430 0ustar pbusernogroup00000000000000add_subdirectory(Telephony) telephony-service-0.1+14.04.20140415/upstart/0000755000015301777760000000000012323310021021102 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/upstart/telephony-service-indicator.conf0000644000015301777760000000031012323307402027373 0ustar pbusernogroup00000000000000description "telephony-service-indicator" author "Tiago Salem Herrmann " start on started unity8 stop on session-end respawn exec /usr/bin/telephony-service-indicator telephony-service-0.1+14.04.20140415/data/0000755000015301777760000000000012323310021020311 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/data/org.freedesktop.Notifications.xml0000644000015301777760000000350112323307402026754 0ustar pbusernogroup00000000000000 telephony-service-0.1+14.04.20140415/libtelephonyservice/0000755000015301777760000000000012323310021023457 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/libtelephonyservice/greetercontacts.h0000644000015301777760000000574212323307402027045 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Michael Terry * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef GREETERCONTACTS_H #define GREETERCONTACTS_H #include #include #include #include class QDBusPendingCallWatcher; /** * When running under the greeter, we don't have our own contacts database. * Instead, we query AccountsService for the information. */ class GreeterContacts : public QObject { Q_OBJECT public: static GreeterContacts *instance(); ~GreeterContacts(); void setContactFilter(const QtContacts::QContactFilter &filter); bool silentMode(); QString incomingCallSound(); QString incomingMessageSound(); static bool isGreeterMode(); // Records contact info for currently-logged-in user static void emitContact(const QtContacts::QContact &contact); // These are really implementation details, but are public for ease of unit testing static QVariantMap contactToMap(const QtContacts::QContact &contact); static QtContacts::QContact mapToContact(const QVariantMap &map); Q_SIGNALS: void contactUpdated(const QtContacts::QContact &contact); private Q_SLOTS: void greeterPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated); void accountsPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated, const QDBusMessage &message); void greeterGetEntryReply(QDBusPendingCallWatcher *watcher); void accountsGetUsersReply(QDBusPendingCallWatcher *watcher); void accountsGetContactReply(QDBusPendingCallWatcher *watcher); private: GreeterContacts(QObject *parent = 0); void queryEntry(); void queryContact(const QString &user); void updateActiveUser(const QString &username); QtContacts::QContact lookupContact(); void signalIfNeeded(); void checkUpdatedValue(const QVariantMap &changed, const QStringList &invalidated, const QString &propName, QVariant &propValue); QVariant getUserValue(const QString &interface, const QString &propName); QString mActiveUser; QVariant mSilentMode; QVariant mIncomingCallSound; QVariant mIncomingMessageSound; QtContacts::QContactFilter mFilter; QMap mContacts; static GreeterContacts *mInstance; }; #endif // GREETERCONTACTS_H telephony-service-0.1+14.04.20140415/libtelephonyservice/contactutils.cpp0000644000015301777760000000302212323307402026705 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "contactutils.h" #include QTCONTACTS_USE_NAMESPACE namespace ContactUtils { QContactManager *sharedManager(const QString &engine) { static QContactManager *instance = new QContactManager(engine); return instance; } // Note: update GreeterContacts::mapToContact() if this function is modified // to use more than just first and last names. QString formatContactName(const QContact &contact) { QContactName name = contact.detail(); QString formattedName = name.firstName(); // now check if we need an extra space to separate the first and last names if (!formattedName.isEmpty() && !name.lastName().isEmpty()) { formattedName.append(" "); } formattedName.append(name.lastName()); return formattedName; } } telephony-service-0.1+14.04.20140415/libtelephonyservice/ringtone.h0000644000015301777760000000343012323307402025466 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef RINGTONE_H #define RINGTONE_H #include #include #include #include #include #include #include #include #include #include class RingtoneWorker : public QObject { Q_OBJECT public: RingtoneWorker(QObject *parent = 0); public Q_SLOTS: void playIncomingCallSound(); void stopIncomingCallSound(); void playIncomingMessageSound(); void stopIncomingMessageSound(); private: QMediaPlayer mCallAudioPlayer; QMediaPlaylist mCallAudioPlaylist; QMediaPlayer mMessageAudioPlayer; }; class Ringtone : public QObject { Q_OBJECT public: ~Ringtone(); static Ringtone *instance(); public Q_SLOTS: void playIncomingCallSound(); void stopIncomingCallSound(); void playIncomingMessageSound(); void stopIncomingMessageSound(); private: explicit Ringtone(QObject *parent = 0); RingtoneWorker *mWorker; QThread mThread; }; #endif // RINGTONE_H telephony-service-0.1+14.04.20140415/libtelephonyservice/callmanager.cpp0000644000015301777760000002430512323307410026445 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "callmanager.h" #include "callentry.h" #include "telepathyhelper.h" #include #include #include typedef QMap dbusQMap; Q_DECLARE_METATYPE(dbusQMap) CallManager *CallManager::instance() { static CallManager *self = new CallManager(); return self; } CallManager::CallManager(QObject *parent) : QObject(parent), mNeedsUpdate(false), mConferenceCall(0) { connect(TelepathyHelper::instance(), SIGNAL(connectedChanged()), SLOT(onConnectedChanged())); connect(TelepathyHelper::instance(), SIGNAL(channelObserverUnregistered()), SLOT(onChannelObserverUnregistered())); connect(this, SIGNAL(hasCallsChanged()), SIGNAL(callsChanged())); } QList CallManager::takeCalls(const QList callChannels) { qDebug() << __PRETTY_FUNCTION__; QList entries; // run through the current calls and check which ones we find Q_FOREACH(CallEntry *entry, mCallEntries) { if (callChannels.contains(entry->channel())) { mCallEntries.removeAll(entry); entries << entry; entry->disconnect(this); } } // FIXME: check which of those signals we really need to emit here Q_EMIT hasCallsChanged(); Q_EMIT hasBackgroundCallChanged(); Q_EMIT foregroundCallChanged(); Q_EMIT backgroundCallChanged(); return entries; } void CallManager::addCalls(const QList entries) { Q_FOREACH (CallEntry *entry, entries) { if (!mCallEntries.contains(entry)) { mCallEntries << entry; } setupCallEntry(entry); } // FIXME: check which of those signals we really need to emit here Q_EMIT hasCallsChanged(); Q_EMIT hasBackgroundCallChanged(); Q_EMIT foregroundCallChanged(); Q_EMIT backgroundCallChanged(); } void CallManager::setupCallEntry(CallEntry *entry) { connect(entry, SIGNAL(callEnded()), SLOT(onCallEnded())); connect(entry, SIGNAL(heldChanged()), SIGNAL(foregroundCallChanged())); connect(entry, SIGNAL(activeChanged()), SIGNAL(foregroundCallChanged())); connect(entry, SIGNAL(heldChanged()), SIGNAL(backgroundCallChanged())); connect(entry, SIGNAL(activeChanged()), SIGNAL(hasBackgroundCallChanged())); connect(entry, SIGNAL(activeChanged()), SIGNAL(hasCallsChanged())); } void CallManager::onChannelObserverUnregistered() { // do not clear the manager right now, wait until the observer is re-registered // to avoid flickering in the UI mNeedsUpdate = true; } void CallManager::startCall(const QString &phoneNumber, const QString &accountId) { QString account = accountId; if (account.isNull()) { account = TelepathyHelper::instance()->accountIds()[0]; } QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("StartCall", phoneNumber, account); } void CallManager::onConnectedChanged() { if (!TelepathyHelper::instance()->connected()) { mVoicemailNumber = QString(); Q_EMIT voicemailNumberChanged(); return; } // FIXME: needs to handle voicemail numbers from multiple accounts Tp::ConnectionPtr conn(TelepathyHelper::instance()->accounts()[0]->connection()); if (conn.isNull()) { mVoicemailNumber = QString(); return; } QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusInterface connIface(busName, objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE); QDBusReply replyNumber = connIface.call("VoicemailNumber"); if (replyNumber.isValid()) { mVoicemailNumber = replyNumber.value(); Q_EMIT voicemailNumberChanged(); } } CallEntry *CallManager::foregroundCall() const { CallEntry *call = 0; // if we have only one call, return it as being always in foreground // even if it is held QList calls = activeCalls(); if (calls.count() == 1) { call = calls.first(); } else { Q_FOREACH(CallEntry *entry, calls) { if (!entry->isHeld()) { call = entry; break; } } } return call; } CallEntry *CallManager::backgroundCall() const { QList calls = activeCalls(); // if we have only one call, assume there is no call in background // even if the foreground call is held if (calls.count() == 1) { return 0; } Q_FOREACH(CallEntry *entry, calls) { if (entry->isHeld()) { return entry; } } return 0; } QList CallManager::activeCalls() const { QList calls; if (mConferenceCall) { calls << mConferenceCall; } Q_FOREACH(CallEntry *entry, mCallEntries) { if (entry->isActive() || entry->dialing()) { calls << entry; } } return calls; } QQmlListProperty CallManager::calls() { return QQmlListProperty(this, 0, callsCount, callAt); } bool CallManager::hasCalls() const { // check if the callmanager already has active calls if (activeCalls().count() > 0) { return true; } // if that's not the case, query the teleophony-service-handler for the availability of calls // this is done only to get the live call view on clients as soon as possible, even before the // telepathy observer is configured QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); QDBusReply reply = phoneAppHandler->call("HasCalls"); if (reply.isValid()) { return reply.value(); } return false; } bool CallManager::hasBackgroundCall() const { return activeCalls().count() > 1; } int CallManager::callsCount(QQmlListProperty *p) { return CallManager::instance()->activeCalls().count(); } CallEntry *CallManager::callAt(QQmlListProperty *p, int index) { return CallManager::instance()->activeCalls()[index]; } void CallManager::onCallChannelAvailable(Tp::CallChannelPtr channel) { // if this is the first call after re-registering the observer, clear the data if (mNeedsUpdate) { Q_FOREACH(CallEntry *entry, mCallEntries) { entry->deleteLater(); } mCallEntries.clear(); if (mConferenceCall) { mConferenceCall->deleteLater(); mConferenceCall = 0; } mNeedsUpdate = false; } CallEntry *entry = new CallEntry(channel, this); if (entry->phoneNumber() == getVoicemailNumber()) { entry->setVoicemail(true); } if (entry->isConference()) { // assume there can be only one conference call at any time for now mConferenceCall = entry; // check if any of the existing channels belong to the conference // if they do, move them to the conference QList entries = takeCalls(channel->conferenceChannels()); Q_FOREACH(CallEntry *entry, entries) { mConferenceCall->addCall(entry); } setupCallEntry(mConferenceCall); } else if (mConferenceCall && mConferenceCall->channel()->conferenceChannels().contains(channel)){ // if the call channel belongs to the conference, don't add it here, move it to the conference itself mConferenceCall->addCall(entry); } else { mCallEntries.append(entry); setupCallEntry(entry); } // FIXME: check which of those signals we really need to emit here Q_EMIT hasCallsChanged(); Q_EMIT hasBackgroundCallChanged(); Q_EMIT foregroundCallChanged(); Q_EMIT backgroundCallChanged(); } void CallManager::onCallEnded() { qDebug() << __PRETTY_FUNCTION__; // FIXME: handle multiple calls CallEntry *entry = qobject_cast(sender()); if (!entry) { return; } // at this point the entry should be removed if (entry == mConferenceCall) { mConferenceCall = 0; } else { mCallEntries.removeAll(entry); } Q_EMIT callEnded(entry); Q_EMIT hasCallsChanged(); Q_EMIT hasBackgroundCallChanged(); Q_EMIT foregroundCallChanged(); Q_EMIT backgroundCallChanged(); entry->deleteLater(); } QString CallManager::getVoicemailNumber() { return mVoicemailNumber; } void CallManager::mergeCalls(CallEntry *firstCall, CallEntry *secondCall) { QDBusInterface *handlerInterface = TelepathyHelper::instance()->handlerInterface(); // if there is already a conference call, just merge the remaining channels // in the existing conference if (firstCall->isConference() || secondCall->isConference()) { CallEntry *conferenceCall = firstCall->isConference() ? firstCall : secondCall; CallEntry *otherCall = firstCall->isConference() ? secondCall : firstCall; handlerInterface->call("MergeCall", conferenceCall->channel()->objectPath(), otherCall->channel()->objectPath()); } else { handlerInterface->call("CreateConferenceCall", QStringList() << firstCall->channel()->objectPath() << secondCall->channel()->objectPath()); } } void CallManager::splitCall(CallEntry *callEntry) { QDBusInterface *handlerInterface = TelepathyHelper::instance()->handlerInterface(); handlerInterface->call("SplitCall", callEntry->channel()->objectPath()); } telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/0000755000015301777760000000000012323310021024621 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/GreeterContactsTest.cpp0000644000015301777760000002104512323307402031274 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "greetercontacts.h" #include #include #include #include #include #include #include #include #include #include Q_DECLARE_METATYPE(QtContacts::QContact) // for QVariant's benefit QTCONTACTS_USE_NAMESPACE class GreeterContactsTest : public QObject { Q_OBJECT public: GreeterContactsTest(); public Q_SLOTS: void setFilter(); private Q_SLOTS: void initTestCase(); void cleanup(); void testContactToMap(); void testMapToContact(); void testInitialValues(); void testSignalOnFilter(); void testSignalOnEntry(); void testSignalOnEntryInvalidated(); void testSignalOnContacts(); void testSignalOnContactsInvalidated(); void testEmitContact(); private: void waitForUpdatedSignal(bool convertedPath = false); void makeGreeterContacts(); void waitForInitialQuery(); QContact makeTestContact(bool convertedPath = false); QVariantMap makeTestMap(); void setActiveEntry(const QString &entry); void setCurrentContact(const QVariantMap &map); void setUseInvalidated(const QString &path, const QString &interface, bool useInvalidated); GreeterContacts *mGreeterContacts; QSignalSpy *mSpy; }; GreeterContactsTest::GreeterContactsTest() : QObject() { } void GreeterContactsTest::initTestCase() { mGreeterContacts = NULL; mSpy = NULL; qRegisterMetaType(); } void GreeterContactsTest::cleanup() { if (mSpy) { delete mSpy; mSpy = NULL; } if (mGreeterContacts) { delete mGreeterContacts; mGreeterContacts = NULL; } setActiveEntry(""); setCurrentContact(QVariantMap()); setUseInvalidated("/list", "com.canonical.UnityGreeter.List", false); setUseInvalidated("/org/freedesktop/Accounts/User12345", "com.canonical.TelephonyServiceApprover", false); } void GreeterContactsTest::testContactToMap() { QVariantMap map = GreeterContacts::contactToMap(makeTestContact()); QVariantMap expectedMap = makeTestMap(); QCOMPARE(map, expectedMap); } void GreeterContactsTest::testMapToContact() { QContact contact = GreeterContacts::mapToContact(makeTestMap()); QContact expectedContact = makeTestContact(); QCOMPARE(contact, expectedContact); } void GreeterContactsTest::testInitialValues() { setActiveEntry("testuser"); setCurrentContact(makeTestMap()); makeGreeterContacts(); setFilter(); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnFilter() { setActiveEntry("testuser"); setCurrentContact(makeTestMap()); makeGreeterContacts(); waitForInitialQuery(); // setFilter might immediately send the signal, so wait until we can start the spy QTimer::singleShot(0, this, SLOT(setFilter())); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnEntry() { setCurrentContact(makeTestMap()); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setActiveEntry("testuser"); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnEntryInvalidated() { setCurrentContact(makeTestMap()); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setUseInvalidated("/list", "com.canonical.UnityGreeter.List", true); setActiveEntry("testuser"); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnContacts() { setActiveEntry("testuser"); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setCurrentContact(makeTestMap()); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnContactsInvalidated() { setActiveEntry("testuser"); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setUseInvalidated("/org/freedesktop/Accounts/User12345", "com.canonical.TelephonyServiceApprover", true); setCurrentContact(makeTestMap()); waitForUpdatedSignal(); } void GreeterContactsTest::testEmitContact() { setActiveEntry("testuser"); makeGreeterContacts(); setFilter(); waitForInitialQuery(); // this next line acts like setCurrentContact() because uid is set to 12345 GreeterContacts::emitContact(makeTestContact()); waitForUpdatedSignal(true); } QVariantMap GreeterContactsTest::makeTestMap() { QVariantMap map; map.insert("FirstName", QVariant("First")); map.insert("Image", QVariant(CMAKE_SOURCE_DIR "/icons/hicolor/48x48/apps/telephony-service-call.png")); map.insert("LastName", QVariant("Last")); map.insert("PhoneNumber", QVariant("555")); return map; } QContact GreeterContactsTest::makeTestContact(bool convertedPath) { // This is the same contact that the test server will give out. QContact contact; QContactAvatar avatarDetail; QString imagePath; if (convertedPath) { imagePath = qgetenv("XDG_GREETER_DATA_DIR") + "/telephony-service/contact-image"; } else { imagePath = CMAKE_SOURCE_DIR "/icons/hicolor/48x48/apps/telephony-service-call.png"; } avatarDetail.setValue(QContactAvatar::FieldImageUrl, QUrl::fromLocalFile(imagePath)); contact.saveDetail(&avatarDetail); QContactName nameDetail; nameDetail.setValue(QContactName::FieldFirstName, "First"); nameDetail.setValue(QContactName::FieldLastName, "Last"); contact.saveDetail(&nameDetail); QContactPhoneNumber numberDetail; numberDetail.setValue(QContactPhoneNumber::FieldNumber, "555"); contact.saveDetail(&numberDetail); return contact; } void GreeterContactsTest::setFilter() { mGreeterContacts->setContactFilter(QContactPhoneNumber::match("555")); } void GreeterContactsTest::setActiveEntry(const QString &entry) { QDBusInterface iface("com.canonical.UnityGreeter", "/list", "org.freedesktop.DBus.Properties", QDBusConnection::sessionBus()); QDBusReply reply = iface.call("Set", "com.canonical.UnityGreeter.List", "ActiveEntry", QVariant::fromValue(QDBusVariant(QVariant(entry)))); QVERIFY(reply.isValid()); } void GreeterContactsTest::setCurrentContact(const QVariantMap &map) { QDBusInterface iface("org.freedesktop.Accounts", "/org/freedesktop/Accounts/User12345", "org.freedesktop.DBus.Properties", QDBusConnection::sessionBus()); QDBusReply reply = iface.call("Set", "com.canonical.TelephonyServiceApprover", "CurrentContact", QVariant::fromValue(QDBusVariant(QVariant(map)))); QVERIFY(reply.isValid()); } void GreeterContactsTest::waitForInitialQuery() { QDBusInterface iface("org.freedesktop.Accounts", "/org/freedesktop/Accounts/User12345", "com.canonical.TelephonyServiceApprover", QDBusConnection::sessionBus()); QSignalSpy spy(&iface, SIGNAL(InitialQueriesDone())); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); } void GreeterContactsTest::makeGreeterContacts() { mGreeterContacts = GreeterContacts::instance(); mSpy = new QSignalSpy(mGreeterContacts, SIGNAL(contactUpdated(QtContacts::QContact))); } void GreeterContactsTest::waitForUpdatedSignal(bool convertedPath) { QVERIFY(mSpy->wait()); QCOMPARE(mSpy->count(), 1); QList arguments = mSpy->takeFirst(); QContact expectedContact = makeTestContact(convertedPath); QCOMPARE(arguments.at(0).value(), expectedContact); } void GreeterContactsTest::setUseInvalidated(const QString &path, const QString &interface, bool useInvalidated) { QDBusInterface iface("org.freedesktop.Accounts", path, interface, QDBusConnection::sessionBus()); QDBusReply reply = iface.call("SetUseInvalidated", useInvalidated); QVERIFY(reply.isValid()); } QTEST_MAIN(GreeterContactsTest) #include "GreeterContactsTest.moc" telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/GreeterContactsTestServer.cpp0000644000015301777760000001365612323307402032474 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include #include #include #include #include #include bool listGetCalled = false; bool userGetCalled = false; class AccountsInterface : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Accounts") public: AccountsInterface(QObject *parent = 0); Q_SCRIPTABLE QList ListCachedUsers() const; }; class TelepathyInterface : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.canonical.TelephonyServiceApprover") Q_PROPERTY(QVariantMap CurrentContact READ CurrentContact WRITE SetCurrentContact) Q_SIGNALS: Q_SCRIPTABLE void InitialQueriesDone(); // Only for testing public: TelepathyInterface(QObject *parent = 0); QVariantMap CurrentContact(); void SetCurrentContact(const QVariantMap &map); Q_SCRIPTABLE void SetUseInvalidated(bool useInvalidated); // only for testing bool mGetCalled; // only for testing private: QVariantMap mCurrentContact; bool mUseInvalidated; }; class ListInterface : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.canonical.UnityGreeter.List") Q_PROPERTY(QString ActiveEntry READ ActiveEntry WRITE SetActiveEntry) public: ListInterface(TelepathyInterface *telepathyInterface, QObject *parent = 0); QString ActiveEntry() const; void SetActiveEntry(const QString &entry); Q_SCRIPTABLE void SetUseInvalidated(bool useInvalidated); // only for testing bool mGetCalled; // only for testing private: QString mActiveEntry; TelepathyInterface *mTelepathyInterface; bool mUseInvalidated; }; AccountsInterface::AccountsInterface(QObject *parent) : QObject(parent) { } QList AccountsInterface::ListCachedUsers() const { return QList() << QDBusObjectPath("/org/freedesktop/Accounts/User12345"); } TelepathyInterface::TelepathyInterface(QObject *parent) : QObject(parent), mCurrentContact(), mUseInvalidated(false) { } QVariantMap TelepathyInterface::CurrentContact() { userGetCalled = true; if (userGetCalled && listGetCalled) Q_EMIT InitialQueriesDone(); return mCurrentContact; } void TelepathyInterface::SetCurrentContact(const QVariantMap &map) { mCurrentContact = map; // Now send out a manual changed signal, since Qt won't do it for us. QDBusMessage message; message = QDBusMessage::createSignal("/org/freedesktop/Accounts/User12345", "org.freedesktop.DBus.Properties", "PropertiesChanged"); message << "com.canonical.TelephonyServiceApprover"; if (mUseInvalidated) { QStringList invalidatedProps; invalidatedProps << "CurrentContact"; message << QVariantMap(); message << invalidatedProps; } else { QVariantMap changedProps; changedProps.insert("CurrentContact", QVariant(map)); message << changedProps; message << QStringList(); } QDBusConnection::sessionBus().send(message); } void TelepathyInterface::SetUseInvalidated(bool useInvalidated) { mUseInvalidated = useInvalidated; } ListInterface::ListInterface(TelepathyInterface *telepathyInterface, QObject *parent) : QObject(parent), mActiveEntry(), mTelepathyInterface(telepathyInterface), mUseInvalidated(false) { } QString ListInterface::ActiveEntry() const { listGetCalled = true; if (userGetCalled && listGetCalled && mTelepathyInterface) Q_EMIT mTelepathyInterface->InitialQueriesDone(); return mActiveEntry; } void ListInterface::SetActiveEntry(const QString &entry) { mActiveEntry = entry; // Now send out a manual changed signal, since Qt won't do it for us. QDBusMessage message; message = QDBusMessage::createSignal("/list", "org.freedesktop.DBus.Properties", "PropertiesChanged"); message << "com.canonical.UnityGreeter.List"; if (mUseInvalidated) { QStringList invalidatedProps; invalidatedProps << "ActiveEntry"; message << QVariantMap(); message << invalidatedProps; } else { QVariantMap changedProps; changedProps.insert("ActiveEntry", QVariant(entry)); message << changedProps; message << QStringList(); } QDBusConnection::sessionBus().send(message); } void ListInterface::SetUseInvalidated(bool useInvalidated) { mUseInvalidated = useInvalidated; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QDBusConnection connection = QDBusConnection::sessionBus(); AccountsInterface accounts; connection.registerObject("/org/freedesktop/Accounts", &accounts, QDBusConnection::ExportScriptableContents); TelepathyInterface telepathy; connection.registerObject("/org/freedesktop/Accounts/User12345", &telepathy, QDBusConnection::ExportScriptableContents); ListInterface list(&telepathy); connection.registerObject("/list", &list, QDBusConnection::ExportScriptableContents); connection.registerService("com.canonical.UnityGreeter"); connection.registerService("org.freedesktop.Accounts"); return a.exec(); } #include "GreeterContactsTestServer.moc" telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/PhoneUtilsTest.cpp0000644000015301777760000000707712323307402030303 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include #include "phoneutils.h" class PhoneUtilsTest : public QObject { Q_OBJECT private Q_SLOTS: void testIsPhoneNumber_data(); void testIsPhoneNumber(); void testComparePhoneNumbers_data(); void testComparePhoneNumbers(); }; void PhoneUtilsTest::testIsPhoneNumber_data() { QTest::addColumn("number"); QTest::addColumn("expectedResult"); QTest::newRow("simple number") << "12345678" << true; QTest::newRow("number with dash") << "1234-5678" << true; QTest::newRow("number with area code") << "(123)12345678" << true; QTest::newRow("number with extension") << "12345678#123" << true; QTest::newRow("number with comma") << "33333333,1,1" << true; QTest::newRow("number with semicolon") << "33333333;1" << true; QTest::newRow("short/emergency number") << "190" << true; QTest::newRow("non phone numbers") << "abcdefg" << false; } void PhoneUtilsTest::testIsPhoneNumber() { QFETCH(QString, number); QFETCH(bool, expectedResult); bool result = PhoneUtils::isPhoneNumber(number); QCOMPARE(result, expectedResult); } void PhoneUtilsTest::testComparePhoneNumbers_data() { QTest::addColumn("number1"); QTest::addColumn("number2"); QTest::addColumn("expectedResult"); QTest::newRow("string equal") << "12345678" << "12345678" << true; QTest::newRow("number with dash") << "1234-5678" << "12345678" << true; QTest::newRow("number with area code") << "12312345678" << "12345678" << true; QTest::newRow("number with extension") << "12345678#123" << "12345678" << false; QTest::newRow("both numbers with extension") << "(123)12345678#1" << "12345678#1" << true; QTest::newRow("numbers with different extension") << "1234567#1" << "1234567#2" << false; QTest::newRow("number with comma") << "33333333,1,1" << "33333333" << true; QTest::newRow("both numbers with comma") << "22222222,1" << "22222222,2,1" << true; QTest::newRow("number with semicolon") << "33333333;1" << "33333333" << true; QTest::newRow("both numbers with semicolon") << "22222222;1" << "22222222;2" << true; QTest::newRow("short/emergency numbers") << "190" << "190" << true; QTest::newRow("different numbers") << "12345678" << "1234567" << false; QTest::newRow("both non phone numbers") << "abcdefg" << "abcdefg" << true; QTest::newRow("different non phone numbers") << "abcdefg" << "bcdefg" << false; QTest::newRow("phone number and custom string") << "abc12345678" << "12345678" << false; // FIXME: check what other cases we need to test here" } void PhoneUtilsTest::testComparePhoneNumbers() { QFETCH(QString, number1); QFETCH(QString, number2); QFETCH(bool, expectedResult); bool result = PhoneUtils::comparePhoneNumbers(number1, number2); QCOMPARE(result, expectedResult); } QTEST_MAIN(PhoneUtilsTest) #include "PhoneUtilsTest.moc" telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/libsystem.c0000644000015301777760000000177612323307402027024 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include struct passwd * getpwnam (const char *name) { if (strcmp(name, "testuser") != 0) return 0; static struct passwd user_passwd = {0}; user_passwd.pw_name = "testuser"; user_passwd.pw_uid = 12345; user_passwd.pw_gid = 12345; return &user_passwd; } uid_t getuid () { return 12345; } telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/CMakeLists.txt0000644000015301777760000000330712323307402027375 0ustar pbusernogroup00000000000000include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/libtelephonyservice ) add_library(GreeterContactsLibSystem MODULE libsystem.c) set_target_properties(GreeterContactsLibSystem PROPERTIES OUTPUT_NAME system) add_executable(GreeterContactsTestServerExe GreeterContactsTestServer.cpp) qt5_use_modules(GreeterContactsTestServerExe Core DBus) add_executable(GreeterContactsTestExe GreeterContactsTest.cpp ../greetercontacts.cpp) set_target_properties(GreeterContactsTestExe PROPERTIES COMPILE_DEFINITIONS "AS_BUSNAME=sessionBus;CMAKE_SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\"") qt5_use_modules(GreeterContactsTestExe Contacts Core DBus Test) add_test(NAME GreeterContactsTest COMMAND env LD_PRELOAD=${CMAKE_CURRENT_BINARY_DIR}/libsystem.so XDG_SESSION_CLASS=greeter XDG_GREETER_DATA_DIR=${CMAKE_BINARY_DIR}/Testing/Temporary dbus-test-runner --task ${CMAKE_CURRENT_BINARY_DIR}/GreeterContactsTestServerExe --task-name server --ignore-return --task ${CMAKE_CURRENT_BINARY_DIR}/GreeterContactsTestExe --task-name test --wait-for org.freedesktop.Accounts DEPENDENCIES GreeterContactsTestServerExe GreeterContactsTestExe GreeterContactsLibSystem ) macro(generate_tests) foreach(test ${ARGN}) add_executable(${test} ${test}.cpp) qt5_use_modules(${test} Contacts Core DBus Qml Test) target_link_libraries(${test} telephonyservice ) add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test} -platform offscreen -xunitxml -o ${CMAKE_BINARY_DIR}/test_${test}.xml) endforeach(test) endmacro(generate_tests) generate_tests( ContactUtilsTest PhoneUtilsTest ) telephony-service-0.1+14.04.20140415/libtelephonyservice/tests/ContactUtilsTest.cpp0000644000015301777760000000410312323307402030610 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include #include "contactutils.h" #include QTCONTACTS_USE_NAMESPACE class ContactUtilsTest : public QObject { Q_OBJECT private Q_SLOTS: void testFormatContactName_data(); void testFormatContactName(); void testSharedManagerCreation(); }; void ContactUtilsTest::testFormatContactName_data() { QTest::addColumn("firstName"); QTest::addColumn("lastName"); QTest::addColumn("expectedResult"); QTest::newRow("full name") << "First" << "Last" << "First Last"; QTest::newRow("only first name") << "First" << "" << "First"; QTest::newRow("only last name") << "" << "Last" << "Last"; } void ContactUtilsTest::testFormatContactName() { QFETCH(QString, firstName); QFETCH(QString, lastName); QFETCH(QString, expectedResult); // create the contact QContact contact; QContactName contactName; contactName.setFirstName(firstName); contactName.setLastName(lastName); contact.saveDetail(&contactName); QString result = ContactUtils::formatContactName(contact); QCOMPARE(result, expectedResult); } void ContactUtilsTest::testSharedManagerCreation() { QContactManager *manager = ContactUtils::sharedManager("memory"); QVERIFY(manager); QCOMPARE(manager->managerName(), QString("memory")); } QTEST_MAIN(ContactUtilsTest) #include "ContactUtilsTest.moc" telephony-service-0.1+14.04.20140415/libtelephonyservice/telepathyhelper.cpp0000644000015301777760000002443712323307402027405 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "telepathyhelper.h" #include "chatmanager.h" #include "callmanager.h" #include "config.h" #include #include #include #include #include TelepathyHelper::TelepathyHelper(QObject *parent) : QObject(parent), mChannelObserver(0), mFirstTime(true), mConnected(false), mHandlerInterface(0) { mAccountFeatures << Tp::Account::FeatureCore; mContactFeatures << Tp::Contact::FeatureAlias << Tp::Contact::FeatureAvatarData << Tp::Contact::FeatureAvatarToken << Tp::Contact::FeatureCapabilities << Tp::Contact::FeatureSimplePresence; mConnectionFeatures << Tp::Connection::FeatureCore << Tp::Connection::FeatureSelfContact << Tp::Connection::FeatureSimplePresence; Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus()); channelFactory->addCommonFeatures(Tp::Channel::FeatureCore); // FIXME: at some point this needs to be fixed in tp-qt itself. channelFactory->setSubclassFor(audioConferenceSpec()); mAccountManager = Tp::AccountManager::create( Tp::AccountFactory::create(QDBusConnection::sessionBus(), mAccountFeatures), Tp::ConnectionFactory::create(QDBusConnection::sessionBus(), mConnectionFeatures), channelFactory, Tp::ContactFactory::create(mContactFeatures)); connect(mAccountManager->becomeReady(Tp::AccountManager::FeatureCore), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady(Tp::PendingOperation*))); mClientRegistrar = Tp::ClientRegistrar::create(mAccountManager); } TelepathyHelper::~TelepathyHelper() { } TelepathyHelper *TelepathyHelper::instance() { static TelepathyHelper* helper = new TelepathyHelper(); return helper; } QStringList TelepathyHelper::accountIds() { QStringList ids; if (QCoreApplication::applicationName() == "telephony-service-handler" || mAccounts.size() != 0) { Q_FOREACH(const Tp::AccountPtr &account, mAccounts) { ids << account->uniqueIdentifier(); } } else { QDBusReply reply = handlerInterface()->call("AccountIds"); if (reply.isValid()) { ids = reply.value(); } } return ids; } QList TelepathyHelper::accounts() const { return mAccounts; } ChannelObserver *TelepathyHelper::channelObserver() const { return mChannelObserver; } QDBusInterface *TelepathyHelper::handlerInterface() { if (!mHandlerInterface) { mHandlerInterface = new QDBusInterface("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "com.canonical.TelephonyServiceHandler", QDBusConnection::sessionBus(), this); } return mHandlerInterface; } bool TelepathyHelper::connected() const { return mConnected; } void TelepathyHelper::registerChannelObserver(const QString &observerName) { QString name = observerName; if (name.isEmpty()) { name = "TelephonyPluginObserver"; } if (mChannelObserver) { mChannelObserver->deleteLater(); } mChannelObserver = new ChannelObserver(this); registerClient(mChannelObserver, name); // messages connect(mChannelObserver, SIGNAL(textChannelAvailable(Tp::TextChannelPtr)), ChatManager::instance(), SLOT(onTextChannelAvailable(Tp::TextChannelPtr))); // calls connect(mChannelObserver, SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), CallManager::instance(), SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); Q_EMIT channelObserverCreated(mChannelObserver); } void TelepathyHelper::unregisterChannelObserver() { Tp::AbstractClientPtr clientPtr(mChannelObserver); if (clientPtr) { mClientRegistrar->unregisterClient(clientPtr); } mChannelObserver->deleteLater(); mChannelObserver = NULL; Q_EMIT channelObserverUnregistered(); } QStringList TelepathyHelper::supportedProtocols() const { QStringList protocols; protocols << "ufa" << "tel" << "ofono" << "mock"; // used for tests return protocols; } void TelepathyHelper::initializeAccount(const Tp::AccountPtr &account) { // watch for account state and connection changes connect(account.data(), &Tp::Account::stateChanged, [this, account](bool enabled) { if (!enabled) { ensureAccountEnabled(account); } }); connect(account.data(), &Tp::Account::connectionChanged, [this, account](const Tp::ConnectionPtr &connection) { if (connection.isNull()) { ensureAccountConnected(account); } else { watchSelfContactPresence(account); } updateConnectedStatus(); Q_EMIT connectionChanged(); }); // and make sure it is enabled and connected if (!account->isEnabled()) { ensureAccountEnabled(account); } else { ensureAccountConnected(account); } } void TelepathyHelper::ensureAccountEnabled(const Tp::AccountPtr &account) { account->setConnectsAutomatically(true); connect(account->setEnabled(true), &Tp::PendingOperation::finished, [this, account]() { ensureAccountConnected(account); }); } void TelepathyHelper::ensureAccountConnected(const Tp::AccountPtr &account) { // if the account is not connected, request it to connect if (!account->connection() || account->connectionStatus() != Tp::ConnectionStatusConnected) { Tp::Presence presence(Tp::ConnectionPresenceTypeAvailable, "available", "online"); account->setRequestedPresence(presence); } else { watchSelfContactPresence(account); } if (mFirstTime) { Q_EMIT accountReady(); mFirstTime = false; } } void TelepathyHelper::watchSelfContactPresence(const Tp::AccountPtr &account) { if (account.isNull() || account->connection().isNull()) { return; } connect(account->connection()->selfContact().data(), SIGNAL(presenceChanged(Tp::Presence)), SLOT(updateConnectedStatus())); updateConnectedStatus(); } void TelepathyHelper::registerClient(Tp::AbstractClient *client, QString name) { Tp::AbstractClientPtr clientPtr(client); bool succeeded = mClientRegistrar->registerClient(clientPtr, name); if (!succeeded) { name.append("%1"); int count = 0; // limit the number of registered clients to 20, that should be a safe margin while (!succeeded && count < 20) { succeeded = mClientRegistrar->registerClient(clientPtr, name.arg(++count)); if (succeeded) { name = name.arg(count); } } } if (succeeded) { QObject *object = dynamic_cast(client); if (object) { object->setProperty("clientName", TP_QT_IFACE_CLIENT + "." + name ); } } } Tp::AccountPtr TelepathyHelper::accountForConnection(const Tp::ConnectionPtr &connection) const { if (connection.isNull()) { return Tp::AccountPtr(); } Q_FOREACH(const Tp::AccountPtr &account, mAccounts) { if (account->connection() == connection) { return account; } } return Tp::AccountPtr(); } Tp::AccountPtr TelepathyHelper::accountForId(const QString &accountId) const { Q_FOREACH(const Tp::AccountPtr &account, mAccounts) { if (account->uniqueIdentifier() == accountId) { return account; } } return Tp::AccountPtr(); } bool TelepathyHelper::isAccountConnected(const Tp::AccountPtr &account) const { return !account.isNull() && !account->connection().isNull() && account->connection()->selfContact()->presence().type() == Tp::ConnectionPresenceTypeAvailable; } Tp::ChannelClassSpec TelepathyHelper::audioConferenceSpec() { static Tp::ChannelClassSpec spec; if (!spec.isValid()) { spec = Tp::ChannelClassSpec(TP_QT_IFACE_CHANNEL_TYPE_CALL, Tp::HandleTypeNone); spec.setCallInitialAudioFlag(); } return spec; } void TelepathyHelper::onAccountManagerReady(Tp::PendingOperation *op) { Q_UNUSED(op) Tp::AccountSetPtr accountSet; // try to find an account of the one of supported protocols Q_FOREACH(const QString &protocol, supportedProtocols()) { accountSet = mAccountManager->accountsByProtocol(protocol); if (accountSet->accounts().count() > 0) { mAccounts << accountSet->accounts(); } } if (mAccounts.count() == 0) { qCritical() << "No compatible telepathy account found!"; return; } Q_EMIT accountIdsChanged(); Q_FOREACH(const Tp::AccountPtr &account, mAccounts) { initializeAccount(account); } } void TelepathyHelper::updateConnectedStatus() { bool previousConnectedStatus = mConnected; mConnected = false; // check if any of the accounts is currently connected Q_FOREACH(const Tp::AccountPtr &account, mAccounts) { if (isAccountConnected(account)) { mConnected = true; break; } } // avoid emitting changed signals when the pro if (mConnected != previousConnectedStatus) { Q_EMIT connectedChanged(); } } telephony-service-0.1+14.04.20140415/libtelephonyservice/ussdmanager.cpp0000644000015301777760000002253612323307402026515 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "ussdmanager.h" #include "telepathyhelper.h" #include #include typedef QMap dbusQMap; Q_DECLARE_METATYPE(dbusQMap) USSDManager *USSDManager::instance() { static USSDManager *self = new USSDManager(); return self; } USSDManager::USSDManager(QObject *parent) : QObject(parent), mActive(false) { connect(TelepathyHelper::instance(), SIGNAL(connectedChanged()), SLOT(onConnectedChanged())); } void USSDManager::initiate(const QString &command, const QString &accountId) { Tp::AccountPtr account; if (accountId.isNull()) { account = TelepathyHelper::instance()->accounts()[0]; } else { account = TelepathyHelper::instance()->accountForId(accountId); } Tp::ConnectionPtr conn(account->connection()); QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE); ussdIface.asyncCall("Initiate", command); } void USSDManager::respond(const QString &reply, const QString &accountId) { Tp::AccountPtr account; if (accountId.isNull()) { account = TelepathyHelper::instance()->accounts()[0]; } else { account = TelepathyHelper::instance()->accountForId(accountId); } Tp::ConnectionPtr conn(account->connection()); QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE); ussdIface.asyncCall("Respond", reply); } void USSDManager::cancel(const QString &accountId) { Tp::AccountPtr account; if (accountId.isNull()) { account = TelepathyHelper::instance()->accounts()[0]; } else { account = TelepathyHelper::instance()->accountForId(accountId); } Tp::ConnectionPtr conn(account->connection()); QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE); ussdIface.asyncCall("Cancel"); } void USSDManager::disconnectAllSignals(const Tp::ConnectionPtr& conn) { QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "StateChanged", this, SLOT(onStateChanged(QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RequestReceived", this, SIGNAL(requestReceived(QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "NotificationReceived", this, SIGNAL(notificationReceived(QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateUSSDComplete", this, SIGNAL(initiateUSSDComplete(QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RespondComplete", this, SIGNAL(respondComplete(bool, QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "BarringComplete", this, SIGNAL(barringComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ForwardingComplete", this, SIGNAL(forwardingComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "WaitingComplete", this, SIGNAL(waitingComplete(QString, QVariantMap))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLinePresentationComplete", this, SIGNAL(callingLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLineRestrictionComplete", this, SIGNAL(callingLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLineRestrictionComplete", this, SIGNAL(connectedLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLinePresentationComplete", this, SIGNAL(connectedLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateFailed", this, SIGNAL(initiateFailed())); } void USSDManager::connectAllSignals(const Tp::ConnectionPtr& conn) { QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "StateChanged", this, SLOT(onStateChanged(QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RequestReceived", this, SIGNAL(requestReceived(QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "NotificationReceived", this, SIGNAL(notificationReceived(QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateUSSDComplete", this, SIGNAL(initiateUSSDComplete(QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RespondComplete", this, SIGNAL(respondComplete(bool, QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "BarringComplete", this, SIGNAL(barringComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ForwardingComplete", this, SIGNAL(forwardingComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "WaitingComplete", this, SIGNAL(waitingComplete(QString, QVariantMap))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLinePresentationComplete", this, SIGNAL(callingLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLineRestrictionComplete", this, SIGNAL(callingLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLineRestrictionComplete", this, SIGNAL(connectedLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLinePresentationComplete", this, SIGNAL(connectedLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().connect(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateFailed", this, SIGNAL(initiateFailed())); } void USSDManager::onConnectedChanged() { // everytime the connection changes we need to check if there is any ongoing ussd session mActive = false; mActiveAccountId = QString::null; mState = QString("idle"); if (!TelepathyHelper::instance()->connected()) { Q_EMIT stateChanged(mState); Q_EMIT activeChanged(); Q_EMIT activeAccountIdChanged(); return; } Q_FOREACH (const Tp::AccountPtr &account, TelepathyHelper::instance()->accounts()) { // disconnect all and reconnect only the online accounts Tp::ConnectionPtr conn(account->connection()); disconnectAllSignals(conn); if (TelepathyHelper::instance()->isAccountConnected(account)) { QString busName = conn->busName(); QString objectPath = conn->objectPath(); connectAllSignals(conn); QDBusInterface ussdIface(busName, objectPath, CANONICAL_TELEPHONY_USSD_IFACE); mState = ussdIface.property("State").toString(); mSerials[account->uniqueIdentifier()] = ussdIface.property("Serial").toString(); if (active()) { mActiveAccountId = account->uniqueIdentifier(); } } } Q_EMIT stateChanged(mState); Q_EMIT activeChanged(); Q_EMIT activeAccountIdChanged(); } void USSDManager::onStateChanged(const QString &state) { mState = state; Q_EMIT stateChanged(state); } bool USSDManager::active() const { return mState != "idle" && !mState.isEmpty(); } QString USSDManager::activeAccountId() const { return mActiveAccountId; } QString USSDManager::state() const { return mState; } QString USSDManager::serial(const QString &accountId) const { return mSerials[accountId]; } telephony-service-0.1+14.04.20140415/libtelephonyservice/callnotification.h0000644000015301777760000000232712323307402027167 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CALLNOTIFICATION_H #define CALLNOTIFICATION_H #include class CallNotification : public QObject { Q_OBJECT public: enum NotificationReason { CallHeld, CallEnded, CallRejected }; public Q_SLOTS: static CallNotification *instance(); void showNotificationForCall(const QStringList &participants, NotificationReason reason); private: explicit CallNotification(QObject *parent = 0); }; #endif // CALLNOTIFICATION_H telephony-service-0.1+14.04.20140415/libtelephonyservice/contactutils.h0000644000015301777760000000204312323307402026354 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CONTACTUTILS_H #define CONTACTUTILS_H #include #include QTCONTACTS_USE_NAMESPACE namespace ContactUtils { QContactManager *sharedManager(const QString &engine = "galera"); QString formatContactName(const QContact &contact); } #endif // CONTACTUTILS_H telephony-service-0.1+14.04.20140415/libtelephonyservice/chatmanager.h0000644000015301777760000000435112323307402026116 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CHATMANAGER_H #define CHATMANAGER_H #include #include #include #include class ChatManager : public QObject { Q_OBJECT public: static ChatManager *instance(); Q_INVOKABLE void sendMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId = QString::null); Q_SIGNALS: void messageReceived(const QString &phoneNumber, const QString &message, const QDateTime ×tamp, const QString &messageId, bool unread); void messageSent(const QString &phoneNumber, const QString &message); void unreadMessagesChanged(const QString &phoneNumber); public Q_SLOTS: void onTextChannelAvailable(Tp::TextChannelPtr channel); void onMessageReceived(const Tp::ReceivedMessage &message); void onPendingMessageRemoved(const Tp::ReceivedMessage &message); void onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message); void acknowledgeMessage(const QString &phoneNumber, const QString &messageId, const QString &accountId = QString::null); protected: Tp::TextChannelPtr existingChat(const QStringList &phoneNumbers, const QString &accountId); protected Q_SLOTS: void onAckTimerTriggered(); private: explicit ChatManager(QObject *parent = 0); QList mChannels; QMap > mMessagesToAck; QTimer mMessagesAckTimer; }; #endif // CHATMANAGER_H telephony-service-0.1+14.04.20140415/libtelephonyservice/ringtone.cpp0000644000015301777760000000551412323307402026026 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "greetercontacts.h" #include "ringtone.h" RingtoneWorker::RingtoneWorker(QObject *parent) : QObject(parent), mCallAudioPlayer(this), mCallAudioPlaylist(this), mMessageAudioPlayer(this) { mCallAudioPlaylist.setPlaybackMode(QMediaPlaylist::Loop); mCallAudioPlaylist.setCurrentIndex(0); } void RingtoneWorker::playIncomingCallSound() { if (GreeterContacts::instance()->silentMode()) { return; } if (mCallAudioPlayer.state() == QMediaPlayer::PlayingState) { return; } mCallAudioPlaylist.clear(); mCallAudioPlaylist.addMedia(QUrl::fromLocalFile(GreeterContacts::instance()->incomingCallSound())); mCallAudioPlayer.setPlaylist(&mCallAudioPlaylist); mCallAudioPlayer.play(); } void RingtoneWorker::stopIncomingCallSound() { mCallAudioPlayer.stop(); } void RingtoneWorker::playIncomingMessageSound() { if (GreeterContacts::instance()->silentMode()) { return; } if (mMessageAudioPlayer.state() == QMediaPlayer::PlayingState) { return; } mMessageAudioPlayer.setMedia(QUrl::fromLocalFile(GreeterContacts::instance()->incomingMessageSound())); mMessageAudioPlayer.play(); } void RingtoneWorker::stopIncomingMessageSound() { mMessageAudioPlayer.stop(); } Ringtone::Ringtone(QObject *parent) : QObject(parent) { mWorker = new RingtoneWorker(this); mWorker->moveToThread(&mThread); mThread.start(); } Ringtone::~Ringtone() { mThread.quit(); mThread.wait(); } Ringtone *Ringtone::instance() { static Ringtone *self = new Ringtone(); return self; } void Ringtone::playIncomingCallSound() { QMetaObject::invokeMethod(mWorker, "playIncomingCallSound", Qt::QueuedConnection); } void Ringtone::stopIncomingCallSound() { QMetaObject::invokeMethod(mWorker, "stopIncomingCallSound", Qt::QueuedConnection); } void Ringtone::playIncomingMessageSound() { QMetaObject::invokeMethod(mWorker, "playIncomingMessageSound", Qt::QueuedConnection); } void Ringtone::stopIncomingMessageSound() { QMetaObject::invokeMethod(mWorker, "stopIncomingMessageSound", Qt::QueuedConnection); } telephony-service-0.1+14.04.20140415/libtelephonyservice/greetercontacts.cpp0000644000015301777760000003152312323307402027374 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Michael Terry * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "greetercontacts.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include QTCONTACTS_USE_NAMESPACE GreeterContacts *GreeterContacts::mInstance = nullptr; GreeterContacts *GreeterContacts::instance() { if (!mInstance) mInstance = new GreeterContacts(); return mInstance; } GreeterContacts::GreeterContacts(QObject *parent) : QObject(parent), mActiveUser(), mFilter(QContactInvalidFilter()), mContacts() { // Watch for changes QDBusConnection connection = QDBusConnection::AS_BUSNAME(); connection.connect("org.freedesktop.Accounts", nullptr, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(accountsPropertiesChanged(QString, QVariantMap, QStringList, QDBusMessage))); // Are we in greeter mode or not? if (isGreeterMode()) { connection = QDBusConnection::sessionBus(); connection.connect("com.canonical.UnityGreeter", "/list", "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(greeterPropertiesChanged(QString, QVariantMap, QStringList))); QDBusInterface iface("org.freedesktop.Accounts", "/org/freedesktop/Accounts", "org.freedesktop.Accounts", QDBusConnection::AS_BUSNAME()); QDBusPendingCall call = iface.asyncCall("ListCachedUsers"); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this, SLOT(accountsGetUsersReply(QDBusPendingCallWatcher *))); queryEntry(); } else { QString uid = QString::number(getuid()); mActiveUser = "/org/freedesktop/Accounts/User" + uid; } } GreeterContacts::~GreeterContacts() { if (mInstance == this) { mInstance = nullptr; } } bool GreeterContacts::isGreeterMode() { return qgetenv("XDG_SESSION_CLASS") == "greeter"; } void GreeterContacts::setContactFilter(const QContactFilter &filter) { mFilter = filter; signalIfNeeded(); } bool GreeterContacts::silentMode() { if (!mSilentMode.isValid()) { mSilentMode = getUserValue("com.ubuntu.touch.AccountsService.Sound", "SilentMode"); } return mSilentMode.toBool(); } QString GreeterContacts::incomingCallSound() { if (!mIncomingCallSound.isValid()) { mIncomingCallSound = getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingCallSound"); } return mIncomingCallSound.toString(); } QString GreeterContacts::incomingMessageSound() { if (!mIncomingMessageSound.isValid()) { mIncomingMessageSound = getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingMessageSound"); } return mIncomingMessageSound.toString(); } void GreeterContacts::greeterPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated) { if (interface == "com.canonical.UnityGreeter.List") { if (changed.contains("ActiveEntry")) { updateActiveUser(changed.value("ActiveEntry").toString()); } else if (invalidated.contains("ActiveEntry")) { queryEntry(); } } } QVariant GreeterContacts::getUserValue(const QString &interface, const QString &propName) { QDBusInterface iface("org.freedesktop.Accounts", mActiveUser, "org.freedesktop.DBus.Properties", QDBusConnection::AS_BUSNAME()); QDBusReply reply = iface.call("Get", interface, propName); if (reply.isValid()) { return reply.value(); } else { qWarning() << "Failed to get user property " << propName << " from AccountsService:" << reply.error().message(); } } void GreeterContacts::checkUpdatedValue(const QVariantMap &changed, const QStringList &invalidated, const QString &propName, QVariant &propValue) { if (changed.contains(propName)) { propValue = changed.value(propName); } else if (invalidated.contains(propName)) { propValue = QVariant(); } } void GreeterContacts::accountsPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated, const QDBusMessage &message) { if (interface == "com.canonical.TelephonyServiceApprover") { if (changed.contains("CurrentContact")) { mContacts.insert(message.path(), qdbus_cast(changed.value("CurrentContact"))); signalIfNeeded(); } else if (invalidated.contains("CurrentContact")) { queryContact(message.path()); } } else if (interface == "com.ubuntu.touch.AccountsService.Sound" && message.path() == mActiveUser) { checkUpdatedValue(changed, invalidated, "SilentMode", mSilentMode); checkUpdatedValue(changed, invalidated, "IncomingCallSound", mIncomingCallSound); checkUpdatedValue(changed, invalidated, "IncomingMessageSound", mIncomingMessageSound); } } void GreeterContacts::greeterGetEntryReply(QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; if (!reply.isError()) { updateActiveUser(reply.argumentAt<0>().toString()); } else { qWarning() << "Failed to get active entry from Unity Greeter:" << reply.error().message(); } watcher->deleteLater(); } void GreeterContacts::accountsGetUsersReply(QDBusPendingCallWatcher *watcher) { QDBusPendingReply> reply = *watcher; if (!reply.isError()) { Q_FOREACH (const QDBusObjectPath &user, reply.argumentAt<0>()) { queryContact(user.path()); } } else { qWarning() << "Failed to get user list from AccountsService:" << reply.error().message(); } watcher->deleteLater(); } void GreeterContacts::accountsGetContactReply(QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; if (!reply.isError()) { mContacts.insert(watcher->property("telepathyPath").toString(), qdbus_cast(reply.argumentAt<0>())); signalIfNeeded(); } else { qWarning() << "Failed to get user's contact from AccountsService:" << reply.error().message(); } watcher->deleteLater(); } void GreeterContacts::queryEntry() { QDBusInterface iface("com.canonical.UnityGreeter", "/list", "org.freedesktop.DBus.Properties", QDBusConnection::sessionBus()); QDBusPendingCall call = iface.asyncCall("Get", "com.canonical.UnityGreeter.List", "ActiveEntry"); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this, SLOT(greeterGetEntryReply(QDBusPendingCallWatcher *))); } void GreeterContacts::queryContact(const QString &user) { QDBusInterface iface("org.freedesktop.Accounts", user, "org.freedesktop.DBus.Properties", QDBusConnection::AS_BUSNAME()); QDBusPendingCall call = iface.asyncCall("Get", "com.canonical.TelephonyServiceApprover", "CurrentContact"); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); watcher->setProperty("telepathyPath", QVariant(user)); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this, SLOT(accountsGetContactReply(QDBusPendingCallWatcher *))); } void GreeterContacts::updateActiveUser(const QString &username) { struct passwd *pwinfo = getpwnam(username.toLatin1()); if (pwinfo) { mActiveUser = "/org/freedesktop/Accounts/User" + QString::number(pwinfo->pw_uid); mSilentMode = QVariant(); mIncomingCallSound = QVariant(); mIncomingMessageSound = QVariant(); signalIfNeeded(); } } QContact GreeterContacts::lookupContact() { // For now, only ever look at active user's contact info. In future, // maybe we should search all users for any matching info. QVariantMap contactInfo = mContacts.value(mActiveUser); if (!contactInfo.empty()) { QContact contact = mapToContact(contactInfo); if (QContactManagerEngine::testFilter(mFilter, contact)) { return contact; } } return QContact(); } void GreeterContacts::signalIfNeeded() { QContact contact = lookupContact(); if (!contact.isEmpty()) { Q_EMIT contactUpdated(contact); } } void GreeterContacts::emitContact(const QContact &contact) { QString uid = QString::number(getuid()); QVariantMap map = contactToMap(contact); if (!map.value("Image").toString().isEmpty()) { // OK, so we want to tell LightDM about our contact. But LightDM won't // have access to our image file in their normal location managed by // evolution. And rather than give world-readable permissions to our // evolution dir, we minimize the damage by copying the image to a new // more accessible location. // Clean up from previous (poor) implementation of this method QFile imageFile(QDir::home().filePath(".telephony-service-contact-image")); imageFile.remove(); // Now copy into greeter data dir, if one is set QString path = qgetenv("XDG_GREETER_DATA_DIR"); if (!path.isEmpty()) { QDir(path).mkdir("telephony-service"); // create namespaced subdir path += "/telephony-service/contact-image"; QFile(path).remove(); // copy() won't overwrite, so remove before if (QFile(map.value("Image").toString()).copy(path)) { map.insert("Image", path); } } } QDBusInterface iface("org.freedesktop.Accounts", "/org/freedesktop/Accounts/User" + uid, "org.freedesktop.DBus.Properties", QDBusConnection::AS_BUSNAME()); iface.asyncCall("Set", "com.canonical.TelephonyServiceApprover", "CurrentContact", QVariant::fromValue(QDBusVariant(QVariant(map)))); } QVariantMap GreeterContacts::contactToMap(const QContact &contact) { QVariantMap map; QContactAvatar avatarDetail = contact.detail(); map.insert("Image", avatarDetail.imageUrl().toLocalFile()); QContactName nameDetail = contact.detail(); map.insert("FirstName", nameDetail.firstName()); map.insert("LastName", nameDetail.lastName()); QContactPhoneNumber numberDetail = contact.detail(); map.insert("PhoneNumber", numberDetail.number()); return map; } QContact GreeterContacts::mapToContact(const QVariantMap &map) { QContact contact; QContactAvatar avatarDetail; avatarDetail.setValue(QContactAvatar::FieldImageUrl, QUrl::fromLocalFile(map.value("Image").toString())); contact.saveDetail(&avatarDetail); // We only use FirstName and LastName right now in ContactUtils::formatContactName(). // If/When we use more, we should save more detail values here. QContactName nameDetail; nameDetail.setValue(QContactName::FieldFirstName, map.value("FirstName")); nameDetail.setValue(QContactName::FieldLastName, map.value("LastName")); contact.saveDetail(&nameDetail); QContactPhoneNumber numberDetail; numberDetail.setValue(QContactPhoneNumber::FieldNumber, map.value("PhoneNumber")); contact.saveDetail(&numberDetail); return contact; } telephony-service-0.1+14.04.20140415/libtelephonyservice/chatmanager.cpp0000644000015301777760000001323612323307402026453 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "chatmanager.h" #include "telepathyhelper.h" #include "phoneutils.h" #include "config.h" #include #include ChatManager::ChatManager(QObject *parent) : QObject(parent) { // wait one second for other acknowledge calls before acknowledging messages to avoid many round trips mMessagesAckTimer.setInterval(1000); mMessagesAckTimer.setSingleShot(true); connect(&mMessagesAckTimer, SIGNAL(timeout()), SLOT(onAckTimerTriggered())); } ChatManager *ChatManager::instance() { static ChatManager *manager = new ChatManager(); return manager; } void ChatManager::sendMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId) { Tp::AccountPtr account; if (accountId.isNull()) { account = TelepathyHelper::instance()->accounts()[0]; } else { account = TelepathyHelper::instance()->accountForId(accountId); } QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("SendMessage", phoneNumbers, message, account->uniqueIdentifier()); } void ChatManager::onTextChannelAvailable(Tp::TextChannelPtr channel) { QString id = channel->targetContact()->id(); mChannels.append(channel); connect(channel.data(), SIGNAL(messageReceived(Tp::ReceivedMessage)), SLOT(onMessageReceived(Tp::ReceivedMessage))); connect(channel.data(), SIGNAL(messageSent(Tp::Message,Tp::MessageSendingFlags,QString)), SLOT(onMessageSent(Tp::Message,Tp::MessageSendingFlags,QString))); connect(channel.data(), SIGNAL(pendingMessageRemoved(const Tp::ReceivedMessage&)), SLOT(onPendingMessageRemoved(const Tp::ReceivedMessage&))); Q_EMIT unreadMessagesChanged(id); Q_FOREACH(const Tp::ReceivedMessage &message, channel->messageQueue()) { onMessageReceived(message); } } void ChatManager::onMessageReceived(const Tp::ReceivedMessage &message) { // ignore delivery reports for now // FIXME: we need to handle errors on sending messages at some point if (message.isDeliveryReport()) { return; } Q_EMIT messageReceived(message.sender()->id(), message.text(), message.received(), message.messageToken(), true); Q_EMIT unreadMessagesChanged(message.sender()->id()); } void ChatManager::onPendingMessageRemoved(const Tp::ReceivedMessage &message) { // emit the signal saying the unread messages for a specific number has changed Q_EMIT unreadMessagesChanged(message.sender()->id()); } void ChatManager::onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message) { Q_UNUSED(message) Q_UNUSED(flags) Tp::TextChannel *channel = qobject_cast(sender()); if (!channel) { return; } Q_EMIT messageSent(channel->targetContact()->id(), sentMessage.text()); } Tp::TextChannelPtr ChatManager::existingChat(const QStringList &phoneNumbers, const QString &accountId) { Tp::TextChannelPtr channel; Q_FOREACH(const Tp::TextChannelPtr &channel, mChannels) { Tp::AccountPtr channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection()); int count = 0; if (!channelAccount || channelAccount->uniqueIdentifier() != accountId || channel->groupContacts(false).size() != phoneNumbers.size()) { continue; } Q_FOREACH(const QString &phoneNumberNew, phoneNumbers) { Q_FOREACH(const Tp::ContactPtr &phoneNumberOld, channel->groupContacts(false)) { if (PhoneUtils::comparePhoneNumbers(phoneNumberOld->id(), phoneNumberNew)) { count++; } } } if (count == phoneNumbers.size()) { return channel; } } return channel; } void ChatManager::acknowledgeMessage(const QString &phoneNumber, const QString &messageId, const QString &accountId) { Tp::AccountPtr account; if (accountId.isNull()) { account = TelepathyHelper::instance()->accounts()[0]; } else { account = TelepathyHelper::instance()->accountForId(accountId); } mMessagesAckTimer.start(); mMessagesToAck[account->uniqueIdentifier()][phoneNumber].append(messageId); } void ChatManager::onAckTimerTriggered() { // ack all pending messages QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); QMap >::const_iterator it = mMessagesToAck.constBegin(); while (it != mMessagesToAck.constEnd()) { QString accountId = it.key(); QMap::const_iterator it2 = it.value().constBegin(); while (it2 != it.value().constEnd()) { phoneAppHandler->call("AcknowledgeMessages", it2.key(), it2.value(), accountId); ++it2; } ++it; } mMessagesToAck.clear(); } telephony-service-0.1+14.04.20140415/libtelephonyservice/contactemailaddress.h0000644000015301777760000000251712323307402027657 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CONTACTEMAILADDRESS_H #define CONTACTEMAILADDRESS_H #include "contactdetail.h" #include class ContactEmailAddress : public ContactDetail { Q_OBJECT Q_PROPERTY(QString emailAddress READ emailAddress WRITE setEmailAddress NOTIFY changed) public: explicit ContactEmailAddress(const QContactDetail &detail = QContactEmailAddress(), QObject *parent = 0); QString emailAddress() const; void setEmailAddress(const QString &value); Q_SIGNALS: void changed(); }; #endif // CONTACTEMAILADDRESS_H telephony-service-0.1+14.04.20140415/libtelephonyservice/phoneutils.h0000644000015301777760000000214412323307402026034 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef PHONEUTILS_H #define PHONEUTILS_H #include class PhoneUtils : public QObject { Q_OBJECT public: explicit PhoneUtils(QObject *parent = 0); Q_INVOKABLE static bool comparePhoneNumbers(const QString &number1, const QString &number2); Q_INVOKABLE static bool isPhoneNumber(const QString &identifier); }; #endif // PHONEUTILS_H telephony-service-0.1+14.04.20140415/libtelephonyservice/channelobserver.h0000644000015301777760000000437212323307402027027 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CHANNELOBSERVER_H #define CHANNELOBSERVER_H #include #include #include #include class ChannelObserver : public QObject, public Tp::AbstractClientObserver { Q_OBJECT public: explicit ChannelObserver(QObject *parent = 0); Tp::ChannelClassSpecList channelFilters() const; void observeChannels(const Tp::MethodInvocationContextPtr<> &context, const Tp::AccountPtr &account, const Tp::ConnectionPtr &connection, const QList &channels, const Tp::ChannelDispatchOperationPtr &dispatchOperation, const QList &requestsSatisfied, const Tp::AbstractClientObserver::ObserverInfo &observerInfo); Q_SIGNALS: void callEnded(const Tp::CallChannelPtr &channel); void textChannelAvailable(const Tp::TextChannelPtr &channel); void callChannelAvailable(const Tp::CallChannelPtr &channel); protected Q_SLOTS: void onChannelInvalidated(); void onCallChannelReady(Tp::PendingOperation *op); void onTextChannelReady(Tp::PendingOperation *op); protected: void checkContextFinished(Tp::Channel *channel); private: QMap > mContexts; QMap mReadyMap; QList mChannels; }; #endif // CHANNELOBSERVER_H telephony-service-0.1+14.04.20140415/libtelephonyservice/channelobserver.cpp0000644000015301777760000001531712323307402027363 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "channelobserver.h" #include "telepathyhelper.h" #include #include #include #include ChannelObserver::ChannelObserver(QObject *parent) : QObject(parent), Tp::AbstractClientObserver(channelFilters(), true) { } Tp::ChannelClassSpecList ChannelObserver::channelFilters() const { Tp::ChannelClassSpecList specList; specList << TelepathyHelper::audioConferenceSpec(); specList << Tp::ChannelClassSpec::audioCall(); specList << Tp::ChannelClassSpec::textChat(); return specList; } void ChannelObserver::observeChannels(const Tp::MethodInvocationContextPtr<> &context, const Tp::AccountPtr &account, const Tp::ConnectionPtr &connection, const QList &channels, const Tp::ChannelDispatchOperationPtr &dispatchOperation, const QList &requestsSatisfied, const Tp::AbstractClientObserver::ObserverInfo &observerInfo) { Q_UNUSED(account) Q_UNUSED(connection) Q_UNUSED(dispatchOperation) Q_UNUSED(requestsSatisfied) Q_UNUSED(observerInfo) Q_FOREACH (Tp::ChannelPtr channel, channels) { mContexts[channel.data()] = context; mChannels.append(channel); connect(channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,const QString&, const QString&)), SLOT(onChannelInvalidated())); Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (callChannel) { Tp::PendingReady *ready = callChannel->becomeReady(Tp::Features() << Tp::CallChannel::FeatureCore << Tp::CallChannel::FeatureCallMembers << Tp::CallChannel::FeatureCallState << Tp::CallChannel::FeatureContents << Tp::CallChannel::FeatureLocalHoldState); connect(ready, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onCallChannelReady(Tp::PendingOperation*))); mReadyMap[ready] = callChannel; } Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if (textChannel) { Tp::PendingReady *ready = textChannel->becomeReady(Tp::Features() << Tp::TextChannel::FeatureCore << Tp::TextChannel::FeatureChatState << Tp::TextChannel::FeatureMessageCapabilities << Tp::TextChannel::FeatureMessageQueue << Tp::TextChannel::FeatureMessageSentSignal); connect(ready, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onTextChannelReady(Tp::PendingOperation*))); mReadyMap[ready] = textChannel; } } } void ChannelObserver::onCallChannelReady(Tp::PendingOperation *op) { Tp::PendingReady *ready = qobject_cast(op); if (!ready) { qCritical() << "Pending operation is not a pending ready:" << op; return; } if (!mReadyMap.contains(ready)) { qWarning() << "Pending ready finished but not on the map:" << ready; return; } Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(mReadyMap[ready]); mReadyMap.remove(ready); if (!callChannel) { qWarning() << "Ready channel is not a call channel:" << callChannel; return; } // save the timestamp as a property in the call channel callChannel->setProperty("timestamp", QDateTime::currentDateTime()); if (callChannel->callState() == Tp::CallStateActive) { callChannel->setProperty("activeTimestamp", QDateTime::currentDateTime()); } Q_EMIT callChannelAvailable(callChannel); checkContextFinished(callChannel.data()); } void ChannelObserver::onChannelInvalidated() { Tp::ChannelPtr channel(qobject_cast(sender())); mChannels.removeAll(channel); } void ChannelObserver::onTextChannelReady(Tp::PendingOperation *op) { Tp::PendingReady *ready = qobject_cast(op); if (!ready) { qCritical() << "Pending operation is not a pending ready:" << op; return; } if (!mReadyMap.contains(ready)) { qWarning() << "Pending ready finished but not on the map:" << ready; return; } Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(mReadyMap[ready]); mReadyMap.remove(ready); if (!textChannel) { qWarning() << "Ready channel is not a call channel:" << textChannel; return; } Q_EMIT textChannelAvailable(textChannel); checkContextFinished(textChannel.data()); } void ChannelObserver::checkContextFinished(Tp::Channel *channel) { if (!mContexts.contains(channel)) { qWarning() << "Context for channel not available:" << channel; return; } Tp::MethodInvocationContextPtr<> context = mContexts[channel]; mContexts.remove(channel); // check if this is the last channel from the context Q_FOREACH(Tp::MethodInvocationContextPtr<> otherContext, mContexts.values()) { // if we find the context, just return from the function. We need to wait // for the other channels to become ready before setting the context finished if (otherContext == context) { return; } } context->setFinished(); } telephony-service-0.1+14.04.20140415/libtelephonyservice/contactemailaddress.cpp0000644000015301777760000000250712323307402030211 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "contactemailaddress.h" ContactEmailAddress::ContactEmailAddress(const QContactDetail &detail, QObject *parent) : ContactDetail(detail, parent) { connect(this, SIGNAL(detailChanged()), SIGNAL(changed())); } QString ContactEmailAddress::emailAddress() const { return mDetail.value(QContactEmailAddress::FieldEmailAddress).toString(); } void ContactEmailAddress::setEmailAddress(const QString &value) { if (value != emailAddress()) { mDetail.setValue(QContactEmailAddress::FieldEmailAddress, value); Q_EMIT changed(); } } telephony-service-0.1+14.04.20140415/libtelephonyservice/telepathyhelper.h0000644000015301777760000000661612323307402027051 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef TELEPATHYHELPER_H #define TELEPATHYHELPER_H #include #include #include #include #include #include #include "channelobserver.h" #define CANONICAL_TELEPHONY_VOICEMAIL_IFACE "com.canonical.Telephony.Voicemail" #define CANONICAL_TELEPHONY_SPEAKER_IFACE "com.canonical.Telephony.Speaker" #define CANONICAL_TELEPHONY_USSD_IFACE "com.canonical.Telephony.USSD" class TelepathyHelper : public QObject { Q_OBJECT Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) Q_PROPERTY(QStringList accountIds READ accountIds NOTIFY accountIdsChanged) public: ~TelepathyHelper(); static TelepathyHelper *instance(); QList accounts() const; ChannelObserver *channelObserver() const; QDBusInterface *handlerInterface(); bool connected() const; QStringList accountIds(); Tp::AccountPtr accountForConnection(const Tp::ConnectionPtr &connection) const; Tp::AccountPtr accountForId(const QString &accountId) const; bool isAccountConnected(const Tp::AccountPtr &account) const; void registerClient(Tp::AbstractClient *client, QString name); // pre-populated channel class specs for conferences static Tp::ChannelClassSpec audioConferenceSpec(); Q_SIGNALS: void channelObserverCreated(ChannelObserver *observer); void channelObserverUnregistered(); void accountReady(); void connectionChanged(); void connectedChanged(); void accountIdsChanged(); public Q_SLOTS: Q_INVOKABLE void registerChannelObserver(const QString &observerName = QString::null); Q_INVOKABLE void unregisterChannelObserver(); protected: QStringList supportedProtocols() const; void initializeAccount(const Tp::AccountPtr &account); void ensureAccountEnabled(const Tp::AccountPtr &account); void ensureAccountConnected(const Tp::AccountPtr &account); void watchSelfContactPresence(const Tp::AccountPtr &account); private Q_SLOTS: void onAccountManagerReady(Tp::PendingOperation *op); void updateConnectedStatus(); private: explicit TelepathyHelper(QObject *parent = 0); Tp::AccountManagerPtr mAccountManager; Tp::Features mAccountManagerFeatures; Tp::Features mAccountFeatures; Tp::Features mContactFeatures; Tp::Features mConnectionFeatures; Tp::ClientRegistrarPtr mClientRegistrar; QList mAccounts; ChannelObserver *mChannelObserver; bool mFirstTime; bool mConnected; QDBusInterface *mHandlerInterface; }; #endif // TELEPATHYHELPER_H telephony-service-0.1+14.04.20140415/libtelephonyservice/callentry.h0000644000015301777760000001167112323307402025644 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CALLENTRY_H #define CALLENTRY_H #include #include #include #include class CallEntry : public QObject { Q_OBJECT Q_PROPERTY (bool held READ isHeld WRITE setHold NOTIFY heldChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMute NOTIFY mutedChanged) Q_PROPERTY(bool voicemail READ isVoicemail WRITE setVoicemail NOTIFY voicemailChanged) // this property is only filled for 1-1 calls Q_PROPERTY(QString phoneNumber READ phoneNumber NOTIFY phoneNumberChanged) // this property is only filled for conference calls Q_PROPERTY(QQmlListProperty calls READ calls NOTIFY callsChanged) Q_PROPERTY(bool isConference READ isConference NOTIFY isConferenceChanged) Q_PROPERTY(int elapsedTime READ elapsedTime NOTIFY elapsedTimeChanged) Q_PROPERTY(bool active READ isActive NOTIFY activeChanged) Q_PROPERTY(bool dialing READ dialing NOTIFY dialingChanged) Q_PROPERTY(bool incoming READ incoming NOTIFY incomingChanged) Q_PROPERTY(bool ringing READ ringing NOTIFY ringingChanged) Q_PROPERTY(bool speaker READ isSpeakerOn WRITE setSpeaker NOTIFY speakerChanged) Q_PROPERTY(QString dtmfString READ dtmfString NOTIFY dtmfStringChanged) public: explicit CallEntry(const Tp::CallChannelPtr &channel, QObject *parent = 0); void timerEvent(QTimerEvent *event); bool isHeld() const; void setHold(bool hold); bool isMuted() const; void setMute(bool value); bool isVoicemail() const; void setVoicemail(bool voicemail); int elapsedTime() const; bool isActive() const; bool isSpeakerOn(); Q_INVOKABLE void setSpeaker(bool speaker); bool dialing() const; bool incoming() const; bool ringing() const; QString phoneNumber() const; QQmlListProperty calls(); bool isConference() const; QString dtmfString() const; Q_INVOKABLE void sendDTMF(const QString &key); Q_INVOKABLE void endCall(); Q_INVOKABLE void splitCall(); Tp::CallChannelPtr channel() const; // QQmlListProperty helpers static int callsCount(QQmlListProperty *p); static CallEntry* callAt(QQmlListProperty *p, int index); void addCall(CallEntry *call); protected Q_SLOTS: void onCallStateChanged(Tp::CallState state); void onCallFlagsChanged(Tp::CallFlags flags); void onMutedChanged(uint state); void onSpeakerChanged(bool active); void onCallPropertiesChanged(const QString &objectPath, const QVariantMap &properties); // conference related stuff void onConferenceChannelMerged(const Tp::ChannelPtr &channel); void onConferenceChannelRemoved(const Tp::ChannelPtr &channel, const Tp::Channel::GroupMemberChangeDetails &details); void onInternalCallEnded(); protected: void setupCallChannel(); void updateChannelProperties(const QVariantMap &properties = QVariantMap()); Q_SIGNALS: void callEnded(); void callActive(); void activeChanged(); void heldChanged(); void mutedChanged(); void voicemailChanged(); void phoneNumberChanged(); void callsChanged(); void isConferenceChanged(); void dtmfStringChanged(); void dialingChanged(); void incomingChanged(); void ringingChanged(); void elapsedTimeChanged(); void speakerChanged(); private: void refreshProperties(); Tp::AccountPtr mAccount; Tp::CallChannelPtr mChannel; QDBusInterface mMuteInterface; QDBusInterface mSpeakerInterface; QMap mProperties; bool mVoicemail; bool mLocalMuteState; QDateTime mActiveTimestamp; bool mHasSpeakerProperty; bool mSpeakerMode; QList mCalls; }; #endif // CALLENTRY_H telephony-service-0.1+14.04.20140415/libtelephonyservice/applicationutils.cpp0000644000015301777760000000366612323307402027573 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "applicationutils.h" #include #include #include #include #include #include #include #include #ifdef USE_UBUNTU_PLATFORM_API #include #include #endif ApplicationUtils::ApplicationUtils(QObject *parent) : QObject(parent) { } ApplicationUtils *ApplicationUtils::instance() { static ApplicationUtils *self = new ApplicationUtils(); return self; } bool ApplicationUtils::checkApplicationRunning(const QString &serviceName) { bool result = false; QDBusReply reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName); if (reply.isValid()) { result = reply.value(); } return result; } bool ApplicationUtils::openUrl(const QUrl &url) { #ifdef USE_UBUNTU_PLATFORM_API UAUrlDispatcherSession* session = ua_url_dispatcher_session(); if (!session) return false; ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL); free(session); #endif return true; } telephony-service-0.1+14.04.20140415/libtelephonyservice/callentry.cpp0000644000015301777760000002626412323307402026203 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "callentry.h" #include "callmanager.h" #include "telepathyhelper.h" #include #include #include #include #include #define TELEPATHY_MUTE_IFACE "org.freedesktop.Telepathy.Call1.Interface.Mute" #define TELEPATHY_CALL_IFACE "org.freedesktop.Telepathy.Channel.Type.Call1" #define DBUS_PROPERTIES_IFACE "org.freedesktop.DBus.Properties" #define PROPERTY_SPEAKERMODE "SpeakerMode" CallEntry::CallEntry(const Tp::CallChannelPtr &channel, QObject *parent) : QObject(parent), mChannel(channel), mVoicemail(false), mLocalMuteState(false), mMuteInterface(channel->busName(), channel->objectPath(), TELEPATHY_MUTE_IFACE), mSpeakerInterface(channel->busName(), channel->objectPath(), CANONICAL_TELEPHONY_SPEAKER_IFACE), mHasSpeakerProperty(false), mSpeakerMode(false) { mAccount = TelepathyHelper::instance()->accountForConnection(mChannel->connection()); setupCallChannel(); // connect to the DBus signal connect(TelepathyHelper::instance()->handlerInterface(), SIGNAL(CallPropertiesChanged(QString, QVariantMap)), SLOT(onCallPropertiesChanged(QString,QVariantMap))); Q_EMIT incomingChanged(); } void CallEntry::onSpeakerChanged(bool active) { mSpeakerMode = active; Q_EMIT speakerChanged(); } void CallEntry::onCallPropertiesChanged(const QString &objectPath, const QVariantMap &properties) { if (objectPath != mChannel->objectPath()) { return; } updateChannelProperties(properties); } void CallEntry::onConferenceChannelMerged(const Tp::ChannelPtr &channel) { QList entries = CallManager::instance()->takeCalls(QList() << channel); if (entries.isEmpty()) { qWarning() << "Could not find the call that was just merged."; return; } CallEntry *entry = entries.first(); connect(entry, SIGNAL(callEnded()), SLOT(onInternalCallEnded())); mCalls.append(entry); Q_EMIT callsChanged(); } void CallEntry::onConferenceChannelRemoved(const Tp::ChannelPtr &channel, const Tp::Channel::GroupMemberChangeDetails &details) { Q_FOREACH(CallEntry *entry, mCalls) { Tp::ChannelPtr entryChannel = entry->channel(); if (entryChannel == channel) { CallManager::instance()->addCalls(QList() << entry); mCalls.removeAll(entry); entry->disconnect(this); Q_EMIT callsChanged(); break; } } } void CallEntry::onInternalCallEnded() { CallEntry *entry = qobject_cast(sender()); mCalls.removeAll(entry); Q_EMIT callsChanged(); entry->deleteLater(); } void CallEntry::setupCallChannel() { connect(mChannel.data(), SIGNAL(callStateChanged(Tp::CallState)), SLOT(onCallStateChanged(Tp::CallState))); connect(mChannel.data(), SIGNAL(callFlagsChanged(Tp::CallFlags)), SLOT(onCallFlagsChanged(Tp::CallFlags))); connect(mChannel.data(), SIGNAL(localHoldStateChanged(Tp::LocalHoldState,Tp::LocalHoldStateReason)), SIGNAL(heldChanged())); connect(&mMuteInterface, SIGNAL(MuteStateChanged(uint)), SLOT(onMutedChanged(uint))); if (mChannel->isConference()) { connect(mChannel.data(), SIGNAL(conferenceChannelMerged(Tp::ChannelPtr)), SLOT(onConferenceChannelMerged(Tp::ChannelPtr))); connect(mChannel.data(), SIGNAL(conferenceChannelRemoved(Tp::ChannelPtr, Tp::Channel::GroupMemberChangeDetails)), SLOT(onConferenceChannelRemoved(Tp::ChannelPtr,Tp::Channel::GroupMemberChangeDetails))); } refreshProperties(); mHasSpeakerProperty = mProperties.contains(PROPERTY_SPEAKERMODE); if (mHasSpeakerProperty) { connect(&mSpeakerInterface, SIGNAL(SpeakerChanged(bool)), SLOT(onSpeakerChanged(bool))); } onCallStateChanged(mChannel->callState()); Q_EMIT heldChanged(); Q_EMIT phoneNumberChanged(); Q_EMIT dialingChanged(); } void CallEntry::updateChannelProperties(const QVariantMap &properties) { QVariantMap props = properties; // fetch the properties if the map is empty if (props.isEmpty()) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); QDBusReply reply = phoneAppHandler->call("GetCallProperties", mChannel->objectPath()); if (!reply.isValid()) { return; } props = reply.value(); } QDateTime timestamp; if (props.contains("timestamp")) { props["timestamp"].value() >> timestamp; } if (props.contains("activeTimestamp")) { props["activeTimestamp"].value() >> mActiveTimestamp; } mChannel->setProperty("dtmfString", props["dtmfString"]); mChannel->setProperty("timestamp", timestamp); mChannel->setProperty("activeTimestamp", mActiveTimestamp); Q_EMIT dtmfStringChanged(); } void CallEntry::timerEvent(QTimerEvent *event) { Q_EMIT elapsedTimeChanged(); } void CallEntry::refreshProperties() { QDBusInterface callChannelIface(mChannel->busName(), mChannel->objectPath(), DBUS_PROPERTIES_IFACE); QDBusMessage reply = callChannelIface.call("GetAll", TELEPATHY_CALL_IFACE); QVariantList args = reply.arguments(); QMap map = qdbus_cast >(args[0]); reply = callChannelIface.call("GetAll", CANONICAL_TELEPHONY_SPEAKER_IFACE); args = reply.arguments(); QMap map2 = qdbus_cast >(args[0]); mProperties.clear(); QMapIterator i(map); while(i.hasNext()) { i.next(); mProperties[i.key()] = i.value(); } QMapIterator i2(map2); while(i2.hasNext()) { i2.next(); mProperties[i2.key()] = i2.value(); } onSpeakerChanged(mProperties[PROPERTY_SPEAKERMODE].toBool()); } bool CallEntry::dialing() const { return !incoming() && (mChannel->callState() == Tp::CallStateInitialised); } bool CallEntry::incoming() const { if (!mAccount) { return false; } return mChannel->initiatorContact() != mAccount->connection()->selfContact(); } bool CallEntry::ringing() const { return incoming() && (mChannel->callState() == Tp::CallStateInitialised); } QString CallEntry::phoneNumber() const { if (mChannel->isConference() || !mChannel->actualFeatures().contains(Tp::CallChannel::FeatureCore)) { return ""; } return mChannel->targetContact()->id(); } QQmlListProperty CallEntry::calls() { return QQmlListProperty(this, 0, callsCount, callAt); } bool CallEntry::isConference() const { return mChannel->isConference(); } QString CallEntry::dtmfString() const { return mChannel->property("dtmfString").toString(); } void CallEntry::sendDTMF(const QString &key) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("SendDTMF", mChannel->objectPath(), key); } void CallEntry::endCall() { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("HangUpCall", mChannel->objectPath()); } void CallEntry::splitCall() { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("SplitCall", mChannel->objectPath()); } Tp::CallChannelPtr CallEntry::channel() const { return mChannel; } int CallEntry::callsCount(QQmlListProperty *p) { CallEntry *entry = qobject_cast(p->object); if (!entry) { return 0; } return entry->mCalls.count(); } CallEntry *CallEntry::callAt(QQmlListProperty *p, int index) { CallEntry *entry = qobject_cast(p->object); if (!entry) { return 0; } return entry->mCalls[index]; } void CallEntry::addCall(CallEntry *call) { mCalls << call; connect(call, SIGNAL(callEnded()), SLOT(onInternalCallEnded())); Q_EMIT callsChanged(); } bool CallEntry::isHeld() const { if (!mChannel->actualFeatures().contains(Tp::CallChannel::FeatureLocalHoldState)) { return false; } return (mChannel->localHoldState() == Tp::LocalHoldStateHeld); } void CallEntry::setHold(bool hold) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("SetHold", mChannel->objectPath(), hold); } void CallEntry::onMutedChanged(uint state) { // Replace this by a Mute interface method call when it // becomes available in telepathy-qt mLocalMuteState = (state == 1); Q_EMIT mutedChanged(); } bool CallEntry::isMuted() const { // Replace this by a Mute interface method call when it // becomes available in telepathy-qt return mLocalMuteState; } void CallEntry::setMute(bool value) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("SetMuted", mChannel->objectPath(), value); } void CallEntry::onCallStateChanged(Tp::CallState state) { // fetch the channel properties from the handler updateChannelProperties(); switch (state) { case Tp::CallStateEnded: Q_EMIT callEnded(); break; case Tp::CallStateActive: startTimer(1000); Q_EMIT callActive(); Q_EMIT activeChanged(); break; } Q_EMIT dialingChanged(); } void CallEntry::onCallFlagsChanged(Tp::CallFlags flags) { Q_UNUSED(flags) Q_EMIT ringingChanged(); } void CallEntry::setVoicemail(bool voicemail) { mVoicemail = voicemail; Q_EMIT voicemailChanged(); } bool CallEntry::isVoicemail() const { return mVoicemail; } int CallEntry::elapsedTime() const { if (!mActiveTimestamp.isValid()) { return 0; } return mActiveTimestamp.secsTo(QDateTime::currentDateTimeUtc()); } bool CallEntry::isActive() const { return (mChannel->callState() == Tp::CallStateActive); } bool CallEntry::isSpeakerOn() { if (mHasSpeakerProperty) { return mSpeakerMode; } return false; } void CallEntry::setSpeaker(bool speaker) { if (!mHasSpeakerProperty) { return; } QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("SetSpeakerMode", mChannel->objectPath(), speaker); } telephony-service-0.1+14.04.20140415/libtelephonyservice/CMakeLists.txt0000644000015301777760000000160512323307402026232 0ustar pbusernogroup00000000000000set(library_SRCS applicationutils.cpp callentry.cpp callmanager.cpp callnotification.cpp channelobserver.cpp chatmanager.cpp contactutils.cpp greetercontacts.cpp phoneutils.cpp ringtone.cpp telepathyhelper.cpp ussdmanager.cpp ) include_directories( ${TP_QT5_INCLUDE_DIRS} ${NOTIFY_INCLUDE_DIRS} ) if (USE_UBUNTU_PLATFORM_API) set(UBUNTU_APP_LIB "-lubuntu_application_api") endif (USE_UBUNTU_PLATFORM_API) add_library(telephonyservice STATIC ${library_SRCS} ${library_HDRS}) set_target_properties(telephonyservice PROPERTIES COMPILE_DEFINITIONS AS_BUSNAME=systemBus) target_link_libraries(telephonyservice ${TP_QT5_LIBRARIES} ${UBUNTU_APP_LIB} ${NOTIFY_LIBRARIES}) qt5_use_modules(telephonyservice Contacts Core DBus Multimedia Qml Quick) add_subdirectory(tests) telephony-service-0.1+14.04.20140415/libtelephonyservice/applicationutils.h0000644000015301777760000000225512323307402027231 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef APPLICATIONUTILS_H #define APPLICATIONUTILS_H #include #include #include class ApplicationUtils : public QObject { Q_OBJECT public: static ApplicationUtils *instance(); static bool checkApplicationRunning(const QString &serviceName); static bool openUrl(const QUrl &url); private: explicit ApplicationUtils(QObject *parent = 0); }; #endif // APPLICATIONUTILS_H telephony-service-0.1+14.04.20140415/libtelephonyservice/ussdmanager.h0000644000015301777760000000617012323307402026156 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef USSDMANAGER_H #define USSDMANAGER_H #include #include #include class TelepathyHelper; class USSDManager : public QObject { Q_OBJECT Q_PROPERTY(bool active READ active NOTIFY activeChanged) Q_PROPERTY(QString activeAccountId READ activeAccountId NOTIFY activeAccountIdChanged) Q_PROPERTY(QString state READ state NOTIFY stateChanged) public: static USSDManager *instance(); Q_INVOKABLE void initiate(const QString &command, const QString &accountId = QString::null); Q_INVOKABLE void respond(const QString &reply, const QString &accountId = QString::null); Q_INVOKABLE void cancel(const QString &accountId = QString::null); Q_INVOKABLE QString serial(const QString& accountId) const; bool active() const; QString activeAccountId() const; QString state() const; public Q_SLOTS: void onConnectedChanged(); void onStateChanged(const QString &state); Q_SIGNALS: void activeChanged(); void activeAccountIdChanged(); void stateChanged(const QString &state); void notificationReceived(const QString &message); void requestReceived(const QString &message); void initiateUSSDComplete(const QString &ussdResp); void respondComplete(bool success, const QString &ussdResp); void barringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap); void forwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap); void waitingComplete(const QString &ssOp, const QVariantMap &cwMap); void callingLinePresentationComplete(const QString &ssOp, const QString &status); void connectedLinePresentationComplete(const QString &ssOp, const QString &status); void callingLineRestrictionComplete(const QString &ssOp, const QString &status); void connectedLineRestrictionComplete(const QString &ssOp, const QString &status); void initiateFailed(); private: explicit USSDManager(QObject *parent = 0); void disconnectAllSignals(const Tp::ConnectionPtr& conn); void connectAllSignals(const Tp::ConnectionPtr& conn); bool mActive; QString mActiveAccountId; QString mState; QMap mSerials; }; #endif // USSDMANAGER_H telephony-service-0.1+14.04.20140415/libtelephonyservice/callmanager.h0000644000015301777760000000653612323307402026121 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CALLMANAGER_H #define CALLMANAGER_H #include #include #include #include #include class CallEntry; class TelepathyHelper; class CallManager : public QObject { Q_OBJECT Q_PROPERTY(QObject *foregroundCall READ foregroundCall NOTIFY foregroundCallChanged) Q_PROPERTY(QObject *backgroundCall READ backgroundCall NOTIFY backgroundCallChanged) Q_PROPERTY(bool hasCalls READ hasCalls NOTIFY hasCallsChanged) Q_PROPERTY(bool hasBackgroundCall READ hasBackgroundCall NOTIFY hasBackgroundCallChanged) Q_PROPERTY(QString voicemailNumber READ getVoicemailNumber NOTIFY voicemailNumberChanged) Q_PROPERTY(QQmlListProperty calls READ calls NOTIFY callsChanged) public: static CallManager *instance(); Q_INVOKABLE void startCall(const QString &phoneNumber, const QString &accountId = QString::null); Q_INVOKABLE QString getVoicemailNumber(); Q_INVOKABLE void mergeCalls(CallEntry *firstCall, CallEntry *secondCall); Q_INVOKABLE void splitCall(CallEntry *callEntry); CallEntry *foregroundCall() const; CallEntry *backgroundCall() const; QList activeCalls() const; QQmlListProperty calls(); bool hasCalls() const; bool hasBackgroundCall() const; // conference related members QList takeCalls(const QList callChannels); void addCalls(const QList entries); // QQmlListProperty helpers static int callsCount(QQmlListProperty *p); static CallEntry* callAt(QQmlListProperty *p, int index); Q_SIGNALS: void callEnded(CallEntry *entry); void foregroundCallChanged(); void backgroundCallChanged(); void callsChanged(); void hasCallsChanged(); void hasBackgroundCallChanged(); void speakerChanged(); void voicemailNumberChanged(); public Q_SLOTS: void onCallChannelAvailable(Tp::CallChannelPtr channel); void onChannelObserverUnregistered(); void onCallEnded(); void onConnectedChanged(); private: explicit CallManager(QObject *parent = 0); void refreshProperties(); void setupCallEntry(CallEntry *entry); mutable QList mCallEntries; QString mVoicemailNumber; bool mNeedsUpdate; CallEntry *mConferenceCall; }; #endif // CALLMANAGER_H telephony-service-0.1+14.04.20140415/libtelephonyservice/phonenumberutils.h0000644000015301777760000001725012323307402027251 0ustar pbusernogroup00000000000000/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Original source code available at: http://androidxref.com/4.0.4/xref/frameworks/base/telephony/java/android/telephony/PhoneNumberUtils.java */ #ifndef PHONENUMBERUTILS_H #define PHONENUMBERUTILS_H #include namespace PhoneNumberUtils { /** True if c is ISO-LATIN characters 0-9, *, # , +, WILD, WAIT, PAUSE */ bool isNonSeparator(char c) { return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N' || c == ';' || c == ','; } /** True if c is ISO-LATIN characters 0-9, *, # , +, WILD */ bool isDialable(char c) { return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N'; } /** True if c is ISO-LATIN characters 0-9 */ bool isISODigit (char c) { return c >= '0' && c <= '9'; } /** or -1 if both are negative */ int minPositive (int a, int b) { if (a >= 0 && b >= 0) { return (a < b) ? a : b; } else if (a >= 0) { /* && b < 0 */ return a; } else if (b >= 0) { /* && a < 0 */ return b; } else { /* a < 0 && b < 0 */ return -1; } } /** index of the last character of the network portion * (eg anything after is a post-dial string) */ int indexOfLastNetworkChar(const QString &a) { int pIndex, wIndex; int origLength; int trimIndex; origLength = a.length(); pIndex = a.indexOf(','); wIndex = a.indexOf(';'); trimIndex = minPositive(pIndex, wIndex); if (trimIndex < 0) { return origLength - 1; } else { return trimIndex - 1; } } /** all of a up to len must be an international prefix or * separators/non-dialing digits */ bool matchIntlPrefix(const QString &a, int len) { /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */ /* 0 1 2 3 45 */ int state = 0; for (int i = 0 ; i < len ; i++) { char c = a.at(i).toLatin1(); switch (state) { case 0: if (c == '+') state = 1; else if (c == '0') state = 2; else if (isNonSeparator(c)) return false; break; case 2: if (c == '0') state = 3; else if (c == '1') state = 4; else if (isNonSeparator(c)) return false; break; case 4: if (c == '1') state = 5; else if (isNonSeparator(c)) return false; break; default: if (isNonSeparator(c)) return false; break; } } return state == 1 || state == 3 || state == 5; } /** all of 'a' up to len must match non-US trunk prefix ('0') */ bool matchTrunkPrefix(const QString &a, int len) { bool found; found = false; for (int i = 0 ; i < len ; i++) { char c = a.at(i).toLatin1(); if (c == '0' && !found) { found = true; } else if (isNonSeparator(c)) { return false; } } return found; } /** all of 'a' up to len must be a (+|00|011)country code) * We're fast and loose with the country code. Any \d{1,3} matches */ bool matchIntlPrefixAndCC(const QString &a, int len) { /* [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */ /* 0 1 2 3 45 6 7 8 */ int state = 0; for (int i = 0 ; i < len ; i++ ) { char c = a.at(i).toLatin1(); switch (state) { case 0: if (c == '+') state = 1; else if (c == '0') state = 2; else if (isNonSeparator(c)) return false; break; case 2: if (c == '0') state = 3; else if (c == '1') state = 4; else if (isNonSeparator(c)) return false; break; case 4: if (c == '1') state = 5; else if (isNonSeparator(c)) return false; break; case 1: case 3: case 5: if (isISODigit(c)) state = 6; else if (isNonSeparator(c)) return false; break; case 6: case 7: if (isISODigit(c)) state++; else if (isNonSeparator(c)) return false; break; default: if (isNonSeparator(c)) return false; } } return state == 6 || state == 7 || state == 8; } /** * Compare phone numbers a and b, return true if they're identical * enough for caller ID purposes. * * - Compares from right to left * - requires MIN_MATCH (7) characters to match * - handles common trunk prefixes and international prefixes * (basically, everything except the Russian trunk prefix) * * Note that this method does not return false even when the two phone numbers * are not exactly same; rather; we can call this method "similar()", not "equals()". * * @hide */ bool compareLoosely(const QString &a, const QString &b) { int ia, ib; int matched; int numNonDialableCharsInA = 0; int numNonDialableCharsInB = 0; if (a.length() == 0 || b.length() == 0) { return false; } if (a == b) { return true; } ia = indexOfLastNetworkChar (a); ib = indexOfLastNetworkChar (b); matched = 0; while (ia >= 0 && ib >=0) { char ca, cb; bool skipCmp = false; ca = a.at(ia).toLatin1(); if (!isDialable(ca)) { ia--; skipCmp = true; numNonDialableCharsInA++; } cb = b.at(ib).toLatin1(); if (!isDialable(cb)) { ib--; skipCmp = true; numNonDialableCharsInB++; } if (!skipCmp) { if (cb != ca && ca != 'N' && cb != 'N') { break; } ia--; ib--; matched++; } } if (matched < 7) { int effectiveALen = a.length() - numNonDialableCharsInA; int effectiveBLen = b.length() - numNonDialableCharsInB; // if the number of dialable chars in a and b match, but the matched chars < MIN_MATCH, // treat them as equal (i.e. 404-04 and 40404) if (effectiveALen == effectiveBLen && effectiveALen == matched) { return true; } return false; } // At least one string has matched completely; if (matched >= 7 && (ia < 0 || ib < 0)) { return true; } /* * Now, what remains must be one of the following for a * match: * * - a '+' on one and a '00' or a '011' on the other * - a '0' on one and a (+,00) on the other * (for this, a '0' and a '00' prefix would have succeeded above) */ if (matchIntlPrefix(a, ia + 1) && matchIntlPrefix (b, ib +1) ) { return true; } if (matchTrunkPrefix(a, ia + 1) && matchIntlPrefixAndCC(b, ib +1) ) { return true; } if (matchTrunkPrefix(b, ib + 1) && matchIntlPrefixAndCC(a, ia +1) ) { return true; } return false; } } #endif telephony-service-0.1+14.04.20140415/libtelephonyservice/phoneutils.cpp0000644000015301777760000000320212323307402026363 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "phoneutils.h" #include "phonenumberutils.h" PhoneUtils::PhoneUtils(QObject *parent) : QObject(parent) { } bool PhoneUtils::comparePhoneNumbers(const QString &number1, const QString &number2) { if (isPhoneNumber(number1) && isPhoneNumber(number2)) { return PhoneNumberUtils::compareLoosely(number1, number2); } // if at least one of the id's is not a phone number, then perform a simple string comparison return number1 == number2; } bool PhoneUtils::isPhoneNumber(const QString &identifier) { // remove all non diable digits QString finalNumber = QString(identifier).replace(QRegExp("[p+*#(),;-]"),""); finalNumber = finalNumber.replace(QRegExp("(\\s+)"), ""); // if empty, the number is invalid if (finalNumber.isEmpty()) return false; finalNumber = finalNumber.replace(QRegExp("(\\d+)"), ""); return finalNumber.isEmpty(); } telephony-service-0.1+14.04.20140415/libtelephonyservice/callnotification.cpp0000644000015301777760000000737512323307402027532 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "callnotification.h" #include "contactutils.h" #include "config.h" #include #include #include #include namespace C { #include } CallNotification::CallNotification(QObject *parent) : QObject(parent) { } CallNotification *CallNotification::instance() { static CallNotification *self = new CallNotification(); return self; } void CallNotification::showNotificationForCall(const QStringList &participants, CallNotification::NotificationReason reason) { // FIXME: the new designs don't have on screen notifications, and that's why they are disabled here // in case that changes again in the future, just remove the #if 0 #if 0 QString title; bool isConference = participants.count() > 1; switch (reason) { case CallHeld: title = isConference? C::gettext("Conf call on hold") : C::gettext("%1 call on hold"); break; case CallEnded: title = isConference? C::gettext("Conf call ended") : C::gettext("%1 call ended"); break; case CallRejected: title = C::gettext("%1 call declined"); break; } // just to make things easier, search for a contact even when the call is a conference QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(participants.first())); // place the notify-notification item only after the contact fetch request is finished, as we can´t simply update QObject::connect(request, &QContactAbstractRequest::stateChanged, [request, participants, title, isConference]() { QString finalTitle = title; // only process the results after the finished state is reached if (request->state() != QContactAbstractRequest::FinishedState) { return; } QString displayLabel; QString avatar; if (request->contacts().size() > 0) { QContact contact = request->contacts().at(0); displayLabel = ContactUtils::formatContactName(contact); avatar = contact.detail().imageUrl().toEncoded(); } if (!isConference) { finalTitle = title.arg(displayLabel.isEmpty() ? participants[0] : displayLabel); } if (avatar.isEmpty()) { avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); } // show the notification NotifyNotification *notification = notify_notification_new(finalTitle.toStdString().c_str(), NULL, avatar.toStdString().c_str()); GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show message notification:" << error->message; g_error_free (error); } }); request->setManager(ContactUtils::sharedManager()); request->start(); #endif } telephony-service-0.1+14.04.20140415/COPYING.CC-BY-SA-30000644000015301777760000005333612323307402021713 0ustar pbusernogroup00000000000000Creative Commons Legal Code Attribution-ShareAlike 3.0 Unported CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. License THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 1. Definitions a. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. b. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License. c. "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License. d. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. e. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. f. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. g. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. h. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. i. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. j. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. k. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: a. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; b. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; c. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, d. to Distribute and Publicly Perform Adaptations. e. For the avoidance of doubt: i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, iii. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested. b. You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License. c. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. d. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. 5. Representations, Warranties and Disclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. Termination a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 8. Miscellaneous a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. b. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. e. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. Creative Commons Notice Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of the License. Creative Commons may be contacted at http://creativecommons.org/. telephony-service-0.1+14.04.20140415/config.h.in0000644000015301777760000000310512323307402021433 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Olivier Tilloy * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ // Qt #include #include #include #include #include inline bool isRunningInstalled() { static bool installed = (QCoreApplication::applicationDirPath() == QDir(("@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@")).canonicalPath()); return installed; } inline QString telephonyServiceDir() { if (isRunningInstalled()) { return QString("@CMAKE_INSTALL_PREFIX@/@TELEPHONY_SERVICE_DIR@/"); } else { return QString("@CMAKE_SOURCE_DIR@/"); } } inline QString ubuntuPhonePluginPath() { if (isRunningInstalled()) { return QString::null; } else { return QString("@CMAKE_SOURCE_DIR@/"); } } telephony-service-0.1+14.04.20140415/assets/0000755000015301777760000000000012323310021020702 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/assets/avatar-default@18.png0000644000015301777760000000471312323307402024577 0ustar pbusernogroup00000000000000PNG  IHDRFtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp +=IDATx_Un뺛FnTdV[[EZ(6?Rp!I  0z(57k?km̾T{z{?Ίܙߜg̝9ajjTJ#U@@@@@@@@&BТbFE]qe*#4.>YqX,^S5V ӠSѭYJsŰ't(*aw}igT/)>U|&(^~ I4)?\KW'c  i wZX!_ ,^l7(.@h<@鏤݁L7!'iV܊@n B;#!3?ea.#P?UDPBE!PFp "4"8'8)9@(v_y#PFF <#&0D*!+U|hg(K/Kũ> > t|( kt)|#CBc@_nyk59kRy1, #j!#߱9g{׶X*8j-x֠:KbBGR?SZ P y*6OK^Sq=PqyG }),+2ۈ[</їO~Nsn|/cl2WeMn39:bbF};Or У*&?8RMH$3O,dQ ǷVSQvq4Coҿs@N&~>,Nґfkj`VŐJܮH&czҬ]$eBqgڻ\.[?_ų%Ҵȿ1 tyo+jk`;'\-@p{ o5j^KOٱ۪:\I).SߕV4XQ(~I88չ?MRס?XxLQ uʽSF6J`$ZQ0-5]s:$-(bH{>*2E>\':XYV6Ethͭ@~ B6LS !A5@@@@@@@@> 4ES P~)( #4!!"͑ 2# "N)vرol 2̨P(x&h@ @ @ @ @ @ @ @ -;;XIENDB`telephony-service-0.1+14.04.20140415/indicator/0000755000015301777760000000000012323310021021354 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/indicator/callchannelobserver.cpp0000644000015301777760000000741312323307402026112 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "callchannelobserver.h" #include "callnotification.h" #include "messagingmenu.h" #include "metrics.h" #include "telepathyhelper.h" #include CallChannelObserver::CallChannelObserver(QObject *parent) : QObject(parent) { } void CallChannelObserver::onCallChannelAvailable(Tp::CallChannelPtr callChannel) { // save the timestamp as a property in the call channel callChannel->setProperty("timestamp", QDateTime::currentDateTime()); if (callChannel->callState() == Tp::CallStateActive) { callChannel->setProperty("activeTimestamp", QDateTime::currentDateTime()); } connect(callChannel.data(), SIGNAL(callStateChanged(Tp::CallState)), SLOT(onCallStateChanged(Tp::CallState))); connect(callChannel.data(), SIGNAL(localHoldStateChanged(Tp::LocalHoldState,Tp::LocalHoldStateReason)), SLOT(onHoldChanged())); mChannels.append(callChannel); } void CallChannelObserver::onCallStateChanged(Tp::CallState state) { Tp::CallChannelPtr channel(qobject_cast(sender())); if (!channel) { return; } Tp::AccountPtr account = TelepathyHelper::instance()->accountForConnection(channel->connection()); if (!account) { return; } bool incoming = channel->initiatorContact() != account->connection()->selfContact(); bool missed = incoming && channel->callStateReason().reason == Tp::CallStateChangeReasonNoAnswer; QDateTime activeTimestamp = channel->property("activeTimestamp").toDateTime(); switch (state) { case Tp::CallStateEnded: Q_EMIT callEnded(channel); // add the missed call to the messaging menu if (missed) { // FIXME: handle conf call MessagingMenu::instance()->addCall(channel->targetContact()->id(), QDateTime::currentDateTime()); } else { // and show a notification // FIXME: handle conf call CallNotification::instance()->showNotificationForCall(QStringList() << channel->targetContact()->id(), CallNotification::CallEnded); } mChannels.removeOne(channel); // update the metrics Metrics::instance()->increment(incoming ? Metrics::IncomingCalls : Metrics::OutgoingCalls); if (activeTimestamp.isValid()) { double minutes = activeTimestamp.secsTo(QDateTime::currentDateTime()) / 60.; Metrics::instance()->increment(Metrics::CallDurations, qRound(minutes * 100) / 100); } break; case Tp::CallStateActive: channel->setProperty("activeTimestamp", QDateTime::currentDateTime()); break; } } void CallChannelObserver::onHoldChanged() { Tp::CallChannelPtr channel(qobject_cast(sender())); if (!channel) { return; } if (channel->localHoldState() == Tp::LocalHoldStateHeld) { // FIXME: handle conf call CallNotification::instance()->showNotificationForCall(QStringList() << channel->targetContact()->id(), CallNotification::CallHeld); } } telephony-service-0.1+14.04.20140415/indicator/icons/0000755000015301777760000000000012323310021022467 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/indicator/icons/notification-unknown-call.svg0000644000015301777760000001210212323307402030311 0ustar pbusernogroup00000000000000 telephony-service-0.1+14.04.20140415/indicator/icons/notification-group-call.svg0000644000015301777760000002533112323307402027756 0ustar pbusernogroup00000000000000 telephony-service-0.1+14.04.20140415/indicator/icons/notification-unavailable-image-call.svg0000644000015301777760000001212112323307402032156 0ustar pbusernogroup00000000000000 telephony-service-0.1+14.04.20140415/indicator/icons/CMakeLists.txt0000644000015301777760000000032112323307402025234 0ustar pbusernogroup00000000000000 set(icons notification-group-call.svg notification-unavailable-image-call.svg notification-unknown-call.svg ) install(FILES ${icons} DESTINATION share/notify-osd/icons/gnome/scalable/status) telephony-service-0.1+14.04.20140415/indicator/voicemailindicator.h0000644000015301777760000000245112323307402025405 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef VOICEMAILINDICATOR_H #define VOICEMAILINDICATOR_H #include #include #include class VoiceMailIndicator : public QObject { Q_OBJECT public: explicit VoiceMailIndicator(QObject *parent = 0); public Q_SLOTS: void onVoicemailCountChanged(uint count); void onVoicemailIndicatorChanged(bool active); void onAccountReady(); private: bool voicemailIndicatorVisible(); uint voicemailCount(); bool checkConnected(); QDBusConnection mConnection; }; #endif // VOICEMAILINDICATOR_H telephony-service-0.1+14.04.20140415/indicator/DBusTypes.h0000644000015301777760000000206512323307402023423 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see . * * Author: Pete Woods */ #ifndef DBUSTYPES_H_ #define DBUSTYPES_H_ #include #include typedef QMap QVariantDictMap; Q_DECLARE_METATYPE(QVariantDictMap) class DBusTypes { public: static void registerMetaTypes() { qRegisterMetaType("QVariantDictMap"); qDBusRegisterMetaType(); } }; #endif /* DBUSTYPES_H_ */ telephony-service-0.1+14.04.20140415/indicator/ussdmenu.cpp0000644000015301777760000001057012323307402023737 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see . * * Author: Pete Woods * Author: Tiago Salem Herrmann */ #include "ussdmenu.h" #include #include #include static const QString USSD_ACTION_PATH("/action/%1"); static const QString USSD_MENU_PATH("/menu/%1"); class USSDMenuPriv { public: USSDMenuPriv() : m_connection(g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL)), m_exportedActionGroupId(0), m_exportedMenuModelId(0) { } ~USSDMenuPriv() { g_object_unref(m_connection); } static void responseChangedCallback(GAction *responseAction, GVariant *variant, gpointer userData) { USSDMenuPriv *self(reinterpret_cast(userData)); self->m_response = QString::fromUtf8(g_variant_get_string(variant, 0)); } GDBusConnection *m_connection; QString m_busName; QString m_actionPath; QString m_menuPath; unsigned int m_exportedActionGroupId; unsigned int m_exportedMenuModelId; QString m_response; }; USSDMenu::USSDMenu(bool needsResponse) : p(new USSDMenuPriv()) { int exportrev; p->m_busName = QString::fromUtf8( g_dbus_connection_get_unique_name(p->m_connection)); // menu GMenu *menu(g_menu_new()); GMenuItem *ussdItem(g_menu_item_new("", "notifications.ussd")); if (needsResponse) { g_menu_item_set_attribute_value(ussdItem, "x-canonical-type", g_variant_new_string("com.canonical.snapdecision.textfield")); g_menu_item_set_attribute_value(ussdItem, "x-echo-mode-password", g_variant_new_boolean(false)); g_menu_append_item(menu, ussdItem); } // actions GActionGroup *actions(G_ACTION_GROUP(g_simple_action_group_new())); GAction *ussdAction(G_ACTION( g_simple_action_new_stateful("ussd", G_VARIANT_TYPE_STRING, g_variant_new_string("")))); g_signal_connect(G_OBJECT(ussdAction), "change-state", G_CALLBACK(USSDMenuPriv::responseChangedCallback), reinterpret_cast(p.data())); g_action_map_add_action(G_ACTION_MAP(actions), ussdAction); /* Export the actions group. If we can't get a name, keep trying to use increasing numbers. There is possible races on fast import/exports. They're rare, but worth protecting against. */ exportrev = 0; do { exportrev++; p->m_actionPath = USSD_ACTION_PATH.arg(exportrev); p->m_exportedActionGroupId = g_dbus_connection_export_action_group( p->m_connection, p->m_actionPath.toUtf8().data(), actions, NULL); } while (p->m_exportedActionGroupId == 0 && exportrev < 128); /* Export the menu. If we can't get a name, keep trying to use increasing numbers. There is possible races on fast import/exports. They're rare, but worth protecting against. */ exportrev = 0; do { exportrev++; p->m_menuPath = USSD_MENU_PATH.arg(exportrev); p->m_exportedMenuModelId = g_dbus_connection_export_menu_model( p->m_connection, p->m_menuPath.toUtf8().data(), G_MENU_MODEL(menu), NULL); } while (p->m_exportedMenuModelId == 0 && exportrev < 128); /* Unref the objects as a reference is maintained by the fact that they're exported onto the bus. */ g_object_unref(menu); g_object_unref(ussdItem); g_object_unref(actions); g_object_unref(ussdAction); } USSDMenu::~USSDMenu() { g_dbus_connection_unexport_action_group(p->m_connection, p->m_exportedActionGroupId); g_dbus_connection_unexport_menu_model(p->m_connection, p->m_exportedMenuModelId); } const QString & USSDMenu::busName() const { return p->m_busName; } const QString & USSDMenu::response() const { return p->m_response; } const QString & USSDMenu::actionPath() const { return p->m_actionPath; } const QString & USSDMenu::menuPath() const { return p->m_menuPath; } void USSDMenu::clearResponse() { p->m_response.clear(); } telephony-service-0.1+14.04.20140415/indicator/ussdmenu.h0000644000015301777760000000226212323307402023403 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see . * * Author: Pete Woods * Author: Tiago Salem Herrmann */ #ifndef USSDMENU_H_ #define USSDMENU_H_ #include #include class USSDMenuPriv; class USSDMenu { public: USSDMenu(bool needsResponse = false); virtual ~USSDMenu(); const QString & busName() const; const QString & response() const; const QString & actionPath() const; const QString & menuPath() const; void clearResponse(); protected: QScopedPointer p; }; #endif /* USSDMENU_H_ */ telephony-service-0.1+14.04.20140415/indicator/metrics.cpp0000644000015301777760000000655412323307402023551 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Ugo Riboni * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "metrics.h" #include const QString APP_ID = QString("telephony-service"); const QString MESSAGES_RECEIVED_STATISTICS_ID = QString("text-messages-received"); const QString MESSAGES_SENT_STATISTICS_ID = QString("text-messages-sent"); const QString DIALER_INCOMING_STATISTICS_ID = QString("dialer-calls-incoming"); const QString DIALER_OUTGOING_STATISTICS_ID = QString("dialer-calls-outgoing"); const QString DIALER_CALL_DURATION_STATISTICS_ID = QString("dialer-calls-duration"); using namespace UserMetricsInput; Metrics::Metrics(QObject *parent) : QObject(parent) { try { mMetricManager.reset(MetricManager::getInstance()); mMetrics[SentMessages] = mMetricManager->add(MetricParameters(MESSAGES_SENT_STATISTICS_ID).formatString("%1 text messages sent today") .emptyDataString("No text messages sent today").textDomain(APP_ID).minimum(0.0)); mMetrics[ReceivedMessages] = mMetricManager->add(MetricParameters(MESSAGES_RECEIVED_STATISTICS_ID).formatString("%1 text messages received today") .emptyDataString("No text messages received today").textDomain(APP_ID).minimum(0.0)); mMetrics[IncomingCalls] = mMetricManager->add(MetricParameters(DIALER_INCOMING_STATISTICS_ID).formatString("%1 calls received today") .emptyDataString("No calls received today").textDomain(APP_ID).minimum(0.0)); mMetrics[OutgoingCalls] = mMetricManager->add(MetricParameters(DIALER_OUTGOING_STATISTICS_ID).formatString("%1 calls made today") .emptyDataString("No calls made today").textDomain(APP_ID).minimum(0.0)); mMetrics[CallDurations] = mMetricManager->add(MetricParameters(DIALER_CALL_DURATION_STATISTICS_ID).formatString("Spent %1 minutes in calls today") .emptyDataString("No calls made today").textDomain(APP_ID).minimum(0.0)); } catch(std::exception &e) { qWarning() << "Error connecting to metrics service:" << e.what(); } } Metrics *Metrics::instance() { static Metrics *self = new Metrics(); return self; } void Metrics::increment(Metrics::MetricType metric, double amount) { MetricPtr metricPtr; metricPtr = mMetrics[metric]; if (!metricPtr) { return; } try { metricPtr->increment(amount); } catch(std::exception &e) { qWarning() << "Error incrementing telephony metric:" << e.what(); } } telephony-service-0.1+14.04.20140415/indicator/messagingmenu.cpp0000644000015301777760000004351012323307402024736 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "applicationutils.h" #include "callmanager.h" #include "config.h" #include "contactutils.h" #include "phoneutils.h" #include "messagingmenu.h" #include "telepathyhelper.h" #include #include #include #include #include #include #include #include #include #include namespace C { #include } #define SOURCE_ID "telephony-service-indicator" QTCONTACTS_USE_NAMESPACE MessagingMenu::MessagingMenu(QObject *parent) : QObject(parent), mVoicemailCount(-1), mVoicemailId("voicemail") { GIcon *icon = g_icon_new_for_string("telephony-service-indicator", NULL); mMessagesApp = messaging_menu_app_new("telephony-service-sms.desktop"); messaging_menu_app_register(mMessagesApp); messaging_menu_app_append_source(mMessagesApp, SOURCE_ID, icon, C::gettext("Telephony Service")); mCallsApp = messaging_menu_app_new("telephony-service-call.desktop"); messaging_menu_app_register(mCallsApp); messaging_menu_app_append_source(mCallsApp, SOURCE_ID, icon, C::gettext("Telephony Service")); g_object_unref(icon); } void MessagingMenu::addFlashMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text) { QUrl iconPath = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); QString contactAlias = phoneNumber; GFile *file = g_file_new_for_uri(iconPath.toString().toUtf8().data()); GIcon *icon = g_file_icon_new(file); MessagingMenuMessage *message = messaging_menu_message_new(messageId.toUtf8().data(), icon, "", NULL, text.toUtf8().data(), timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds /* FIXME: uncomment when messaging-menu support two regular buttons messaging_menu_message_add_action(message, "saveFlashMessage", C::gettext("Save"), NULL, NULL ); messaging_menu_message_add_action(message, "dismiss", C::gettext("Dismiss"), NULL, NULL ); */ g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::flashMessageActivateCallback), this); QVariantMap details; details["phoneNumber"] = phoneNumber; details["messageId"] = messageId; details["timestamp"] = timestamp; details["text"] = text; mMessages[messageId] = details; messaging_menu_app_append_message(mMessagesApp, message, SOURCE_ID, true); g_object_unref(file); g_object_unref(icon); g_object_unref(message); } void MessagingMenu::addMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text) { // try to get a contact for that phone number QUrl iconPath = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); QString contactAlias = phoneNumber; // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(phoneNumber)); // place the messaging-menu item only after the contact fetch request is finished, as we can´t simply update QObject::connect(request, &QContactAbstractRequest::stateChanged, [request, phoneNumber, messageId, text, timestamp, iconPath, contactAlias, this]() { // only process the results after the finished state is reached if (request->state() != QContactAbstractRequest::FinishedState) { return; } QString displayLabel; QUrl avatar; if (request->contacts().size() > 0) { QContact contact = request->contacts().at(0); displayLabel = ContactUtils::formatContactName(contact); avatar = contact.detail().imageUrl(); } if (displayLabel.isEmpty()) { displayLabel = contactAlias; } if (avatar.isEmpty()) { avatar = iconPath; } GFile *file = g_file_new_for_uri(avatar.toString().toUtf8().data()); GIcon *icon = g_file_icon_new(file); MessagingMenuMessage *message = messaging_menu_message_new(messageId.toUtf8().data(), icon, displayLabel.toUtf8().data(), NULL, text.toUtf8().data(), timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds messaging_menu_message_add_action(message, "quickReply", NULL, // label G_VARIANT_TYPE("s"), NULL // predefined values ); g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::messageActivateCallback), this); // save the phone number to use in the actions QVariantMap details; details["phoneNumber"] = phoneNumber; mMessages[messageId] = details; messaging_menu_app_append_message(mMessagesApp, message, SOURCE_ID, true); g_object_unref(file); g_object_unref(icon); g_object_unref(message); }); request->setManager(ContactUtils::sharedManager()); request->start(); } void MessagingMenu::removeMessage(const QString &messageId) { if (!mMessages.contains(messageId)) { return; } messaging_menu_app_remove_message_by_id(mMessagesApp, messageId.toUtf8().data()); mMessages.remove(messageId); } void MessagingMenu::addCall(const QString &phoneNumber, const QDateTime ×tamp) { Call call; bool found = false; Q_FOREACH(Call callMessage, mCalls) { if (PhoneUtils::comparePhoneNumbers(callMessage.number, phoneNumber)) { call = callMessage; found = true; mCalls.removeOne(callMessage); // remove the previous entry and add a new one increasing the missed call count messaging_menu_app_remove_message_by_id(mCallsApp, callMessage.messageId.toUtf8().data()); break; } } if (!found) { call.contactAlias = phoneNumber; call.contactIcon = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); call.number = phoneNumber; call.count = 0; } call.count++; QString text; text = QString::fromUtf8(C::ngettext("%1 missed call", "%1 missed calls", call.count)).arg(call.count); // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(phoneNumber)); // place the messaging-menu item only after the contact fetch request is finished, as we can´t simply update QObject::connect(request, &QContactAbstractRequest::stateChanged, [request, call, text, timestamp, this]() { // only process the results after the finished state is reached if (request->state() != QContactAbstractRequest::FinishedState) { return; } Call newCall = call; if (request->contacts().size() > 0) { QContact contact = request->contacts().at(0); QString displayLabel = ContactUtils::formatContactName(contact); QUrl avatar = contact.detail().imageUrl(); if (!displayLabel.isEmpty()) { newCall.contactAlias = displayLabel; } if (!avatar.isEmpty()) { newCall.contactIcon = avatar; } } GFile *file = g_file_new_for_uri(newCall.contactIcon.toString().toUtf8().data()); GIcon *icon = g_file_icon_new(file); MessagingMenuMessage *message = messaging_menu_message_new(newCall.number.toUtf8().data(), icon, newCall.contactAlias.toUtf8().data(), NULL, text.toUtf8().data(), timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds newCall.messageId = messaging_menu_message_get_id(message); messaging_menu_message_add_action(message, "callBack", NULL, // label NULL, // argument type NULL // predefined values ); const char *predefinedMessages[] = { C::gettext("I missed your call - can you call me now?"), C::gettext("I'm running late. I'm on my way."), C::gettext("I'm busy at the moment. I'll call you later."), C::gettext("I'll be 20 minutes late."), C::gettext("Sorry, I'm still busy. I'll call you later."), 0 }; GVariant *messages = g_variant_new_strv(predefinedMessages, -1); messaging_menu_message_add_action(message, "replyWithMessage", NULL, // label G_VARIANT_TYPE("s"), messages // predefined values ); g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::callsActivateCallback), this); messaging_menu_app_append_message(mCallsApp, message, SOURCE_ID, true); mCalls.append(newCall); g_object_unref(messages); g_object_unref(file); g_object_unref(icon); g_object_unref(message); }); request->setManager(ContactUtils::sharedManager()); request->start(); } void MessagingMenu::showVoicemailEntry(uint count) { if (!mVoicemailId.isEmpty()) { // if the count didn't change, don't do anything if (count == mVoicemailCount) { return; } messaging_menu_app_remove_message_by_id(mCallsApp, mVoicemailId.toUtf8().data()); } QString messageBody = C::gettext("Voicemail messages"); if (count != 0) { messageBody = QString::fromUtf8(C::ngettext("%1 voicemail message", "%1 voicemail messages", count)).arg(count); } GIcon *icon = g_themed_icon_new("indicator-call"); MessagingMenuMessage *message = messaging_menu_message_new(mVoicemailId.toUtf8().data(), icon, "Voicemail", NULL, messageBody.toUtf8().data(), QDateTime::currentDateTime().toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::callsActivateCallback), this); messaging_menu_app_append_message(mCallsApp, message, SOURCE_ID, true); g_object_unref(icon); g_object_unref(message); } void MessagingMenu::hideVoicemailEntry() { messaging_menu_app_remove_message_by_id(mCallsApp, mVoicemailId.toUtf8().data()); } void MessagingMenu::messageActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance) { QString action(actionId); QString messageId(messaging_menu_message_get_id(message)); QString text(g_variant_get_string(param, NULL)); if (action == "quickReply") { QMetaObject::invokeMethod(instance, "sendMessageReply", Q_ARG(QString, messageId), Q_ARG(QString, text)); } else if (action.isEmpty()) { QMetaObject::invokeMethod(instance, "showMessage", Q_ARG(QString, messageId)); } } void MessagingMenu::flashMessageActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance) { QString action(actionId); QString messageId(messaging_menu_message_get_id(message)); if (action == "saveFlashMessage") { QMetaObject::invokeMethod(instance, "saveFlashMessage", Q_ARG(QString, messageId)); } } void MessagingMenu::callsActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance) { QString action(actionId); QString messageId(messaging_menu_message_get_id(message)); if (messageId == instance->mVoicemailId) { QMetaObject::invokeMethod(instance, "callVoicemail", Q_ARG(QString, messageId)); return; } if (action == "callBack" || action.isEmpty()) { QMetaObject::invokeMethod(instance, "callBack", Q_ARG(QString, messageId)); } else if (action == "replyWithMessage") { QString text(g_variant_get_string(param, NULL)); QMetaObject::invokeMethod(instance, "replyWithMessage", Q_ARG(QString, messageId), Q_ARG(QString, text)); } } void MessagingMenu::sendMessageReply(const QString &messageId, const QString &reply) { QString phoneNumber = mMessages[messageId]["phoneNumber"].toString(); Q_EMIT replyReceived(phoneNumber, reply); Q_EMIT messageRead(phoneNumber, messageId); } void MessagingMenu::saveFlashMessage(const QString &messageId) { QVariantMap details = mMessages[messageId]; // TODO: handle dual sim History::Thread thread = History::Manager::instance()->threadForParticipants(TelepathyHelper::instance()->accountIds()[0], History::EventTypeText, QStringList() << details["phoneNumber"].toString(), History::MatchPhoneNumber, true); History::TextEvent textEvent(TelepathyHelper::instance()->accountIds()[0], thread.threadId(), details["messageId"].toString(), details["phoneNumber"].toString(), details["timestamp"].toDateTime(), false, details["text"].toString(), History::MessageTypeText); History::Events events; events.append(textEvent); History::Manager::instance()->writeEvents(events); } void MessagingMenu::showMessage(const QString &messageId) { QString phoneNumber = mMessages[messageId]["phoneNumber"].toString(); ApplicationUtils::openUrl(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(phoneNumber)))); } void MessagingMenu::callBack(const QString &messageId) { QString phoneNumber = callFromMessageId(messageId).number; qDebug() << "TelephonyService/MessagingMenu: Calling back" << phoneNumber; ApplicationUtils::openUrl(QString("tel:///%1").arg(QString(QUrl::toPercentEncoding(phoneNumber)))); } void MessagingMenu::replyWithMessage(const QString &messageId, const QString &reply) { QString phoneNumber = callFromMessageId(messageId).number; qDebug() << "TelephonyService/MessagingMenu: Replying to call" << phoneNumber << "with text" << reply; Q_EMIT replyReceived(phoneNumber, reply); } void MessagingMenu::callVoicemail(const QString &messageId) { qDebug() << "TelephonyService/MessagingMenu: Calling voicemail for messageId" << messageId; QString voicemailNumber = CallManager::instance()->getVoicemailNumber(); if (!voicemailNumber.isEmpty()) { ApplicationUtils::openUrl(QUrl(QString("tel:///%1").arg(voicemailNumber))); } } Call MessagingMenu::callFromMessageId(const QString &messageId) { Q_FOREACH(const Call &call, mCalls) { if (call.messageId == messageId) { return call; } } return Call(); } MessagingMenu *MessagingMenu::instance() { static MessagingMenu *menu = new MessagingMenu(); return menu; } MessagingMenu::~MessagingMenu() { g_object_unref(mMessagesApp); g_object_unref(mCallsApp); } telephony-service-0.1+14.04.20140415/indicator/ussdindicator.h0000644000015301777760000000333712323307402024417 0ustar pbusernogroup00000000000000/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef USSDINDICATOR_H #define USSDINDICATOR_H #include #include #include "indicator/NotificationsInterface.h" #include "ussdmanager.h" #include "ussdmenu.h" class USSDIndicator : public QObject { Q_OBJECT public: explicit USSDIndicator(QObject *parent = 0); void showUSSDNotification(const QString &message, bool replyRequired); public Q_SLOTS: void onNotificationReceived(const QString &message); void onRequestReceived(const QString &message); void onInitiateUSSDComplete(const QString &ussdResp); void onRespondComplete(bool success, const QString &ussdResp); void onStateChanged(const QString &state); void actionInvoked(uint id, const QString &actionKey); void notificationClosed(uint id, uint reason); private: unsigned int m_notificationId; USSDMenu m_menuRequest; USSDMenu m_menuNotification; QString mPendingMessage; org::freedesktop::Notifications m_notifications; }; #endif // USSDINDICATOR_H telephony-service-0.1+14.04.20140415/indicator/callchannelobserver.h0000644000015301777760000000245512323307402025560 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CALLCHANNELOBSERVER_H #define CALLCHANNELOBSERVER_H #include #include class CallChannelObserver : public QObject { Q_OBJECT public: explicit CallChannelObserver(QObject *parent = 0); public Q_SLOTS: void onCallChannelAvailable(Tp::CallChannelPtr callChannel); Q_SIGNALS: void callEnded(Tp::CallChannelPtr callChannel); protected Q_SLOTS: void onCallStateChanged(Tp::CallState state); void onHoldChanged(); private: QList mChannels; }; #endif // CALLCHANNELOBSERVER_H telephony-service-0.1+14.04.20140415/indicator/ussdindicator.cpp0000644000015301777760000001121212323307402024741 0ustar pbusernogroup00000000000000/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ namespace C { #include } #include #include #include "ringtone.h" #include "ussdindicator.h" USSDIndicator::USSDIndicator(QObject *parent) : QObject(parent), m_menuRequest(true), m_menuNotification(false), m_notifications("org.freedesktop.Notifications", "/org/freedesktop/Notifications", QDBusConnection::sessionBus()) { connect(USSDManager::instance(), SIGNAL(notificationReceived(const QString &)), SLOT(onNotificationReceived(const QString &))); connect(USSDManager::instance(), SIGNAL(requestReceived(const QString &)), SLOT(onRequestReceived(const QString &))); connect(USSDManager::instance(), SIGNAL(initiateUSSDComplete(const QString &)), SLOT(onInitiateUSSDComplete(const QString &))); connect(USSDManager::instance(), SIGNAL(respondComplete(bool, const QString &)), SLOT(onRespondComplete(bool, const QString &))); connect(USSDManager::instance(), SIGNAL(stateChanged(const QString &)), SLOT(onStateChanged(const QString &))); connect(&m_notifications, SIGNAL(ActionInvoked(uint, const QString &)), this, SLOT(actionInvoked(uint, const QString &))); connect(&m_notifications, SIGNAL(NotificationClosed(uint, uint)), this, SLOT(notificationClosed(uint, uint))); } void USSDIndicator::onNotificationReceived(const QString &message) { showUSSDNotification(message, false); } void USSDIndicator::onRequestReceived(const QString &message) { showUSSDNotification(message, true); } void USSDIndicator::onInitiateUSSDComplete(const QString &ussdResp) { showUSSDNotification(ussdResp, (USSDManager::instance()->state() == "user-response")); } void USSDIndicator::onRespondComplete(bool success, const QString &ussdResp) { if (success) { showUSSDNotification(ussdResp, (USSDManager::instance()->state() == "user-response")); } } void USSDIndicator::onStateChanged(const QString &state) { // TODO: check if we should close notifications when the state is idle } void USSDIndicator::showUSSDNotification(const QString &message, bool replyRequired) { USSDMenu *menu = replyRequired ? &m_menuRequest : &m_menuNotification; QString actionId = "ok_id"; QString actionLabel = C::gettext("Ok"); if (replyRequired) { actionId = "reply_id"; actionLabel = C::gettext("Reply"); } // indicate to the notification-daemon, that we want to use snap-decisions QVariantMap notificationHints; notificationHints["x-canonical-snap-decisions"] = "true"; notificationHints["x-canonical-private-button-tint"] = "true"; QVariantMap menuModelActions; menuModelActions["notifications"] = menu->actionPath(); QVariantMap menuModelPaths; menuModelPaths["busName"] = menu->busName(); menuModelPaths["menuPath"] = menu->menuPath(); menuModelPaths["actions"] = menuModelActions; notificationHints["x-canonical-private-menu-model"] = menuModelPaths; m_notificationId = m_notifications.Notify("telephony-service-indicator", 0, "", "", message, QStringList() << actionId << actionLabel << "cancel_id" << C::gettext("Cancel"), notificationHints, 0); Ringtone::instance()->playIncomingMessageSound(); } void USSDIndicator::actionInvoked(uint id, const QString &actionKey) { if (id != m_notificationId) { return; } m_notificationId = 0; if (actionKey == "reply_id") { USSDManager::instance()->respond(m_menuRequest.response(), USSDManager::instance()->activeAccountId()); } else if (actionKey == "cancel_id") { USSDManager::instance()->cancel(USSDManager::instance()->activeAccountId()); } m_menuRequest.clearResponse(); } void USSDIndicator::notificationClosed(uint id, uint reason) { if (id != m_notificationId) { return; } m_notifications.CloseNotification(m_notificationId); m_notificationId = 0; } telephony-service-0.1+14.04.20140415/indicator/messagingmenu.h0000644000015301777760000000565712323307402024415 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef MESSAGINGMENU_H #define MESSAGINGMENU_H #include #include #include #include class Call { public: Call() : count(0) { } QString number; int count; QString contactAlias; QUrl contactIcon; QString messageId; bool operator==(const Call &other) { return other.number == number; } }; class MessagingMenu : public QObject { Q_OBJECT public: static MessagingMenu *instance(); virtual ~MessagingMenu(); void addMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text); void addFlashMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text); void removeMessage(const QString &messageId); void addCall(const QString &phoneNumber, const QDateTime ×tamp); static void flashMessageActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance); static void messageActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance); static void callsActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance); void showVoicemailEntry(uint count); void hideVoicemailEntry(); Q_SIGNALS: void replyReceived(const QString &phoneNumber, const QString &reply); void messageRead(const QString &phoneNumber, const QString &messageId); private Q_SLOTS: void sendMessageReply(const QString &messageId, const QString &reply); void showMessage(const QString &messageId); void callBack(const QString &messageId); void replyWithMessage(const QString &messageId, const QString &reply); void callVoicemail(const QString &messageId); void saveFlashMessage(const QString &messageId); Call callFromMessageId(const QString &messageId); private: explicit MessagingMenu(QObject *parent = 0); MessagingMenuApp *mCallsApp; MessagingMenuApp *mMessagesApp; QMap mMessages; QList mCalls; QString mVoicemailId; int mVoicemailCount; }; #endif // MESSAGINGMENU_H ././@LongLink0000000000000000000000000000016500000000000011217 Lustar 00000000000000telephony-service-0.1+14.04.20140415/indicator/org.freedesktop.Telepathy.Client.TelephonyServiceIndicator.service.intelephony-service-0.1+14.04.20140415/indicator/org.freedesktop.Telepathy.Client.TelephonyServiceIndi0000644000015301777760000000023712323307402033661 0ustar pbusernogroup00000000000000[D-BUS Service] Name=org.freedesktop.Telepathy.Client.TelephonyServiceIndicator Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-indicator telephony-service-0.1+14.04.20140415/indicator/textchannelobserver.h0000644000015301777760000000403412323307402025624 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef TEXTCHANNELOBSERVER_H #define TEXTCHANNELOBSERVER_H #include #include #include #include #include class NotificationData; class TextChannelObserver : public QObject { Q_OBJECT public: explicit TextChannelObserver(QObject *parent = 0); ~TextChannelObserver(); public Q_SLOTS: void onTextChannelAvailable(Tp::TextChannelPtr textChannel); protected: void showNotificationForMessage(const Tp::ReceivedMessage &message); void showNotificationForFlashMessage(const Tp::ReceivedMessage &message); protected Q_SLOTS: void onTextChannelInvalidated(); void onMessageReceived(const Tp::ReceivedMessage &message); void onPendingMessageRemoved(const Tp::ReceivedMessage &message); void onReplyReceived(const QString &phoneNumber, const QString &reply); void onMessageRead(const QString &phoneNumber, const QString &encodedMessageId); void onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString); void updateNotifications(const QtContacts::QContact &contact); private: QList mChannels; QList mFlashChannels; QMap mNotifications; }; #endif // TEXTCHANNELOBSERVER_H telephony-service-0.1+14.04.20140415/indicator/telephony-service-sms.desktop.in0000644000015301777760000000025112323307402027630 0ustar pbusernogroup00000000000000[Desktop Entry] Type=Application Name=tr("SMS") Exec=telephony-service-indicator Icon=telephony-service-message NoDisplay=true X-Ubuntu-Gettext-Domain=telephony-service telephony-service-0.1+14.04.20140415/indicator/voicemailindicator.cpp0000644000015301777760000000724012323307402025741 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "voicemailindicator.h" #include "telepathyhelper.h" #include "messagingmenu.h" #include #include VoiceMailIndicator::VoiceMailIndicator(QObject *parent) : QObject(parent), mConnection(QDBusConnection::sessionBus()) { if(!checkConnected()) { connect(TelepathyHelper::instance(), SIGNAL(accountReady()), SLOT(onAccountReady())); connect(TelepathyHelper::instance(), SIGNAL(connectionChanged()), SLOT(onAccountReady())); } else { onAccountReady(); } } bool VoiceMailIndicator::checkConnected() { return TelepathyHelper::instance()->connected(); } void VoiceMailIndicator::onAccountReady() { if (!checkConnected()) { return; } // FIXME: handle multiple accounts Tp::ConnectionPtr conn(TelepathyHelper::instance()->accounts()[0]->connection()); if (conn.isNull()) { return; } QString busName = conn->busName(); QString objectPath = conn->objectPath(); mConnection.connect(busName, objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, QLatin1String("VoicemailCountChanged"), this, SLOT(onVoicemailCountChanged(uint))); mConnection.connect(busName, objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, QLatin1String("VoicemailIndicatorChanged"), this, SLOT(onVoicemailIndicatorChanged(bool))); onVoicemailCountChanged(voicemailCount()); } void VoiceMailIndicator::onVoicemailIndicatorChanged(bool active) { if (active) { MessagingMenu::instance()->showVoicemailEntry(voicemailCount()); } else { MessagingMenu::instance()->hideVoicemailEntry(); } } bool VoiceMailIndicator::voicemailIndicatorVisible() { if (!checkConnected()) { return false; } // FIXME: handle multiple accounts Tp::ConnectionPtr conn(TelepathyHelper::instance()->accounts()[0]->connection()); if (conn.isNull()) { return false; } QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusInterface connIface(busName, objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE); QDBusReply reply = connIface.call("VoicemailIndicator"); if (reply.isValid()) { return reply.value(); } return false; } uint VoiceMailIndicator::voicemailCount() { if (!checkConnected()) { return 0; } // FIXME: handle multiple accounts Tp::ConnectionPtr conn(TelepathyHelper::instance()->accounts()[0]->connection()); if (conn.isNull()) { return false; } QString busName = conn->busName(); QString objectPath = conn->objectPath(); QDBusInterface connIface(busName, objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE); QDBusReply reply = connIface.call("VoicemailCount"); if (reply.isValid()) { return reply.value(); } return 0; } void VoiceMailIndicator::onVoicemailCountChanged(uint count) { onVoicemailIndicatorChanged(voicemailIndicatorVisible()); } telephony-service-0.1+14.04.20140415/indicator/metrics.h0000644000015301777760000000264512323307402023213 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Ugo Riboni * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef METRICS_H #define METRICS_H #include #include #include using namespace UserMetricsInput; class Metrics : public QObject { Q_OBJECT public: enum MetricType { SentMessages, ReceivedMessages, IncomingCalls, OutgoingCalls, CallDurations }; static Metrics *instance(); void increment(MetricType metric, double amount = 1.0f); private: explicit Metrics(QObject *parent = 0); QMap mMetrics; UserMetricsInput::MetricManagerPtr mMetricManager; }; #endif // METRICS_H telephony-service-0.1+14.04.20140415/indicator/main.cpp0000644000015301777760000000560612323307402023024 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include "applicationutils.h" #include "callchannelobserver.h" #include "metrics.h" #include "telepathyhelper.h" #include "textchannelobserver.h" #include "voicemailindicator.h" #include "ussdindicator.h" #include #include #include #include #include namespace C { #include } int main(int argc, char **argv) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("telephony-service-indicator"); C::bindtextdomain( "telephony-service", "/usr/share/locale" ); C::textdomain("telephony-service"); notify_init(C::gettext("Telephony Service Indicator")); Tp::registerTypes(); // check if there is already an instance of the indicator running if (ApplicationUtils::checkApplicationRunning(TP_QT_IFACE_CLIENT + ".TelephonyServiceIndicator")) { qDebug() << "Found another instance of the indicator. Quitting."; return 1; } // register the observer TelepathyHelper::instance()->registerChannelObserver("TelephonyServiceIndicator"); // Connect the textObserver and the callObserver to the channel observer in TelepathyHelper CallChannelObserver *callObserver = new CallChannelObserver(); TextChannelObserver *textObserver = new TextChannelObserver(); QObject::connect(TelepathyHelper::instance()->channelObserver(), SIGNAL(textChannelAvailable(Tp::TextChannelPtr)), textObserver, SLOT(onTextChannelAvailable(Tp::TextChannelPtr))); QObject::connect(TelepathyHelper::instance()->channelObserver(), SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), callObserver, SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); // we don't need to call anything on the indicator, it will work by itself VoiceMailIndicator voiceMailIndicator; Q_UNUSED(voiceMailIndicator); USSDIndicator ussdIndicator; Q_UNUSED(ussdIndicator); // instanciate the metrics helper Metrics::instance(); return app.exec(); } telephony-service-0.1+14.04.20140415/indicator/CMakeLists.txt0000644000015301777760000000453112323307402024130 0ustar pbusernogroup00000000000000 set(qt_SRCS callchannelobserver.cpp messagingmenu.cpp metrics.cpp textchannelobserver.cpp ussdindicator.cpp ussdmenu.cpp voicemailindicator.cpp ) set_source_files_properties( "${DATA_DIR}/org.freedesktop.Notifications.xml" PROPERTIES INCLUDE "${CMAKE_SOURCE_DIR}/indicator/DBusTypes.h" ) qt5_add_dbus_interface( qt_SRCS "${DATA_DIR}/org.freedesktop.Notifications.xml" NotificationsInterface ) set(indicator_SRCS main.cpp ${qt_SRCS}) include_directories( ${TP_QT5_INCLUDE_DIRS} ${NOTIFY_INCLUDE_DIRS} ${MESSAGING_MENU_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_CURRENT_BINARY_DIR} ${UserMetrics_INCLUDE_DIRS} ${HISTORY_INCLUDE_DIRS} ) link_directories(${MESSAGING_MENU_LIBRARY_DIRS}) add_executable(telephony-service-indicator ${indicator_SRCS} ${indicator_HDRS}) qt5_use_modules(telephony-service-indicator Contacts Core DBus Gui Multimedia Qml) target_link_libraries(telephony-service-indicator ${TP_QT5_LIBRARIES} ${NOTIFY_LIBRARIES} ${MESSAGING_MENU_LIBRARIES} ${UserMetrics_LIBRARIES} ${HISTORY_LIBRARIES} telephonyservice ) configure_file(org.freedesktop.Telepathy.Client.TelephonyServiceIndicator.service.in org.freedesktop.Telepathy.Client.TelephonyServiceIndicator.service) install(TARGETS telephony-service-indicator RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.TelephonyServiceIndicator.service DESTINATION share/dbus-1/services) install(FILES TelephonyServiceIndicator.client DESTINATION share/telepathy/clients) # Handle i18n in desktop files set(desktop_FILES telephony-service-sms.desktop telephony-service-call.desktop) foreach(DESKTOP_FILE ${desktop_FILES}) file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE}) file(STRINGS ${DESKTOP_FILE}.in DESKTOP_FILE_CONTENTS) foreach(LINE ${DESKTOP_FILE_CONTENTS}) string(REGEX REPLACE "tr\\\(\"(.*)\"\\\)" "\\1" LINE "${LINE}") file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE} "${LINE}\n") endforeach(LINE) endforeach(DESKTOP_FILE) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/telephony-service-sms.desktop ${CMAKE_CURRENT_BINARY_DIR}/telephony-service-call.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) add_subdirectory(icons) telephony-service-0.1+14.04.20140415/indicator/TelephonyServiceIndicator.client0000644000015301777760000000137312323307402027716 0ustar pbusernogroup00000000000000[org.freedesktop.Telepathy.Client] Interfaces=org.freedesktop.Telepathy.Client.Observer; [org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 0] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Call1 org.freedesktop.Telepathy.Channel.TargetHandleType u=1 org.freedesktop.Telepathy.Channel.Type.Call1.InitialAudio b=true [org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 1] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=1 [org.freedesktop.Telepathy.Client.Observer.Capabilities] org.freedesktop.Telepathy.Channel.Type.Call1/audio=true org.freedesktop.Telepathy.Channel.Type.Call1/audio/speex=true telephony-service-0.1+14.04.20140415/indicator/telephony-service-call.desktop.in0000644000015301777760000000025612323307402027746 0ustar pbusernogroup00000000000000[Desktop Entry] Type=Application Name=tr("Phone Calls") Exec=telephony-service-indicator Icon=telephony-service-call NoDisplay=true X-Ubuntu-Gettext-Domain=telephony-service telephony-service-0.1+14.04.20140415/indicator/textchannelobserver.cpp0000644000015301777760000003540412323307402026164 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "applicationutils.h" #include "greetercontacts.h" #include "textchannelobserver.h" #include "messagingmenu.h" #include "metrics.h" #include "chatmanager.h" #include "config.h" #include "contactutils.h" #include "ringtone.h" #include "telepathyhelper.h" #include "phoneutils.h" #include #include #include #include #include #include #include #include #include #include namespace C { #include } QTCONTACTS_USE_NAMESPACE // notification handling class NotificationData { public: QString phoneNumber; QDateTime timestamp; QString text; QString eventId; QString alias; QString message; }; void flash_notification_action(NotifyNotification* notification, char *action, gpointer data) { GError *error = NULL; if (action == QLatin1String("notification_save_action")) { NotificationData *notificationData = (NotificationData*) data; if (notificationData != NULL) { // FIXME: handle multiple accounts History::Thread thread = History::Manager::instance()->threadForParticipants(TelepathyHelper::instance()->accountIds()[0], History::EventTypeText, QStringList() << notificationData->phoneNumber, History::MatchPhoneNumber, true); History::TextEvent textEvent(TelepathyHelper::instance()->accountIds()[0], thread.threadId(), notificationData->eventId, notificationData->phoneNumber, notificationData->timestamp, false, notificationData->text, History::MessageTypeText); History::Events events; events.append(textEvent); History::Manager::instance()->writeEvents(events); } } notify_notification_close(notification, &error); g_object_unref(notification); } void notification_action(NotifyNotification* notification, char *action, gpointer data) { Q_UNUSED(notification); Q_UNUSED(action); NotificationData *notificationData = (NotificationData*) data; if (notificationData != NULL) { // launch the messaging-app to show the message ApplicationUtils::openUrl(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(notificationData->phoneNumber)))); } g_object_unref(notification); } void notification_closed(NotifyNotification *notification, QMap *map) { NotificationData *data = map->take(notification); if (data != NULL) { delete data; } } TextChannelObserver::TextChannelObserver(QObject *parent) : QObject(parent) { connect(MessagingMenu::instance(), SIGNAL(replyReceived(QString,QString)), SLOT(onReplyReceived(QString,QString))); connect(MessagingMenu::instance(), SIGNAL(messageRead(QString,QString)), SLOT(onMessageRead(QString,QString))); if (GreeterContacts::isGreeterMode()) { connect(GreeterContacts::instance(), SIGNAL(contactUpdated(QtContacts::QContact)), this, SLOT(updateNotifications(QtContacts::QContact))); } } TextChannelObserver::~TextChannelObserver() { QMap::const_iterator i = mNotifications.constBegin(); while (i != mNotifications.constEnd()) { NotifyNotification *notification = i.key(); NotificationData *data = i.value(); g_signal_handlers_disconnect_by_data(notification, &mNotifications); delete data; ++i; } mNotifications.clear(); } void TextChannelObserver::showNotificationForFlashMessage(const Tp::ReceivedMessage &message) { Tp::ContactPtr contact = message.sender(); QByteArray token(message.messageToken().toUtf8()); MessagingMenu::instance()->addFlashMessage(contact->id(), token.toHex(), message.received(), message.text()); // show the notification NotifyNotification *notification = notify_notification_new("", message.text().toStdString().c_str(), ""); NotificationData *data = new NotificationData(); data->phoneNumber = contact->id(); data->timestamp = message.received(); data->text = message.text(); data->eventId = message.messageToken().toUtf8(); mNotifications.insert(notification, data); notify_notification_add_action (notification, "notification_ok_action", C::gettext("Ok"), flash_notification_action, NULL, NULL); notify_notification_add_action (notification, "notification_save_action", C::gettext("Save"), flash_notification_action, data, NULL); g_signal_connect(notification, "closed", G_CALLBACK(notification_closed), &mNotifications); notify_notification_set_hint_string(notification, "x-canonical-snap-decisions", "true"); notify_notification_set_hint_string(notification, "x-canonical-private-button-tint", "true"); GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show message notification:" << error->message; g_error_free (error); } Ringtone::instance()->playIncomingMessageSound(); } void TextChannelObserver::showNotificationForMessage(const Tp::ReceivedMessage &message) { Tp::ContactPtr contact = message.sender(); // add the message to the messaging menu (use hex format to avoid invalid characters) QByteArray token(message.messageToken().toUtf8()); MessagingMenu::instance()->addMessage(contact->id(), token.toHex(), message.received(), message.text()); QString title = QString::fromUtf8(C::gettext("SMS from %1")).arg(contact->alias()); QString avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); qDebug() << title << avatar; // show the notification NotifyNotification *notification = notify_notification_new(title.toStdString().c_str(), message.text().toStdString().c_str(), avatar.toStdString().c_str()); // Bundle the data we need for later updating NotificationData *data = new NotificationData(); data->phoneNumber = contact->id(); data->alias = contact->alias(); data->message = message.text(); mNotifications.insert(notification, data); // add the callback action notify_notification_add_action (notification, "notification_action", C::gettext("View message"), notification_action, data, NULL /* will be deleted when closed */); notify_notification_set_hint_string(notification, "x-canonical-switch-to-application", "true"); g_signal_connect(notification, "closed", G_CALLBACK(notification_closed), &mNotifications); if (GreeterContacts::isGreeterMode()) { // we're in the greeter's session GreeterContacts::instance()->setContactFilter(QContactPhoneNumber::match(contact->id())); } else { // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(contact->id())); QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request]() { // only process the results after the finished state is reached if (request->state() != QContactAbstractRequest::FinishedState || request->contacts().size() == 0) { return; } QContact contact = request->contacts().at(0); updateNotifications(contact); // Notify greeter via AccountsService about this contact so it // can show the details if our session is locked. GreeterContacts::emitContact(contact); }); request->setManager(ContactUtils::sharedManager()); request->start(); } GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show message notification:" << error->message; g_error_free (error); } Ringtone::instance()->playIncomingMessageSound(); } void TextChannelObserver::updateNotifications(const QContact &contact) { QMap::const_iterator i = mNotifications.constBegin(); while (i != mNotifications.constEnd()) { NotifyNotification *notification = i.key(); NotificationData *data = i.value(); Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) { if (PhoneUtils::comparePhoneNumbers(data->phoneNumber, phoneNumber.number())) { QString displayLabel = ContactUtils::formatContactName(contact); QString title = QString::fromUtf8(C::gettext("SMS from %1")).arg(displayLabel.isEmpty() ? data->alias : displayLabel); QString avatar = contact.detail().imageUrl().toEncoded(); if (avatar.isEmpty()) { avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); } notify_notification_update(notification, title.toStdString().c_str(), data->message.toStdString().c_str(), avatar.toStdString().c_str()); GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show message notification:" << error->message; g_error_free (error); } } } ++i; } } void TextChannelObserver::onTextChannelAvailable(Tp::TextChannelPtr textChannel) { connect(textChannel.data(), SIGNAL(invalidated(Tp::DBusProxy*,const QString&, const QString&)), SLOT(onTextChannelInvalidated())); connect(textChannel.data(), SIGNAL(messageReceived(const Tp::ReceivedMessage&)), SLOT(onMessageReceived(const Tp::ReceivedMessage&))); connect(textChannel.data(), SIGNAL(pendingMessageRemoved(const Tp::ReceivedMessage&)), SLOT(onPendingMessageRemoved(const Tp::ReceivedMessage&))); connect(textChannel.data(), SIGNAL(messageSent(Tp::Message,Tp::MessageSendingFlags,QString)), SLOT(onMessageSent(Tp::Message,Tp::MessageSendingFlags,QString))); if (textChannel->immutableProperties().contains(TP_QT_IFACE_CHANNEL_INTERFACE_SMS + QLatin1String(".Flash")) && textChannel->immutableProperties()[TP_QT_IFACE_CHANNEL_INTERFACE_SMS + QLatin1String(".Flash")].toBool()) { // class 0 sms mFlashChannels.append(textChannel); Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { showNotificationForFlashMessage(message); } return; } else { mChannels.append(textChannel); } // notify all the messages from the channel Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { onMessageReceived(message); } } void TextChannelObserver::onTextChannelInvalidated() { Tp::TextChannelPtr textChannel(qobject_cast(sender())); mChannels.removeAll(textChannel); mFlashChannels.removeAll(textChannel); } void TextChannelObserver::onMessageReceived(const Tp::ReceivedMessage &message) { Tp::TextChannelPtr textChannel(qobject_cast(sender())); // do not place notification items for scrollback messages if (mFlashChannels.contains(textChannel) && !message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { showNotificationForFlashMessage(message); return; } if (!message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { showNotificationForMessage(message); Metrics::instance()->increment(Metrics::ReceivedMessages); } } void TextChannelObserver::onPendingMessageRemoved(const Tp::ReceivedMessage &message) { MessagingMenu::instance()->removeMessage(message.messageToken()); } void TextChannelObserver::onReplyReceived(const QString &phoneNumber, const QString &reply) { ChatManager::instance()->sendMessage(QStringList() << phoneNumber, reply); } void TextChannelObserver::onMessageRead(const QString &phoneNumber, const QString &encodedMessageId) { QString messageId(QByteArray::fromHex(encodedMessageId.toUtf8())); ChatManager::instance()->acknowledgeMessage(phoneNumber, messageId); } void TextChannelObserver::onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString) { Metrics::instance()->increment(Metrics::SentMessages); } telephony-service-0.1+14.04.20140415/po/0000755000015301777760000000000012323310021020016 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/po/lv.po0000644000015301777760000001577712323307402021031 0ustar pbusernogroup00000000000000# Latvian translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-25 09:49+0000\n" "Last-Translator: Klavs Anson \n" "Language-Team: Latvian \n" "Language: lv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 neatbildēts zvans" msgstr[1] "%1 neatbildētu zvanu" msgstr[2] "%1 neatbildētu zvanu" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 balss pasta ziņa" msgstr[1] "%1 balss pasta ziņas" msgstr[2] "%1 balss pasta ziņas" #: approver/approver.cpp:241 msgid "Accept" msgstr "Piekrist" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Zvanītais numurs nav pieejams" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Zvana no %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Zvanīšana no privātā numura" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Zvanīšana no nezināma numura" #: approver/approver.cpp:247 msgid "Decline" msgstr "Noraidīt" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Es nokavēju tavu zvanu - vai vari man piezvanīt tagad?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Es nokavēšu 20 minūtes." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Es esmu aizņemts. Es tev vēlak piezvanīšu." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Es esmu aizkavējies. Es tūlīt būšu." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Tālruņa zvani" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS no %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Piedod es vēl esmu aizņemts. Es tev piezvanīšu vēlāk." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Nezināms zvanītājs" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Balss pasta ziņas" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Pārvalda ienākošās ziņas, zvanus un indikātorus" #~ msgid "Phone App Approver" #~ msgstr "Telefona Aplikācijas Apstiprinātājs" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 stunda zvans" #~ msgstr[1] "%1 stundu zvans" #~ msgstr[2] "%1 stundu zvans" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minutes zvans" #~ msgstr[1] "%1 minušu zvans" #~ msgstr[2] "%1 minušu zvans" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 sekundes zvans" #~ msgstr[1] "%1 sekunžu zvans" #~ msgstr[2] "%1 sekunžu zvans" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Pievienot" #~ msgid "Add a phone number" #~ msgstr "Pievienot telefona numuru" #~ msgid "Add a postal address" #~ msgstr "Pievienot pasta indekssu" #~ msgid "Add an email address" #~ msgstr "Pievienot epasta adresi" #~ msgid "Add an online account" #~ msgstr "Pievienot tiešsaistes kontu" #~ msgid "Address" #~ msgstr "Adrese" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Vai tiešām vēlaties dzēst šo kontaktu?" #~ msgid "Call" #~ msgstr "Zvanīt" #~ msgid "Calls" #~ msgstr "Zvani" #~ msgid "Cancel" #~ msgstr "Atcelt" #~ msgid "Communication" #~ msgstr "Saziņa" #~ msgid "Compose" #~ msgstr "Kompozēt" #~ msgid "Contact Details" #~ msgstr "Kontakta informācija" #~ msgid "Contacts" #~ msgstr "Kontakti" #~ msgid "Conversations" #~ msgstr "Sarunas" #~ msgid "Country" #~ msgstr "Valsts" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Dzēst" #~ msgid "Delete Contact" #~ msgstr "Dzēst Kontaktu" #~ msgid "Dialing" #~ msgstr "Zvanīsana" #~ msgid "Duration %1" #~ msgstr "Ilgums %1" #~ msgid "Edit" #~ msgstr "Rediģēt" #~ msgid "Email" #~ msgstr "E-pasts" #~ msgid "Enter a number" #~ msgstr "Ievadīt numuru" #~ msgid "First" #~ msgstr "Pirmais" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Mājas" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Pēdējais" #~ msgid "Locality" #~ msgstr "Apgabals" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Ziņojumi" #~ msgid "Middle" #~ msgstr "Vidū" #~ msgid "Mobile" #~ msgstr "Mobilais" #~ msgid "New Contact" #~ msgstr "Jauns Kontakts" #~ msgid "New Message" #~ msgstr "Jauna Ziņa" #~ msgid "On Call" #~ msgstr "Zvanā" #~ msgid "Other" #~ msgstr "Citi" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Tālrunis" #~ msgid "Phone App" #~ msgstr "Telefona Aplikācija" #~ msgid "Phone application" #~ msgstr "Telefona Aplikācija" #~ msgid "Postal Code" #~ msgstr "Pasta indekss" #~ msgid "Prefix" #~ msgstr "Priedēklis" #~ msgid "Private number" #~ msgstr "Privātais numurs" #~ msgid "Region" #~ msgstr "Reģions" #~ msgid "Reply via SMS" #~ msgstr "Atbildēt ar SMS" #~ msgid "Save" #~ msgstr "Saglabāt" #~ msgid "Send" #~ msgstr "Sūtīt" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Iela" #~ msgid "Suffix" #~ msgstr "Priedēklis" #~ msgid "Swap Calls" #~ msgstr "Apmainīt Zvanus" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Uz:" #~ msgid "Today" #~ msgstr "Šodien" #~ msgid "Unknown Contact" #~ msgstr "Nezināms Kontakts" #~ msgid "Unknown number" #~ msgstr "Nezināms numurs" #~ msgid "Voicemail" #~ msgstr "Balss pasts" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Darbs" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Vakar" #~ msgid "missed call" #~ msgstr "nokavētie zvani" telephony-service-0.1+14.04.20140415/po/ko.po0000644000015301777760000000553112323307402021004 0ustar pbusernogroup00000000000000# Korean translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-18 16:47+0000\n" "Last-Translator: Jinkyu Yi \n" "Language-Team: Korean \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" #~ msgid "#" #~ msgstr "#" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "Address" #~ msgstr "주소" telephony-service-0.1+14.04.20140415/po/zh_CN.po0000644000015301777760000001504412323307402021374 0ustar pbusernogroup00000000000000# Chinese (Simplified) translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-14 16:29+0000\n" "Last-Translator: Anthony Wong \n" "Language-Team: Chinese (Simplified) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 个未接来电" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 个语音信息" #: approver/approver.cpp:241 msgid "Accept" msgstr "接听" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "没有对方来电号码" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "%1 的来电" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "私人号码来电" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "陌生号码来电" #: approver/approver.cpp:247 msgid "Decline" msgstr "拒绝" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "我错过了您的电话,您可以现在打给我吗?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "我将会迟到20分钟。" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "现在正忙,待会儿回您电话。" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "快迟到了,我这就动身。" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "手机通话" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "信息" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "来自 %1 的信息" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "抱歉,我还在忙,待会儿给您回电话。" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "未知来电者" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "语音信箱信息" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "处理收到的信息,拨号和指示器" #~ msgid "Phone App Approver" #~ msgstr "拨号应用审批程序" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 小时通话" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 分钟通话" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 秒通话" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "添加" #~ msgid "Add a phone number" #~ msgstr "添加电话号码" #~ msgid "Add a postal address" #~ msgstr "添加通讯地址" #~ msgid "Add an email address" #~ msgstr "添加 email 地址" #~ msgid "Add an online account" #~ msgstr "添加在线账户" #~ msgid "Address" #~ msgstr "地址" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "您确定要删除该联系人吗?" #~ msgid "Call" #~ msgstr "拨号" #~ msgid "Calls" #~ msgstr "通话" #~ msgid "Cancel" #~ msgstr "取消" #~ msgid "Communication" #~ msgstr "通讯" #~ msgid "Compose" #~ msgstr "编写" #~ msgid "Contact Details" #~ msgstr "联系人详情" #~ msgid "Contacts" #~ msgstr "联系人" #~ msgid "Conversations" #~ msgstr "会话" #~ msgid "Country" #~ msgstr "国家/地区" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "删除" #~ msgid "Delete Contact" #~ msgstr "删除联系人" #~ msgid "Dialing" #~ msgstr "正在拨号" #~ msgid "Duration %1" #~ msgstr "通话时长 %1" #~ msgid "Edit" #~ msgstr "编辑" #~ msgid "Email" #~ msgstr "电邮地址" #~ msgid "Enter a number" #~ msgstr "输入一个号码" #~ msgid "First" #~ msgstr "名字" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "主页" #~ msgid "IM" #~ msgstr "即时通讯" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "姓氏" #~ msgid "Locality" #~ msgstr "城市" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "信息" #~ msgid "Middle" #~ msgstr "中间名" #~ msgid "Mobile" #~ msgstr "手机" #~ msgid "New Contact" #~ msgstr "新增联系人" #~ msgid "New Message" #~ msgstr "新消息" #~ msgid "On Call" #~ msgstr "正在通话" #~ msgid "Other" #~ msgstr "其它" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "电话" #~ msgid "Phone App" #~ msgstr "拨号应用" #~ msgid "Phone application" #~ msgstr "拨号应用程序" #~ msgid "Postal Code" #~ msgstr "邮政编码" #~ msgid "Prefix" #~ msgstr "名称前缀" #~ msgid "Private number" #~ msgstr "私人号码" #~ msgid "Region" #~ msgstr "地区" #~ msgid "Reply via SMS" #~ msgstr "以信息回复" #~ msgid "Save" #~ msgstr "保存" #~ msgid "Send" #~ msgstr "发送" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "街道" #~ msgid "Suffix" #~ msgstr "名称后缀" #~ msgid "Swap Calls" #~ msgstr "切换通话" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "至:" #~ msgid "Today" #~ msgstr "今天" #~ msgid "Unknown Contact" #~ msgstr "未知联系人" #~ msgid "Unknown number" #~ msgstr "陌生号码" #~ msgid "Voicemail" #~ msgstr "语音信箱" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "公司" #~ msgid "Yahoo" #~ msgstr "雅虎" #~ msgid "Yesterday" #~ msgstr "昨天" #~ msgid "missed call" #~ msgstr "未接来电" telephony-service-0.1+14.04.20140415/po/it.po0000644000015301777760000001506712323307402021014 0ustar pbusernogroup00000000000000# Italian translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-13 10:40+0000\n" "Last-Translator: Claudio Arseni \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 chiamata persa" msgstr[1] "%1 chiamate perse" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 messaggio in segreteria" msgstr[1] "%1 messaggi in segreteria" #: approver/approver.cpp:241 msgid "Accept" msgstr "Accetta" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Numero chiamante non disponibile" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Chiamata da %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Chiamata da numero privato" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Chiamata da numero sconosciuto" #: approver/approver.cpp:247 msgid "Decline" msgstr "Rifiuta" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Ho perso la tua chiamata. Puoi richiamarmi ora?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Sarò in ritardo di 20 minuti." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Sono occupato in questo momento. Ti richiamerò più tardi." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Sono in ritardo. Sto per arrivare." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Chiamate telefoniche" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS da %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Mi dispiace, sono ancora occupato. Ti richiamerò più tardi." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Chiamante sconosciuto" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Messaggi in segreteria" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Gestisce indicatori e chiamate e messaggi in arrivo" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 ora" #~ msgstr[1] "%1 ore" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minuto" #~ msgstr[1] "%1 minuti" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 secondo" #~ msgstr[1] "%1 secondi" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Aggiungi" #~ msgid "Add a phone number" #~ msgstr "Aggiungi un numero di telefono" #~ msgid "Add a postal address" #~ msgstr "Aggiungi un indirizzo postale" #~ msgid "Add an email address" #~ msgstr "Aggiungi un indirizzo email" #~ msgid "Add an online account" #~ msgstr "Aggiungi un account online" #~ msgid "Address" #~ msgstr "Indirizzo" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Eliminare veramente questo contatto?" #~ msgid "Call" #~ msgstr "Chiama" #~ msgid "Calls" #~ msgstr "Chiamate" #~ msgid "Cancel" #~ msgstr "Annulla" #~ msgid "Communication" #~ msgstr "Comunicazione" #~ msgid "Compose" #~ msgstr "Scrivi" #~ msgid "Contact Details" #~ msgstr "Dettagli contatto" #~ msgid "Contacts" #~ msgstr "Contatti" #~ msgid "Conversations" #~ msgstr "Conversazioni" #~ msgid "Country" #~ msgstr "Paese" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Elimina" #~ msgid "Delete Contact" #~ msgstr "Elimina contatto" #~ msgid "Dialing" #~ msgstr "Composizione" #~ msgid "Duration %1" #~ msgstr "Durata %1" #~ msgid "Edit" #~ msgstr "Modifica" #~ msgid "Email" #~ msgstr "Email" #~ msgid "Enter a number" #~ msgstr "Inserire un numero" #~ msgid "First" #~ msgstr "Nome" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Casa" #~ msgid "IM" #~ msgstr "Messaggistica istantanea" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Cognome" #~ msgid "Locality" #~ msgstr "Località" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Messaggi" #~ msgid "Middle" #~ msgstr "Secondo nome" #~ msgid "Mobile" #~ msgstr "Cellulare" #~ msgid "New Contact" #~ msgstr "Nuovo contatto" #~ msgid "New Message" #~ msgstr "Nuovo messaggio" #~ msgid "Other" #~ msgstr "Altro" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Telefono" #~ msgid "Postal Code" #~ msgstr "CAP" #~ msgid "Prefix" #~ msgstr "Titolo" #~ msgid "Private number" #~ msgstr "Numero privato" #~ msgid "Region" #~ msgstr "Regione" #~ msgid "Reply via SMS" #~ msgstr "Rispondi via SMS" #~ msgid "Save" #~ msgstr "Salva" #~ msgid "Send" #~ msgstr "Invia" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Via" #~ msgid "Suffix" #~ msgstr "Suffisso" #~ msgid "Swap Calls" #~ msgstr "Scambia chiamate" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "A:" #~ msgid "Today" #~ msgstr "Oggi" #~ msgid "Unknown Contact" #~ msgstr "Contatto sconosciuto" #~ msgid "Unknown number" #~ msgstr "Numero sconosciuto" #~ msgid "Voicemail" #~ msgstr "Segreteria" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Lavoro" #~ msgid "Yahoo" #~ msgstr "Yahoo!" #~ msgid "Yesterday" #~ msgstr "Ieri" #~ msgid "missed call" #~ msgstr "chiamata persa" telephony-service-0.1+14.04.20140415/po/es.po0000644000015301777760000001544012323307402021002 0ustar pbusernogroup00000000000000# Spanish translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-11 10:47+0000\n" "Last-Translator: pros90 \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-12 06:35+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 llamada perdida" msgstr[1] "%1 llamadas perdidas" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mensaje de voz" msgstr[1] "%1 mensaje de voz" #: approver/approver.cpp:241 msgid "Accept" msgstr "Aceptar" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "El número del que llama no está disponible" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "Rechazar" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "No pude responderte, ¿podrías llamarme ahora?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Demoraré 20 minutos." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Estoy ocupado/a en este momento. Te llamaré luego." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Se me hizo tarde, voy en camino." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Llamadas telefónicas" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS de %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Lo siento, sigo ocupado/a. Te llamaré luego." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Llamante desconocido" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Mensajes de voz" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "" #~ "Gestiona las llamadas y mensajes entrantes, así como los indicadores" #~ msgid "Phone App Approver" #~ msgstr "Autorizador de la aplicación Teléfono" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "Llamada de %1 hora" #~ msgstr[1] "Llamada de %1 horas" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "Llamada de %1 minuto" #~ msgstr[1] "Llamada de %1 minutos" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "Llamada de %1 segundo" #~ msgstr[1] "Llamada de %1 segundos" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Añadir" #~ msgid "Add a phone number" #~ msgstr "Añadir un número telefónico" #~ msgid "Add a postal address" #~ msgstr "Añadir una dirección postal" #~ msgid "Add an email address" #~ msgstr "Añadir un correo electrónico" #~ msgid "Add an online account" #~ msgstr "Añadir una cuenta en línea" #~ msgid "Address" #~ msgstr "Dirección" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "¿Está seguro de que quiere eliminar este contacto?" #~ msgid "Call" #~ msgstr "Llamar" #~ msgid "Calls" #~ msgstr "Llamadas" #~ msgid "Cancel" #~ msgstr "Cancelar" #~ msgid "Communication" #~ msgstr "Comunicación" #~ msgid "Compose" #~ msgstr "Redactar" #~ msgid "Contact Details" #~ msgstr "Detalles del contacto" #~ msgid "Contacts" #~ msgstr "Contactos" #~ msgid "Conversations" #~ msgstr "Conversaciones" #~ msgid "Country" #~ msgstr "País" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Eliminar" #~ msgid "Delete Contact" #~ msgstr "Eliminar contacto" #~ msgid "Dialing" #~ msgstr "Marcando" #~ msgid "Duration %1" #~ msgstr "Duración: %1" #~ msgid "Edit" #~ msgstr "Editar" #~ msgid "Email" #~ msgstr "Correo electrónico" #~ msgid "Enter a number" #~ msgstr "Introduzca un número" #~ msgid "First" #~ msgstr "Nombre" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Inicio" #~ msgid "IM" #~ msgstr "MI" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Apellidos" #~ msgid "Locality" #~ msgstr "Localidad" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Mensajes" #~ msgid "Middle" #~ msgstr "2.º nombre" #~ msgid "Mobile" #~ msgstr "Móvil" #~ msgid "New Contact" #~ msgstr "Contacto nuevo" #~ msgid "New Message" #~ msgstr "Mensaje nuevo" #~ msgid "Other" #~ msgstr "Otros" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Teléfono" #~ msgid "Phone App" #~ msgstr "Aplicación Teléfono" #~ msgid "Phone application" #~ msgstr "Aplicación Teléfono" #~ msgid "Postal Code" #~ msgstr "Código postal" #~ msgid "Prefix" #~ msgstr "Prefijo" #~ msgid "Private number" #~ msgstr "Número privado" #~ msgid "Region" #~ msgstr "Región" #~ msgid "Reply via SMS" #~ msgstr "Responder con SMS" #~ msgid "Save" #~ msgstr "Guardar" #~ msgid "Send" #~ msgstr "Enviar" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Calle" #~ msgid "Suffix" #~ msgstr "Sufijo" #~ msgid "Swap Calls" #~ msgstr "Intercambiar llamadas" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Para:" #~ msgid "Today" #~ msgstr "Hoy" #~ msgid "Unknown Contact" #~ msgstr "Contacto desconocido" #~ msgid "Unknown number" #~ msgstr "Número desconocido" #~ msgid "Voicemail" #~ msgstr "Correo de voz" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Trabajo" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Ayer" #~ msgid "missed call" #~ msgstr "llamada perdida" telephony-service-0.1+14.04.20140415/po/uk.po0000644000015301777760000002052512323307402021012 0ustar pbusernogroup00000000000000# Ukrainian translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-13 10:08+0000\n" "Last-Translator: Yuri Chornoivan \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 пропущений дзвінок" msgstr[1] "%1 пропущені дзвінки" msgstr[2] "%1 пропущених дзвінків" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 голосове повідомлення" msgstr[1] "%1 голосових повідомлення" msgstr[2] "%1 голосових повідомлень" #: approver/approver.cpp:241 msgid "Accept" msgstr "Прийняти" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Номер вхідного дзвінка недоступний" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Дзвінок від %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Дзвінок з приватного номера" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Дзвінок з невідомого номера" #: approver/approver.cpp:247 msgid "Decline" msgstr "Відхилити" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Мною пропущено Ваш дзвінок. Можете передзвонити?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Буду за 20 хвилин." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Зараз не можу поговорити. Передзвоню пізніше." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Запізнююся. У дорозі." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Телефонні дзвінки" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "СМС" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "СМС від %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Вибачте, не можу звільнитися. Передзвоню пізніше." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Невідома особа" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Повідомлення голосової пошти" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Обробляє вхідні повідомлення, дзвінки та працює з індикаторами" #~ msgid "Phone App Approver" #~ msgstr "Підтверджувач дзвінків" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1-годинний дзвінок" #~ msgstr[1] "%1-годинний дзвінок" #~ msgstr[2] "%1-годинний дзвінок" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1-хвилинний дзвінок" #~ msgstr[1] "%1-хвилинний дзвінок" #~ msgstr[2] "%1-хвилинний дзвінок" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1-секундний дзвінок" #~ msgstr[1] "%1-секундний дзвінок" #~ msgstr[2] "%1-секундний дзвінок" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "АБВГ" #~ msgid "Add" #~ msgstr "Додати" #~ msgid "Add a phone number" #~ msgstr "Додати телефонний номер" #~ msgid "Add a postal address" #~ msgstr "Додати поштову адресу" #~ msgid "Add an email address" #~ msgstr "Додати адресу електронної пошти" #~ msgid "Add an online account" #~ msgstr "Додати обліковий запису у мережі" #~ msgid "Address" #~ msgstr "Адреса" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Вилучити ці записи контактів?" #~ msgid "Call" #~ msgstr "Дзвінок" #~ msgid "Calls" #~ msgstr "Дзвінки" #~ msgid "Cancel" #~ msgstr "Скасувати" #~ msgid "Communication" #~ msgstr "Зв’язок" #~ msgid "Compose" #~ msgstr "Написати" #~ msgid "Contact Details" #~ msgstr "Подробиці щодо запису контакту" #~ msgid "Contacts" #~ msgstr "Контакти" #~ msgid "Conversations" #~ msgstr "Спілкування" #~ msgid "Country" #~ msgstr "Країна" #~ msgid "DEF" #~ msgstr "ДЕЄЖЗ" #~ msgid "Delete" #~ msgstr "Вилучити" #~ msgid "Delete Contact" #~ msgstr "Вилучити контакт" #~ msgid "Dialing" #~ msgstr "Набирання" #~ msgid "Duration %1" #~ msgstr "Тривалість: %1" #~ msgid "Edit" #~ msgstr "Змінити" #~ msgid "Email" #~ msgstr "Ел. пошта" #~ msgid "Enter a number" #~ msgstr "Введіть номер" #~ msgid "First" #~ msgstr "Перший" #~ msgid "GHI" #~ msgstr "ІЇИЙКЛ" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Домівка" #~ msgid "IM" #~ msgstr "МП" #~ msgid "JKL" #~ msgstr "МНОП" #~ msgid "Last" #~ msgstr "Останній" #~ msgid "Locality" #~ msgstr "Район" #~ msgid "MNO" #~ msgstr "РСТУ" #~ msgid "Messages" #~ msgstr "Повідомлення" #~ msgid "Middle" #~ msgstr "Середина" #~ msgid "Mobile" #~ msgstr "Мобільний" #~ msgid "New Contact" #~ msgstr "Новий контакт" #~ msgid "New Message" #~ msgstr "Нове повідомлення" #~ msgid "On Call" #~ msgstr "Дзвінок" #~ msgid "Other" #~ msgstr "Інше" #~ msgid "PQRS" #~ msgstr "ФХЦЧ" #~ msgid "Phone" #~ msgstr "Телефон" #~ msgid "Phone App" #~ msgstr "Програма-телефон" #~ msgid "Phone application" #~ msgstr "Програма-телефон" #~ msgid "Postal Code" #~ msgstr "Поштовий індекс" #~ msgid "Prefix" #~ msgstr "Префікс" #~ msgid "Private number" #~ msgstr "Приватний номер" #~ msgid "Region" #~ msgstr "Область/Регіон" #~ msgid "Reply via SMS" #~ msgstr "Відповісти СМС" #~ msgid "Save" #~ msgstr "Зберегти" #~ msgid "Send" #~ msgstr "Надіслати" #~ msgid "Skype" #~ msgstr "Скайп" #~ msgid "Street" #~ msgstr "Вулиця" #~ msgid "Suffix" #~ msgstr "Суфікс" #~ msgid "Swap Calls" #~ msgstr "Перемкнути дзвінки" #~ msgid "TUV" #~ msgstr "ШЩ" #~ msgid "To:" #~ msgstr "Кому:" #~ msgid "Today" #~ msgstr "Сьогодні" #~ msgid "Unknown Contact" #~ msgstr "Невідомий контакт" #~ msgid "Unknown number" #~ msgstr "Невідомий номер" #~ msgid "Voicemail" #~ msgstr "Голосова пошта" #~ msgid "WXYZ" #~ msgstr "ЬЮЯ" #~ msgid "Work" #~ msgstr "Робочий" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Вчора" #~ msgid "missed call" #~ msgstr "пропущений дзвінок" telephony-service-0.1+14.04.20140415/po/sv.po0000644000015301777760000000625212323307402021024 0ustar pbusernogroup00000000000000# Swedish translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-02 13:46+0000\n" "Last-Translator: Joachim Johansson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Address" #~ msgstr "Adress" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "New Contact" #~ msgstr "Ny kontakt" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Save" #~ msgstr "Spara" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Yahoo" #~ msgstr "Yahoo" telephony-service-0.1+14.04.20140415/po/zh_HK.po0000644000015301777760000000561612323307402021402 0ustar pbusernogroup00000000000000# Chinese (Hong Kong) translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-04 17:09+0000\n" "Last-Translator: Anthony Wong \n" "Language-Team: Chinese (Hong Kong) \n" "Language: zh_HK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "接聽" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" #~ msgid "#" #~ msgstr "#" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" telephony-service-0.1+14.04.20140415/po/tr.po0000644000015301777760000001530712323307402021022 0ustar pbusernogroup00000000000000# Turkish translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-13 15:38+0000\n" "Last-Translator: Volkan Gezer \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 cevapsız arama" msgstr[1] "%1 cevapsız arama" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 sesli mesaj" msgstr[1] "%1 sesli mesaj" #: approver/approver.cpp:241 msgid "Accept" msgstr "Kabul Et" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Arayan numarası kullanılamıyor" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "%1 kişisinden arama" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Özel numaradan arıyor" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Bilinmeyen numaradan arıyor" #: approver/approver.cpp:247 msgid "Decline" msgstr "Reddet" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Telefona yetişemedim - beni şimdi arar mısın?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "20 dakika geç kalacağım." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Şu anda meşgulüm. Seni sonra arayacağım." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Geç kalıyorum. Yoldayım." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefon Çağrıları" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "%1 kişisinden SMS" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Üzgünüm, hala meşgulüm. Seni sonra arayacağım." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Bilinmeyen arayan" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Telesekreter mesajları" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Gelen mesajları, çağrı ve bildirimleri ele alır" #~ msgid "Phone App Approver" #~ msgstr "Telefon Uygulaması Onaylayıcı" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 saat arama" #~ msgstr[1] "%1 saat arama" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 dakika arama" #~ msgstr[1] "%1 dakika arama" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 saniye arama" #~ msgstr[1] "%1 saniye arama" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Ekle" #~ msgid "Add a phone number" #~ msgstr "Bir telefon numarası ekle" #~ msgid "Add a postal address" #~ msgstr "Bir posta adresi ekle" #~ msgid "Add an email address" #~ msgstr "Bir e-posta adresi ekle" #~ msgid "Add an online account" #~ msgstr "Bir çevrimiçi hesap ekle" #~ msgid "Address" #~ msgstr "Adres" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Bu kişiyi silmek istediğinizden emin misiniz?" #~ msgid "Call" #~ msgstr "Ara" #~ msgid "Calls" #~ msgstr "Çağrılar" #~ msgid "Cancel" #~ msgstr "İptal" #~ msgid "Communication" #~ msgstr "İletişim" #~ msgid "Compose" #~ msgstr "Yaz" #~ msgid "Contact Details" #~ msgstr "Kişi Ayrıntıları" #~ msgid "Contacts" #~ msgstr "Kişiler" #~ msgid "Conversations" #~ msgstr "Sohbetler" #~ msgid "Country" #~ msgstr "Ülke" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Sil" #~ msgid "Delete Contact" #~ msgstr "Kişiyi Sil" #~ msgid "Dialing" #~ msgstr "Arıyor" #~ msgid "Duration %1" #~ msgstr "Süre %1" #~ msgid "Edit" #~ msgstr "Düzenle" #~ msgid "Email" #~ msgstr "E-posta" #~ msgid "Enter a number" #~ msgstr "Bir numara girin" #~ msgid "First" #~ msgstr "İlk" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Ev" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Son" #~ msgid "Locality" #~ msgstr "Konum" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Mesajlar" #~ msgid "Middle" #~ msgstr "Orta" #~ msgid "Mobile" #~ msgstr "Cep Telefonu" #~ msgid "New Contact" #~ msgstr "Yeni Kişi" #~ msgid "New Message" #~ msgstr "Yeni Mesaj" #~ msgid "On Call" #~ msgstr "Aramada" #~ msgid "Other" #~ msgstr "Diğer" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Telefon" #~ msgid "Phone App" #~ msgstr "Telefon Uygulaması" #~ msgid "Phone application" #~ msgstr "Telefon uygulaması" #~ msgid "Postal Code" #~ msgstr "Posta Kodu" #~ msgid "Prefix" #~ msgstr "Ön ek" #~ msgid "Private number" #~ msgstr "Özel numara" #~ msgid "Region" #~ msgstr "Bölge" #~ msgid "Reply via SMS" #~ msgstr "SMS ile yanıtla" #~ msgid "Save" #~ msgstr "Kaydet" #~ msgid "Send" #~ msgstr "Gönder" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Sokak" #~ msgid "Suffix" #~ msgstr "Son ek" #~ msgid "Swap Calls" #~ msgstr "Çağrıları Değiştir" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Kime:" #~ msgid "Today" #~ msgstr "Bugün" #~ msgid "Unknown Contact" #~ msgstr "Bilinmeyen Kişi" #~ msgid "Unknown number" #~ msgstr "Bilinmeyen numara" #~ msgid "Voicemail" #~ msgstr "Telesekreter" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "İş" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Dün" #~ msgid "missed call" #~ msgstr "cevapsız çağrı" telephony-service-0.1+14.04.20140415/po/pl.po0000644000015301777760000001610612323307402021006 0ustar pbusernogroup00000000000000# Polish translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-22 16:46+0000\n" "Last-Translator: GTriderXC \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 nieodebrane połączenie" msgstr[1] "%1 nieodebrane połączenia" msgstr[2] "%1 nieodebranych połączeń" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 wiadomość głosowa" msgstr[1] "%1 wiadomości głosowe" msgstr[2] "%1 wiadomości głosowych" #: approver/approver.cpp:241 msgid "Accept" msgstr "Akceptuj" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Numer rozmówcy jest niedostępny" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Połączenie z %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Połączenie z numerem prywatnym" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Połączenie z nieznanego numeru" #: approver/approver.cpp:247 msgid "Decline" msgstr "Odrzuć" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Nie udało mi się odebrać połączenia. Możemy porozmawiać teraz?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Spóźnię się 20 minut." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Niestety nie mogę teraz odebrać. Oddzwonię później." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Spóźnię się. Jestem w drodze." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Rozmowy telefoniczne" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS od %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Przykro mi, nadal nie mogę rozmawiać. Oddzwonię później." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Nieznany" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Wiadomości głosowe" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "" #~ "Zarządza przychodzącymi połączeniami, wiadomościami i powiadomieniami" #~ msgid "Phone App Approver" #~ msgstr "Zarządzanie aplikacją telefonu" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 godzina rozmowy" #~ msgstr[1] "%1 godziny rozmowy" #~ msgstr[2] "%1 godzin rozmowy" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minuta rozmowy" #~ msgstr[1] "%1 minuty rozmowy" #~ msgstr[2] "%1 minut rozmowy" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 sekunda rozmowy" #~ msgstr[1] "%1 sekundy rozmowy" #~ msgstr[2] "%1 sekund rozmowy" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Dodaj" #~ msgid "Add a phone number" #~ msgstr "Dodaj numer telefonu" #~ msgid "Add a postal address" #~ msgstr "Dodaj adres pocztowy" #~ msgid "Add an email address" #~ msgstr "Dodaj adres e-mail" #~ msgid "Add an online account" #~ msgstr "Dodaj konto online" #~ msgid "Address" #~ msgstr "Adres" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Na pewno usunąć ten kontakt?" #~ msgid "Call" #~ msgstr "Połączenie" #~ msgid "Calls" #~ msgstr "Rozmowy" #~ msgid "Cancel" #~ msgstr "Anuluj" #~ msgid "Communication" #~ msgstr "Komunikacja" #~ msgid "Compose" #~ msgstr "Utwórz" #~ msgid "Contact Details" #~ msgstr "Szczegóły kontaktu" #~ msgid "Contacts" #~ msgstr "Kontakty" #~ msgid "Conversations" #~ msgstr "Conversations" #~ msgid "Country" #~ msgstr "Kraj" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Usuń" #~ msgid "Delete Contact" #~ msgstr "Usuń kontakt" #~ msgid "Dialing" #~ msgstr "Łączę..." #~ msgid "Duration %1" #~ msgstr "Czas %1" #~ msgid "Edit" #~ msgstr "Edycja" #~ msgid "Email" #~ msgstr "e-mail" #~ msgid "Enter a number" #~ msgstr "Podaj numer" #~ msgid "First" #~ msgstr "Początek" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Dom" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Ostatnie" #~ msgid "Locality" #~ msgstr "Miejscowość" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Wiadomości" #~ msgid "Middle" #~ msgstr "Środek" #~ msgid "Mobile" #~ msgstr "Komórka" #~ msgid "New Contact" #~ msgstr "Nowy kontakt" #~ msgid "New Message" #~ msgstr "Nowa wiadomość" #~ msgid "On Call" #~ msgstr "Dostępny" #~ msgid "Other" #~ msgstr "Inne" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Telefon" #~ msgid "Phone App" #~ msgstr "Aplikacja telefonu" #~ msgid "Phone application" #~ msgstr "Aplikacja telefonu" #~ msgid "Postal Code" #~ msgstr "Kod pocztowy" #~ msgid "Prefix" #~ msgstr "Prefiks" #~ msgid "Private number" #~ msgstr "Numer prywatny" #~ msgid "Region" #~ msgstr "Region" #~ msgid "Reply via SMS" #~ msgstr "Odpowiedź przez SMS" #~ msgid "Save" #~ msgstr "Zapisz" #~ msgid "Send" #~ msgstr "Wyślij" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Ulica" #~ msgid "Suffix" #~ msgstr "Sufiks" #~ msgid "Swap Calls" #~ msgstr "Przełączenie połączeń" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Do:" #~ msgid "Today" #~ msgstr "Dziś" #~ msgid "Unknown Contact" #~ msgstr "Nieznany kontakt" #~ msgid "Unknown number" #~ msgstr "Nieznany numer" #~ msgid "Voicemail" #~ msgstr "Poczta głosowa" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Praca" #~ msgid "Yahoo" #~ msgstr "Yahoo!" #~ msgid "Yesterday" #~ msgstr "Wczoraj" #~ msgid "missed call" #~ msgstr "Nieodebrane połączenie" telephony-service-0.1+14.04.20140415/po/de.po0000644000015301777760000001565612323307402020774 0ustar pbusernogroup00000000000000# German translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-13 17:01+0000\n" "Last-Translator: Hendrik Knackstedt \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 verpasster Anruf" msgstr[1] "%1 verpasste Anrufe" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 Sprachnachricht" msgstr[1] "%1 Sprachnachrichten" #: approver/approver.cpp:241 msgid "Accept" msgstr "Annehmen" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Die Nummer des Anrufers ist nicht verfügbar" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Anruf von %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Anruf von einer privaten Nummer" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Anruf von einer unbekannten Nummer" #: approver/approver.cpp:247 msgid "Decline" msgstr "Ablehnen" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Ich habe Ihren Anruf verpasst – können Sie mich jetzt anrufen?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Ich komme 20 Minuten zu spät." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Ich bin im Augenblick beschäftigt. Ich werde Sie später anrufen." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Ich bin spät dran, aber auf dem Weg." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Anrufe" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS von %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" "Entschuldigung, ich bin noch beschäftigt. Ich werde Sie später anrufen." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Unbekannter Anrufer" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Sprachnachrichten" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Verarbeitet eingehende Nachrichten, Anrufe und Benachrichtigungen" #~ msgid "Phone App Approver" #~ msgstr "Telefonanwendungszulasser" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "Anfrufdauer %1 Stunde" #~ msgstr[1] "Anfrufdauer %1 Stunden" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "Anfrufdauer %1 Minute" #~ msgstr[1] "Anfrufdauer %1 Minuten" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "Anfrufdauer %1 Sekunde" #~ msgstr[1] "Anfrufdauer %1 Sekunden" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Hinzufügen" #~ msgid "Add a phone number" #~ msgstr "Eine Telefonnummer hinzufügen" #~ msgid "Add a postal address" #~ msgstr "Eine Postanschrift hinzufügen" #~ msgid "Add an email address" #~ msgstr "Eine E-Mail-Adresse hinzufügen" #~ msgid "Add an online account" #~ msgstr "Ein Online-Konto hinzufügen" #~ msgid "Address" #~ msgstr "Adresse" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Sind Sie sicher, dass Sie diesen Kontakt löschen wollen?" #~ msgid "Call" #~ msgstr "Anruf" #~ msgid "Calls" #~ msgstr "Anrufe" #~ msgid "Cancel" #~ msgstr "Abbrechen" #~ msgid "Communication" #~ msgstr "Mitteilung" #~ msgid "Compose" #~ msgstr "Verfassen" #~ msgid "Contact Details" #~ msgstr "Kontaktinformationen" #~ msgid "Contacts" #~ msgstr "Kontakte" #~ msgid "Conversations" #~ msgstr "Unterhaltungen" #~ msgid "Country" #~ msgstr "Land" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Löschen" #~ msgid "Delete Contact" #~ msgstr "Kontakt löschen" #~ msgid "Dialing" #~ msgstr "Wählen" #~ msgid "Duration %1" #~ msgstr "Dauer %1" #~ msgid "Edit" #~ msgstr "Bearbeiten" #~ msgid "Email" #~ msgstr "E-Mail" #~ msgid "Enter a number" #~ msgstr "Geben Sie eine Zahl ein" #~ msgid "First" #~ msgstr "Erster" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Start" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Letzter" #~ msgid "Locality" #~ msgstr "Ortschaft" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Nachrichten" #~ msgid "Middle" #~ msgstr "Mitte" #~ msgid "Mobile" #~ msgstr "Mobil" #~ msgid "New Contact" #~ msgstr "Neuer Kontakt" #~ msgid "New Message" #~ msgstr "Neue Nachricht" #~ msgid "On Call" #~ msgstr "Beim Anruf" #~ msgid "Other" #~ msgstr "Andere" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Telefon" #~ msgid "Phone App" #~ msgstr "Telefon-Anwendung" #~ msgid "Phone application" #~ msgstr "Telefon-Anwendung" #~ msgid "Postal Code" #~ msgstr "Postleitzahl" #~ msgid "Prefix" #~ msgstr "Präfix" #~ msgid "Private number" #~ msgstr "Privatnummer" #~ msgid "Region" #~ msgstr "Region" #~ msgid "Reply via SMS" #~ msgstr "Per SMS antworten" #~ msgid "Save" #~ msgstr "Speichern" #~ msgid "Send" #~ msgstr "Senden" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Straße" #~ msgid "Suffix" #~ msgstr "Suffix" #~ msgid "Swap Calls" #~ msgstr "Anrufe wechseln" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "An:" #~ msgid "Today" #~ msgstr "Heute" #~ msgid "Unknown Contact" #~ msgstr "Unbekannter Kontakt" #~ msgid "Unknown number" #~ msgstr "Unbekannte Nummer" #~ msgid "Voicemail" #~ msgstr "Sprachnachricht" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Geschäftlich" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Gestern" #~ msgid "missed call" #~ msgstr "verpasster Anruf" telephony-service-0.1+14.04.20140415/po/da.po0000644000015301777760000000472112323307402020757 0ustar pbusernogroup00000000000000# Danish translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-03 23:19+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" telephony-service-0.1+14.04.20140415/po/ca.po0000644000015301777760000001332112323307402020752 0ustar pbusernogroup00000000000000# Catalan translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-05 08:08+0000\n" "Last-Translator: David Planella \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 trucada perduda" msgstr[1] "%1 trucades perdudes" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "Accepta" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "El número de la trucada entrant no està disponible" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "S'està trucant des de %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "S'està trucant des d'un número privat" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "S'està trucant des d'un número desconegut" #: approver/approver.cpp:247 msgid "Decline" msgstr "Rebutja" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "Missatge de text d'en/na %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "Trucada d'%1 hora" #~ msgstr[1] "Trucada de %1 hores" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "Trucada d'%1 minut" #~ msgstr[1] "Trucada %1 minuts" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Afegeix" #~ msgid "Add a phone number" #~ msgstr "Afegeix un número de telèfon" #~ msgid "Add a postal address" #~ msgstr "Afegeix una adreça postal" #~ msgid "Add an email address" #~ msgstr "Afegeix una adreça electrònica" #~ msgid "Add an online account" #~ msgstr "Afegeix un compte en línia" #~ msgid "Address" #~ msgstr "Adreça" #~ msgid "Call" #~ msgstr "Trucada" #~ msgid "Calls" #~ msgstr "Trucades" #~ msgid "Cancel" #~ msgstr "Cancel·la" #~ msgid "Communication" #~ msgstr "Comunicació" #~ msgid "Compose" #~ msgstr "Escriviu un missatge" #~ msgid "Contact Details" #~ msgstr "Detalls del contacte" #~ msgid "Contacts" #~ msgstr "Contactes" #~ msgid "Conversations" #~ msgstr "Converses" #~ msgid "Country" #~ msgstr "País" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Suprimeix" #~ msgid "Dialing" #~ msgstr "S'està marcant" #~ msgid "Duration %1" #~ msgstr "Durada: %1" #~ msgid "Edit" #~ msgstr "Edita" #~ msgid "Email" #~ msgstr "Correu electrònic" #~ msgid "Enter a number" #~ msgstr "Introduïu un número" #~ msgid "First" #~ msgstr "Nom" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Casa" #~ msgid "IM" #~ msgstr "Missatgeria instantània" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Cognoms" #~ msgid "Locality" #~ msgstr "Localitat" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Missatges" #~ msgid "Mobile" #~ msgstr "Mòbil" #~ msgid "New Contact" #~ msgstr "Contacte nou" #~ msgid "New Message" #~ msgstr "Missatge nou" #~ msgid "On Call" #~ msgstr "En una trucada" #~ msgid "Other" #~ msgstr "Altres" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Telèfon" #~ msgid "Postal Code" #~ msgstr "Codi postal" #~ msgid "Prefix" #~ msgstr "Prefix" #~ msgid "Private number" #~ msgstr "Número privat" #~ msgid "Region" #~ msgstr "Regió" #~ msgid "Reply via SMS" #~ msgstr "Contesta per missatge de text" #~ msgid "Save" #~ msgstr "Desa" #~ msgid "Send" #~ msgstr "Envia" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Carrer" #~ msgid "Suffix" #~ msgstr "Sufix" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "A:" #~ msgid "Today" #~ msgstr "Avuí" #~ msgid "Unknown Contact" #~ msgstr "Contacte desconegut" #~ msgid "Unknown number" #~ msgstr "Número desconegut" telephony-service-0.1+14.04.20140415/po/en_AU.po0000644000015301777760000001517112323307402021363 0ustar pbusernogroup00000000000000# English (Australia) translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-18 21:53+0000\n" "Last-Translator: Jackson Doak \n" "Language-Team: English (Australia) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 missed call" msgstr[1] "%1 missed calls" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 voicemail message" msgstr[1] "%1 voicemail messages" #: approver/approver.cpp:241 msgid "Accept" msgstr "Accept" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Caller number is not available" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Calling from %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Calling from private number" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Calling from unknown number" #: approver/approver.cpp:247 msgid "Decline" msgstr "Decline" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "I missed your call - can you call me now?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "I'll be 20 minutes late." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "I'm busy at the moment. I'll call you later." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "I'm running late. I'm on my way." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Phone Calls" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS from %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Sorry, I'm still busy. I'll call you later." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Unknown caller" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Voicemail messages" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Handles incoming messages, calls and indicators" #~ msgid "Phone App Approver" #~ msgstr "Phone App Approver" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 hour call" #~ msgstr[1] "%1 hours call" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minute call" #~ msgstr[1] "%1 minutes call" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 second call" #~ msgstr[1] "%1 seconds call" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Add" #~ msgid "Add a phone number" #~ msgstr "Add a phone number" #~ msgid "Add a postal address" #~ msgstr "Add a postal address" #~ msgid "Add an email address" #~ msgstr "Add an email address" #~ msgid "Add an online account" #~ msgstr "Add an online account" #~ msgid "Address" #~ msgstr "Address" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Are you sure you want to delete this contact?" #~ msgid "Call" #~ msgstr "Call" #~ msgid "Calls" #~ msgstr "Calls" #~ msgid "Cancel" #~ msgstr "Cancel" #~ msgid "Communication" #~ msgstr "Communication" #~ msgid "Compose" #~ msgstr "Compose" #~ msgid "Contact Details" #~ msgstr "Contact Details" #~ msgid "Contacts" #~ msgstr "Contacts" #~ msgid "Conversations" #~ msgstr "Conversations" #~ msgid "Country" #~ msgstr "Country" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Delete" #~ msgid "Delete Contact" #~ msgstr "Delete Contact" #~ msgid "Dialing" #~ msgstr "Dialing" #~ msgid "Duration %1" #~ msgstr "Duration %1" #~ msgid "Edit" #~ msgstr "Edit" #~ msgid "Email" #~ msgstr "Email" #~ msgid "Enter a number" #~ msgstr "Enter a number" #~ msgid "First" #~ msgstr "First" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Home" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Last" #~ msgid "Locality" #~ msgstr "Locality" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Messages" #~ msgid "Middle" #~ msgstr "Middle" #~ msgid "Mobile" #~ msgstr "Mobile" #~ msgid "New Contact" #~ msgstr "New Contact" #~ msgid "New Message" #~ msgstr "New Message" #~ msgid "On Call" #~ msgstr "On Call" #~ msgid "Other" #~ msgstr "Other" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Phone" #~ msgid "Phone App" #~ msgstr "Phone App" #~ msgid "Phone application" #~ msgstr "Phone application" #~ msgid "Postal Code" #~ msgstr "Postal Code" #~ msgid "Prefix" #~ msgstr "Prefix" #~ msgid "Private number" #~ msgstr "Private number" #~ msgid "Region" #~ msgstr "Region" #~ msgid "Reply via SMS" #~ msgstr "Reply via SMS" #~ msgid "Save" #~ msgstr "Save" #~ msgid "Send" #~ msgstr "Send" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Street" #~ msgid "Suffix" #~ msgstr "Suffix" #~ msgid "Swap Calls" #~ msgstr "Swap Calls" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "To:" #~ msgid "Today" #~ msgstr "Today" #~ msgid "Unknown Contact" #~ msgstr "Unknown Contact" #~ msgid "Unknown number" #~ msgstr "Unknown number" #~ msgid "Voicemail" #~ msgstr "Voicemail" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Work" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Yesterday" #~ msgid "missed call" #~ msgstr "missed call" telephony-service-0.1+14.04.20140415/po/zh_TW.po0000644000015301777760000001304512323307402021425 0ustar pbusernogroup00000000000000# Chinese (Traditional) translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-13 16:11+0000\n" "Last-Translator: Cheng-Chia Tseng \n" "Language-Team: Chinese (Traditional) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Launchpad-Export-Date: 2013-07-14 06:00+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 通未接來電" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 通語音留言" #: approver/approver.cpp:241 msgid "Accept" msgstr "接聽" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "%1 來電" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "拒接" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "%1 發送的 SMS" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "抱歉,我還在忙。待會打給你。" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "語音留言訊息" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "通話 %1 小時" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "通話 %1 分鐘" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "通話 %1 秒" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "加入" #~ msgid "Add a phone number" #~ msgstr "加入電話號碼" #~ msgid "Add a postal address" #~ msgstr "加入郵遞地址" #~ msgid "Add an email address" #~ msgstr "加入電子郵件" #~ msgid "Add an online account" #~ msgstr "加入線上帳號" #~ msgid "Address" #~ msgstr "位址" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "您確定要刪除這位連絡人?" #~ msgid "Call" #~ msgstr "通話" #~ msgid "Calls" #~ msgstr "通話" #~ msgid "Cancel" #~ msgstr "取消" #~ msgid "Communication" #~ msgstr "通訊" #~ msgid "Compose" #~ msgstr "撰寫" #~ msgid "Contact Details" #~ msgstr "聯絡人詳情" #~ msgid "Contacts" #~ msgstr "聯絡人" #~ msgid "Conversations" #~ msgstr "對話" #~ msgid "Country" #~ msgstr "國家/地區" #~ msgid "Delete" #~ msgstr "刪除" #~ msgid "Delete Contact" #~ msgstr "刪除聯絡人" #~ msgid "Dialing" #~ msgstr "正在撥號" #~ msgid "Duration %1" #~ msgstr "時間 %1" #~ msgid "Edit" #~ msgstr "編輯" #~ msgid "Email" #~ msgstr "電子郵件" #~ msgid "Enter a number" #~ msgstr "請輸入號碼" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "家屋" #~ msgid "IM" #~ msgstr "即時通訊" #~ msgid "Messages" #~ msgstr "訊息" #~ msgid "New Contact" #~ msgstr "新連絡人" #~ msgid "New Message" #~ msgstr "新訊息" #~ msgid "Other" #~ msgstr "其他" #~ msgid "Phone" #~ msgstr "手機" #~ msgid "Phone App" #~ msgstr "手機程式" #~ msgid "Phone application" #~ msgstr "手機應用程式" #~ msgid "Postal Code" #~ msgstr "郵遞區號" #~ msgid "Prefix" #~ msgstr "前綴" #~ msgid "Region" #~ msgstr "地區" #~ msgid "Reply via SMS" #~ msgstr "以 SMS 回覆" #~ msgid "Save" #~ msgstr "儲存" #~ msgid "Send" #~ msgstr "傳送" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "街巷" #~ msgid "Suffix" #~ msgstr "後綴" #~ msgid "To:" #~ msgstr "收件者:" #~ msgid "Today" #~ msgstr "今日" #~ msgid "Unknown Contact" #~ msgstr "未知聯絡人" #~ msgid "Unknown number" #~ msgstr "未知號碼" #~ msgid "Voicemail" #~ msgstr "語音留言" #~ msgid "Work" #~ msgstr "工作" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "昨日" #~ msgid "missed call" #~ msgstr "未接來電" telephony-service-0.1+14.04.20140415/po/telephony-service.pot0000644000015301777760000000454012323307402024223 0ustar pbusernogroup00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" telephony-service-0.1+14.04.20140415/po/nb.po0000644000015301777760000000474512323307402021000 0ustar pbusernogroup00000000000000# Norwegian Bokmal translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-05-29 08:41+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Norwegian Bokmal \n" "Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" telephony-service-0.1+14.04.20140415/po/en_GB.po0000644000015301777760000001516612323307402021352 0ustar pbusernogroup00000000000000# English (United Kingdom) translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-24 16:41+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 missed call" msgstr[1] "%1 missed calls" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 voicemail message" msgstr[1] "%1 voicemail messages" #: approver/approver.cpp:241 msgid "Accept" msgstr "Accept" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Caller number is not available" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Calling from %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Calling from private number" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Calling from unknown number" #: approver/approver.cpp:247 msgid "Decline" msgstr "Decline" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "I missed your call - can you call me now?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "I'll be 20 minutes late." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "I'm busy at the moment. I'll call you later." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "I'm running late. I'm on my way." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Phone Calls" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS from %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Sorry, I'm still busy. I'll call you later." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Unknown caller" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Voicemail messages" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Handles incoming messages, calls and indicators" #~ msgid "Phone App Approver" #~ msgstr "Phone App Approver" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 hour call" #~ msgstr[1] "%1 hours call" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minute call" #~ msgstr[1] "%1 minutes call" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 second call" #~ msgstr[1] "%1 seconds call" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Add" #~ msgid "Add a phone number" #~ msgstr "Add a phone number" #~ msgid "Add a postal address" #~ msgstr "Add a postal address" #~ msgid "Add an email address" #~ msgstr "Add an email address" #~ msgid "Add an online account" #~ msgstr "Add an online account" #~ msgid "Address" #~ msgstr "Address" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Are you sure you want to delete this contact?" #~ msgid "Call" #~ msgstr "Call" #~ msgid "Calls" #~ msgstr "Calls" #~ msgid "Cancel" #~ msgstr "Cancel" #~ msgid "Communication" #~ msgstr "Communication" #~ msgid "Compose" #~ msgstr "Compose" #~ msgid "Contact Details" #~ msgstr "Contact Details" #~ msgid "Contacts" #~ msgstr "Contacts" #~ msgid "Conversations" #~ msgstr "Conversations" #~ msgid "Country" #~ msgstr "Country" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Delete" #~ msgid "Delete Contact" #~ msgstr "Delete Contact" #~ msgid "Dialing" #~ msgstr "Dialling" #~ msgid "Duration %1" #~ msgstr "Duration %1" #~ msgid "Edit" #~ msgstr "Edit" #~ msgid "Email" #~ msgstr "Email" #~ msgid "Enter a number" #~ msgstr "Enter a number" #~ msgid "First" #~ msgstr "First" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Home" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Last" #~ msgid "Locality" #~ msgstr "Locality" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Messages" #~ msgid "Middle" #~ msgstr "Middle" #~ msgid "Mobile" #~ msgstr "Mobile" #~ msgid "New Contact" #~ msgstr "New Contact" #~ msgid "New Message" #~ msgstr "New Message" #~ msgid "On Call" #~ msgstr "On Call" #~ msgid "Other" #~ msgstr "Other" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Phone" #~ msgid "Phone App" #~ msgstr "Phone App" #~ msgid "Phone application" #~ msgstr "Phone application" #~ msgid "Postal Code" #~ msgstr "Postal Code" #~ msgid "Prefix" #~ msgstr "Prefix" #~ msgid "Private number" #~ msgstr "Private number" #~ msgid "Region" #~ msgstr "Region" #~ msgid "Reply via SMS" #~ msgstr "Reply via SMS" #~ msgid "Save" #~ msgstr "Save" #~ msgid "Send" #~ msgstr "Send" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Street" #~ msgid "Suffix" #~ msgstr "Suffix" #~ msgid "Swap Calls" #~ msgstr "Swap Calls" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "To:" #~ msgid "Today" #~ msgstr "Today" #~ msgid "Unknown Contact" #~ msgstr "Unknown Contact" #~ msgid "Unknown number" #~ msgstr "Unknown number" #~ msgid "Voicemail" #~ msgstr "Voicemail" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Work" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Yesterday" #~ msgid "missed call" #~ msgstr "missed call" telephony-service-0.1+14.04.20140415/po/ar.po0000644000015301777760000002100212323307402020764 0ustar pbusernogroup00000000000000# Arabic translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-14 18:40+0000\n" "Last-Translator: Ibrahim Saed \n" "Language-Team: Arabic \n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= " "3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "لا مكالمات لم ترد عليها (%1)" msgstr[1] "مكالمة واحدة لم ترد عليها (%1)" msgstr[2] "مكالمتين لم ترد عليهما (%1)" msgstr[3] "%1 مكالمات لم ترد عليها" msgstr[4] "%1 مكالمة لم ترد عليها" msgstr[5] "%1 مكالمة لم ترد عليها" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "لا رسائل صوتية (%1)" msgstr[1] "رسالة صوتية واحدة (%1)" msgstr[2] "رسالتان صوتيتان (%1)" msgstr[3] "%1 رسائل صوتية" msgstr[4] "%1 رسالة صوتية" msgstr[5] "%1 رسالة صوتية" #: approver/approver.cpp:241 msgid "Accept" msgstr "أجب" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "رقم المتصل غير متاح حاليا" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "الاتصال من %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "اتصال من رقم خاص" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "اتصال من رقم مجهول" #: approver/approver.cpp:247 msgid "Decline" msgstr "ارفض" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "لقد فاتني اتصالك ولم أرد عليه - أيمكنك معاودة الاتصال بي الآن؟" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "سأتأخر 20 دقيقة." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "أنا منشغل حاليا. سأتصل بك لاحقا." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "قد أتأخر قليلا. أنا في طريقي إليك." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "مكالمات هاتفية" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "رسالة قصيرة" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "رسالة قصيرة من %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "عذرًا، ما زلت منشغلا. سأتصل بك لاحقا." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "متصل مجهول" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "رسائل البريد الصوتي" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "تعامل مع الرسائل، والمكالمات الواردة والمؤشرات" #~ msgid "Phone App Approver" #~ msgstr "تطبيق الإجابة على الهاتف" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "اتصال أقل من ساعة (%1)" #~ msgstr[1] "اتصال ساعة واحدة (%1)" #~ msgstr[2] "اتصال ساعتان (%1)" #~ msgstr[3] "اتصال %1 ساعات" #~ msgstr[4] "اتصال %1 ساعة" #~ msgstr[5] "اتصال %1 ساعة" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "اتصال أقل من دقيقة (%1)" #~ msgstr[1] "اتصال دقيقة واحدة (%1)" #~ msgstr[2] "اتصال دقيقتان (%1)" #~ msgstr[3] "اتصال %1 دقائق" #~ msgstr[4] "اتصال %1 دقيقة" #~ msgstr[5] "اتصال %1 دقيقة" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "اتصال أقل من ثانية (%1)" #~ msgstr[1] "اتصال ثانية واحدة (%1)" #~ msgstr[2] "اتصال ثانيتين (%1)" #~ msgstr[3] "اتصال %1 ثوان" #~ msgstr[4] "اتصال %1 ثانية" #~ msgstr[5] "اتصال %1 ثانية" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "٠" #~ msgid "1" #~ msgstr "١" #~ msgid "2" #~ msgstr "٢" #~ msgid "3" #~ msgstr "٣" #~ msgid "4" #~ msgstr "٤" #~ msgid "5" #~ msgstr "٥" #~ msgid "6" #~ msgstr "٦" #~ msgid "7" #~ msgstr "٧" #~ msgid "8" #~ msgstr "٨" #~ msgid "9" #~ msgstr "٩" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "أضِف" #~ msgid "Add a phone number" #~ msgstr "أضِف رقم هاتف" #~ msgid "Add a postal address" #~ msgstr "أضِف عنوان بريدي" #~ msgid "Add an email address" #~ msgstr "أضِف عنوان بريد إلكتروني" #~ msgid "Add an online account" #~ msgstr "أضِف حساب إنترنت" #~ msgid "Address" #~ msgstr "العنوان" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "أمتأكد أنك ترغب بحذف هذا الشخص؟" #~ msgid "Call" #~ msgstr "اتصل" #~ msgid "Calls" #~ msgstr "المكالمات" #~ msgid "Cancel" #~ msgstr "ألغِ" #~ msgid "Communication" #~ msgstr "التواصل" #~ msgid "Compose" #~ msgstr "إنشاء رسالة" #~ msgid "Contact Details" #~ msgstr "تفاصيل الشخص" #~ msgid "Contacts" #~ msgstr "الأشخاص" #~ msgid "Conversations" #~ msgstr "المحادثات" #~ msgid "Country" #~ msgstr "الدولة" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "احذف" #~ msgid "Delete Contact" #~ msgstr "احذف الشخص" #~ msgid "Duration %1" #~ msgstr "المُدة %1" #~ msgid "Edit" #~ msgstr "حرّر" #~ msgid "Email" #~ msgstr "البريد الإلكتروني" #~ msgid "Enter a number" #~ msgstr "أدخِل رقم" #~ msgid "First" #~ msgstr "الأول" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "جوجل توك" #~ msgid "Home" #~ msgstr "الرئيسية" #~ msgid "IM" #~ msgstr "تراسل فوري" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "الأخير" #~ msgid "Locality" #~ msgstr "المنطقة" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "الرسائل" #~ msgid "Middle" #~ msgstr "الأوسط" #~ msgid "Mobile" #~ msgstr "الهاتف المتنقل" #~ msgid "New Contact" #~ msgstr "شخص جديد" #~ msgid "New Message" #~ msgstr "رسالة جديدة" #~ msgid "On Call" #~ msgstr "على اتصال" #~ msgid "Other" #~ msgstr "أخرى" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "الهاتف" #~ msgid "Phone App" #~ msgstr "تطبيق الهاتف" #~ msgid "Phone application" #~ msgstr "تطبيق الهاتف" #~ msgid "Postal Code" #~ msgstr "الرمز البريدي" #~ msgid "Prefix" #~ msgstr "البادئة" #~ msgid "Private number" #~ msgstr "رقم خاص" #~ msgid "Region" #~ msgstr "المنطقة" #~ msgid "Reply via SMS" #~ msgstr "الرد عبر رسالة قصيرة" #~ msgid "Save" #~ msgstr "احفظ" #~ msgid "Send" #~ msgstr "أرسل" #~ msgid "Skype" #~ msgstr "سكايب" #~ msgid "Street" #~ msgstr "الشارع" #~ msgid "Suffix" #~ msgstr "اللاحقة" #~ msgid "Swap Calls" #~ msgstr "تبديل المكالمات" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "إلى:" #~ msgid "Today" #~ msgstr "اليوم" #~ msgid "Unknown Contact" #~ msgstr "شخص مجهول" #~ msgid "Unknown number" #~ msgstr "رقم مجهول" #~ msgid "Voicemail" #~ msgstr "البريد الصوتي" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "العمل" #~ msgid "Yahoo" #~ msgstr "ياهوو" #~ msgid "Yesterday" #~ msgstr "أمس" #~ msgid "missed call" #~ msgstr "اتصال لم ترد عليه" telephony-service-0.1+14.04.20140415/po/CMakeLists.txt0000644000015301777760000000272512323307402022575 0ustar pbusernogroup00000000000000project(telephony-service-translations) # for dh_translations to extract the domain # (regarding syntax consistency, see http://pad.lv/1181187) set (GETTEXT_PACKAGE "telephony-service") include(FindGettext) set(DOMAIN telephony-service) set(POT_FILE ${DOMAIN}.pot) file(GLOB PO_FILES *.po) file(GLOB_RECURSE I18N_SRCS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/approver/*.cpp ${CMAKE_SOURCE_DIR}/handler/*.cpp ${CMAKE_SOURCE_DIR}/indicator/*.desktop.in ${CMAKE_SOURCE_DIR}/indicator/*.cpp ${CMAKE_SOURCE_DIR}/Ubuntu/*.cpp ) foreach(PO_FILE ${PO_FILES}) get_filename_component(LANG ${PO_FILE} NAME_WE) gettext_process_po_files(${LANG} ALL PO_FILES ${PO_FILE}) set(INSTALL_DIR ${CMAKE_INSTALL_LOCALEDIR}/${LANG}/LC_MESSAGES) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo DESTINATION ${INSTALL_DIR} RENAME ${DOMAIN}.mo) endforeach(PO_FILE) find_program(XGETTEXT_EXECUTABLE xgettext) if(XGETTEXT_EXECUTABLE) add_custom_target(${POT_FILE}) add_custom_command(TARGET ${POT_FILE} COMMAND ${XGETTEXT_EXECUTABLE} --c++ --qt --add-comments=TRANSLATORS --keyword=tr --keyword=tr:1,2 -D ${CMAKE_SOURCE_DIR} -s -p ${CMAKE_CURRENT_SOURCE_DIR} -o ${POT_FILE} ${I18N_SRCS} ) foreach(PO_FILE ${PO_FILES}) add_custom_command(TARGET ${POT_FILE} COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} ${PO_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/${POT_FILE} -o ${PO_FILE} ) endforeach(PO_FILE) endif() telephony-service-0.1+14.04.20140415/po/fi.po0000644000015301777760000001537712323307402021002 0ustar pbusernogroup00000000000000# Finnish translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-13 11:57+0000\n" "Last-Translator: Timo Jyrinki \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 vastaamaton puhelu" msgstr[1] "%1 vastaamatonta puhelua" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 vastaajaviesti" msgstr[1] "%1 vastaajaviestiä" #: approver/approver.cpp:241 msgid "Accept" msgstr "Hyväksy" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Soittajan numero ei ole saatavilla" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Puhelu numerosta %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Puhelu salaisesta numerosta" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Puhelu tuntemattomasta numerosta" #: approver/approver.cpp:247 msgid "Decline" msgstr "Hylkää" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "En huomannut puheluasi, voitko soittaa nyt?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Olen 20 minuuttia myöhässä." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Olen kiireinen. Soitan myöhemmin." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Olen myöhässä, mutta silti tulossa." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Puhelut" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "Tekstiviesti" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "Tekstiviesti numerosta %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Olen valitettavasti edelleen kiireinen. Soitan myöhemmin." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Tuntematon soittaja" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Vastaajaviestit" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Saapuvien viestien, puheluiden ja ilmaisimien hallinta" #~ msgid "Phone App Approver" #~ msgstr "Puhelinsovelluksen hyväksyjä" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 tunnin puhelu" #~ msgstr[1] "%1 tunnin puhelu" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minuutin puhelu" #~ msgstr[1] "%1 minuutin puhelu" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 sekunnin puhelu" #~ msgstr[1] "%1 sekunnin puhelu" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Lisää" #~ msgid "Add a phone number" #~ msgstr "Lisää puhelinnumero" #~ msgid "Add a postal address" #~ msgstr "Lisää postiosoite" #~ msgid "Add an email address" #~ msgstr "Lisää sähköpostiosoite" #~ msgid "Add an online account" #~ msgstr "Lisää verkkotili" #~ msgid "Address" #~ msgstr "Osoite" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Haluatko varmasti poistaa tämän yhteystiedon?" #~ msgid "Call" #~ msgstr "Puhelu" #~ msgid "Calls" #~ msgstr "Puhelut" #~ msgid "Cancel" #~ msgstr "Peru" #~ msgid "Communication" #~ msgstr "Yhteydenpito" #~ msgid "Compose" #~ msgstr "Luo viesti" #~ msgid "Contact Details" #~ msgstr "Tarkemmat tiedot" #~ msgid "Contacts" #~ msgstr "Yhteystiedot" #~ msgid "Conversations" #~ msgstr "Keskustelut" #~ msgid "Country" #~ msgstr "Maa" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Poista" #~ msgid "Delete Contact" #~ msgstr "Poista yhteystieto" #~ msgid "Dialing" #~ msgstr "Soitetaan" #~ msgid "Duration %1" #~ msgstr "Kesto %1" #~ msgid "Edit" #~ msgstr "Muokkaa" #~ msgid "Email" #~ msgstr "Sähköposti" #~ msgid "Enter a number" #~ msgstr "Anna numero" #~ msgid "First" #~ msgstr "Etunimi" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Koti" #~ msgid "IM" #~ msgstr "Pikaviestin" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Sukunimi" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Viestit" #~ msgid "Middle" #~ msgstr "Toinen nimi" #~ msgid "Mobile" #~ msgstr "Matkapuhelin" #~ msgid "New Contact" #~ msgstr "Uusi yhteystieto" #~ msgid "New Message" #~ msgstr "Uusi viesti" #~ msgid "On Call" #~ msgstr "Puhelu käynnissä" #~ msgid "Other" #~ msgstr "Muu" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Puhelin" #~ msgid "Phone App" #~ msgstr "Puhelinsovellus" #~ msgid "Phone application" #~ msgstr "Puhelinsovellus" #~ msgid "Postal Code" #~ msgstr "Postinumero" #~ msgid "Prefix" #~ msgstr "Etuliite" #~ msgid "Private number" #~ msgstr "Salainen numero" #~ msgid "Region" #~ msgstr "Alue" #~ msgid "Reply via SMS" #~ msgstr "Vastaa tekstiviestillä" #~ msgid "Save" #~ msgstr "Tallenna" #~ msgid "Send" #~ msgstr "Lähetä" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Katu" #~ msgid "Swap Calls" #~ msgstr "Vaihda puhelujen välillä" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Vastaanottaja:" #~ msgid "Today" #~ msgstr "Tänään" #~ msgid "Unknown Contact" #~ msgstr "Tuntematon yhteystieto" #~ msgid "Unknown number" #~ msgstr "Tuntematon numero" #~ msgid "Voicemail" #~ msgstr "Vastaaja" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Työ" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Eilen" #~ msgid "missed call" #~ msgstr "vastaamaton puhelu" telephony-service-0.1+14.04.20140415/po/pt_BR.po0000644000015301777760000001546712323307402021412 0ustar pbusernogroup00000000000000# Brazilian Portuguese translation for telephony-service # Copyright (c) 2013 Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-14 21:06+0000\n" "Last-Translator: Rafael Neri \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 chamada perdida" msgstr[1] "%1 chamadas perdidas" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mensagem de voz" msgstr[1] "%1 mensagens de voz" #: approver/approver.cpp:241 msgid "Accept" msgstr "Aceitar" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Número não disponível" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Chamando de %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Chamando de um número privado" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Chamando de um número desconhecido" #: approver/approver.cpp:247 msgid "Decline" msgstr "Rejeitar" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Eu perdi sua ligação - você pode me ligar agora?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "Vou chegar 20 minutos atrasado." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "Estou ocupado no momento. Te ligo mais tarde." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Eu estou atrasado. Eu estou a caminho." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Chamadas telefônicas" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS de %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Descupas, eu continuo ocupado. Eu te ligo depois." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Contato desconhecido" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Caixa de mensagens" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "Manipula as mensagens recebidas, chamadas e indicadores" #~ msgid "Phone App Approver" #~ msgstr "Aprovador do Phone App" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "chamada de %1 hora" #~ msgstr[1] "chamada de %1 horas" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "chamada de %1 minuto" #~ msgstr[1] "chamada de %1 minutos" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "chamada de %1 segundo" #~ msgstr[1] "chamada de %1 segundos" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Adicionar" #~ msgid "Add a phone number" #~ msgstr "Adicionar um número de telefone" #~ msgid "Add a postal address" #~ msgstr "Adicionar um endereço" #~ msgid "Add an email address" #~ msgstr "Adicionar um endereço de email" #~ msgid "Add an online account" #~ msgstr "Adicionar uma conta online" #~ msgid "Address" #~ msgstr "Endereço" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Você tem certeza de que deseja excluir este contato?" #~ msgid "Call" #~ msgstr "Chamada" #~ msgid "Calls" #~ msgstr "Chamadas" #~ msgid "Cancel" #~ msgstr "Cancelar" #~ msgid "Communication" #~ msgstr "Comunicação" #~ msgid "Compose" #~ msgstr "Escrever" #~ msgid "Contact Details" #~ msgstr "Detalhes do Contato" #~ msgid "Contacts" #~ msgstr "Contatos" #~ msgid "Conversations" #~ msgstr "Conversas" #~ msgid "Country" #~ msgstr "País" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Apagar" #~ msgid "Delete Contact" #~ msgstr "Excluir contato" #~ msgid "Dialing" #~ msgstr "Discando" #~ msgid "Duration %1" #~ msgstr "Duração %1" #~ msgid "Edit" #~ msgstr "Editar" #~ msgid "Email" #~ msgstr "Email" #~ msgid "Enter a number" #~ msgstr "Entre com um número" #~ msgid "First" #~ msgstr "Primeiro" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Casa" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Último" #~ msgid "Locality" #~ msgstr "Localidade" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Mensagens" #~ msgid "Middle" #~ msgstr "Meio" #~ msgid "Mobile" #~ msgstr "Celular" #~ msgid "New Contact" #~ msgstr "Novo Contato" #~ msgid "New Message" #~ msgstr "Nova Mensagem" #~ msgid "On Call" #~ msgstr "Em chamada" #~ msgid "Other" #~ msgstr "Outro" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Telefone" #~ msgid "Phone App" #~ msgstr "Phone App" #~ msgid "Phone application" #~ msgstr "Aplicativo de telefone" #~ msgid "Postal Code" #~ msgstr "Cep" #~ msgid "Prefix" #~ msgstr "Prefixo" #~ msgid "Private number" #~ msgstr "Número privado" #~ msgid "Region" #~ msgstr "Região" #~ msgid "Reply via SMS" #~ msgstr "Responder via SMS" #~ msgid "Save" #~ msgstr "Salvar" #~ msgid "Send" #~ msgstr "Enviar" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Rua" #~ msgid "Suffix" #~ msgstr "Sufixo" #~ msgid "Swap Calls" #~ msgstr "Alternar Chamadas" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Para:" #~ msgid "Today" #~ msgstr "Hoje" #~ msgid "Unknown Contact" #~ msgstr "Contato desconhecido" #~ msgid "Unknown number" #~ msgstr "Número desconhecido" #~ msgid "Voicemail" #~ msgstr "Caixa de mensagens" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Trabalho" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Ontem" #~ msgid "missed call" #~ msgstr "chamada perdida" telephony-service-0.1+14.04.20140415/po/my.po0000644000015301777760000002143512323307402021021 0ustar pbusernogroup00000000000000# Burmese translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-13 08:49+0000\n" "Last-Translator: Pyae Sone \n" "Language-Team: Burmese \n" "Language: my\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Launchpad-Export-Date: 2013-07-14 06:00+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 လွတ်သွားသောခေါ်ဆိုမှု့" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 အသံ message" #: approver/approver.cpp:241 msgid "Accept" msgstr "လက်ခံ" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "ခေါ်ဆိုသည့်နံပါတ်မှာမရရှိနိုင်ပါ" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "%1 မှခေါ်နေသည်" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "လျှို့ဝှက်နံပါတ်မှခေါ်နေသည်" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "မသိရှိသောနံပါတ်မှခေါ်နေသည်" #: approver/approver.cpp:247 msgid "Decline" msgstr "ငြင်းပယ်" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "ကျွန်ုပ်သင်၏ခေါ်ဆိုမှု့ကိုမကိုင်မိပါ။ အခုပြန်လည်ခေါ်ဆိုနိုင်သလား။" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "ကျွန်ုပ် မိနစ် ၂၀ နောက်ကျမည်" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "ကျွန်ုပ်ယခုအလုပ်များနေသည်။နောက်မှ ပြန်လည်ခေါ်ဆိုလိုက်မည်" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "ကျွန်ုပ်သွားတာနောက်ကျနေပြီ။လမ်းတွင်ရောက်နေပြီ။" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "ဖုန်းခေါ်ဆိုမည်" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "စာတိုပို့စနစ်" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "%1 မှ SMS" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "ဆောရီး၊ အလုပ်များနေသေးသည်။ နောက်မှပြန်ခေါ်လိုက်မည်" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "မသိသောခေါ်ဆိုသူ" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "အသံနှင့်စာများ" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "အဝင်စာများ၊ ခေါ်ဆိုမှု့များ၊နှင့် indicators များကိုခန့်ခွဲမည်" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 နာရီခေါ်ဆိုမှု့" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 မိနစ် ခေါ်ဆိုမှု့" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 စက္ကန့်ခေါ်ဆိုမှု့" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "၀" #~ msgid "1" #~ msgstr "၁" #~ msgid "2" #~ msgstr "၂" #~ msgid "3" #~ msgstr "၃" #~ msgid "4" #~ msgstr "၄" #~ msgid "5" #~ msgstr "၅" #~ msgid "6" #~ msgstr "၆" #~ msgid "7" #~ msgstr "၇" #~ msgid "8" #~ msgstr "၈" #~ msgid "9" #~ msgstr "၉" #~ msgid "ABC" #~ msgstr "ကခဂ" #~ msgid "Add" #~ msgstr "ပေါင်းထည့်" #~ msgid "Add a phone number" #~ msgstr "ဖုန်းနံပါတ်တစ်ခုပေါင်းထည့်မည်" #~ msgid "Add a postal address" #~ msgstr "စာတိုက်လိပ်စာတစ်ခုထည့်မည်" #~ msgid "Add an email address" #~ msgstr "အီးမေးလ်လိပ်စာတစ်ခုထည့်မည်" #~ msgid "Add an online account" #~ msgstr "အွန်လိုင်းအကောင့်တစ်ခုထည့်မည်" #~ msgid "Address" #~ msgstr "လိပ်စာ" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "ဒီဆက်သွယ်ရမည့်လူစာရင်းကိုဖျက်ချင်တာသေချာပြီလား။" #~ msgid "Call" #~ msgstr "ခေါ်မည်" #~ msgid "Calls" #~ msgstr "ခေါ်ဆိုမှု့" #~ msgid "Cancel" #~ msgstr "ပယ်ဖျက်မည်" #~ msgid "Communication" #~ msgstr "ဆက်သွယ်ရေး" #~ msgid "Compose" #~ msgstr "ပို့မည်" #~ msgid "Contact Details" #~ msgstr "အဆက်အသွယ်၏အချက်အလက်များ" #~ msgid "Contacts" #~ msgstr "အဆက်အသွယ်များ" #~ msgid "Conversations" #~ msgstr "စကားပြောဆိုမှု့များ" #~ msgid "Country" #~ msgstr "တိုင်းပြည်" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "ဖျက်မည်" #~ msgid "Delete Contact" #~ msgstr "ဒီဆက်သွယ်ရမည့်စာရင်းကိုဖျက်မည်။" #~ msgid "Dialing" #~ msgstr "ခေါ်နေသည်" #~ msgid "Duration %1" #~ msgstr "ကြာချိန် %1" #~ msgid "Edit" #~ msgstr "ပြင်ဆင်" #~ msgid "Email" #~ msgstr "အီးမေးလ်" #~ msgid "Enter a number" #~ msgstr "နံပါတ်ရိုက်ထည့်ပါ" #~ msgid "First" #~ msgstr "ပထမ" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "ပင်မ" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "နောက်ဆုံး" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "စာများ" #~ msgid "Middle" #~ msgstr "အလယ်" #~ msgid "Mobile" #~ msgstr "မိုဘိုင်း" #~ msgid "New Contact" #~ msgstr "အဆက်အသွယ် အသစ်" #~ msgid "New Message" #~ msgstr "စာ အသစ်" #~ msgid "On Call" #~ msgstr "ခေါ်နေစဉ်" #~ msgid "Other" #~ msgstr "အခြား" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "ဖုန်း" #~ msgid "Phone App" #~ msgstr "ဖုန်း app" #~ msgid "Phone application" #~ msgstr "ဖုန်း application" #~ msgid "Postal Code" #~ msgstr "စာတိုက်ကုဒ်နံပါတ်" #~ msgid "Prefix" #~ msgstr "ရှေ့ဆက်" #~ msgid "Private number" #~ msgstr "လျှို့ဝှက်နံပါတ်" #~ msgid "Region" #~ msgstr "နေရာဒေသ" #~ msgid "Reply via SMS" #~ msgstr "SMS နှင့်ပြန်ဖြေမည်" #~ msgid "Save" #~ msgstr "သိမ်းမည်" #~ msgid "Send" #~ msgstr "ပို့မည်" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "လမ်း" #~ msgid "Suffix" #~ msgstr "နောက်ဆက်" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "သို့-" #~ msgid "Today" #~ msgstr "ယနေ့" #~ msgid "Unknown Contact" #~ msgstr "မသိသောအဆက်အသွယ်" #~ msgid "Unknown number" #~ msgstr "မသိသောနံပါတ်" #~ msgid "Voicemail" #~ msgstr "အသံmail" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "အလုပ်အကိုင်" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "မနေ့က" #~ msgid "missed call" #~ msgstr "လွတ်သွားသောခေါ်ဆိုမှု့" telephony-service-0.1+14.04.20140415/po/fr.po0000644000015301777760000001432612323307402021004 0ustar pbusernogroup00000000000000# French translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-12 17:11+0000\n" "Last-Translator: electroluth \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Launchpad-Export-Date: 2013-07-13 06:35+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 appel manqué" msgstr[1] "%1 appels manqués" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 message vocal" msgstr[1] "%1 messages vocaux" #: approver/approver.cpp:241 msgid "Accept" msgstr "Accepter" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Le numéro d'appel n'est pas disponible" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Appel depuis un numéro privé" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Appel depuis un numéro inconnu" #: approver/approver.cpp:247 msgid "Decline" msgstr "Refuser" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "J'ai manqué votre appel - pouvez-vous m'appeler maintenant ?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "J'aurai 20 minutes de retard." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Je suis en retard. Je suis en chemin." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Appels téléphoniques" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS de %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Désolé, je suis encore occupé. Je vous rappelle plus tard." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Numéro inconnu" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Messages vocaux" #~ msgid "#" #~ msgstr "#" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "%1 heure d'appel" #~ msgstr[1] "%1 heures d'appel" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "%1 minute d'appel" #~ msgstr[1] "%1 minutes d'appel" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "%1 seconde d'appel" #~ msgstr[1] "%1 secondes d'appel" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Ajouter" #~ msgid "Add a phone number" #~ msgstr "Ajouter un numéro de téléphone" #~ msgid "Add a postal address" #~ msgstr "Ajouter une adresse postale" #~ msgid "Add an email address" #~ msgstr "Ajouter une adresse courriel" #~ msgid "Add an online account" #~ msgstr "Ajouter un compte en ligne" #~ msgid "Address" #~ msgstr "Adresse" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Voulez-vous vraiment supprimer ce contact ?" #~ msgid "Call" #~ msgstr "Appeler" #~ msgid "Calls" #~ msgstr "Appels" #~ msgid "Cancel" #~ msgstr "Annuler" #~ msgid "Communication" #~ msgstr "Communication" #~ msgid "Compose" #~ msgstr "Composer" #~ msgid "Contact Details" #~ msgstr "Détails du contact" #~ msgid "Contacts" #~ msgstr "Contacts" #~ msgid "Conversations" #~ msgstr "Conversations" #~ msgid "Country" #~ msgstr "Pays" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Supprimer" #~ msgid "Delete Contact" #~ msgstr "Supprimer le contact" #~ msgid "Duration %1" #~ msgstr "Durée %1" #~ msgid "Edit" #~ msgstr "Modifier" #~ msgid "Email" #~ msgstr "Courriel" #~ msgid "Enter a number" #~ msgstr "Composer un numéro" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Accueil" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Locality" #~ msgstr "Lieu" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Messages" #~ msgid "Mobile" #~ msgstr "Téléphone portable" #~ msgid "New Contact" #~ msgstr "Nouveau contact" #~ msgid "New Message" #~ msgstr "Nouveau message" #~ msgid "Other" #~ msgstr "Autre" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Téléphone" #~ msgid "Postal Code" #~ msgstr "Code postal" #~ msgid "Prefix" #~ msgstr "Préfixe" #~ msgid "Private number" #~ msgstr "Numéro privé" #~ msgid "Region" #~ msgstr "Région" #~ msgid "Reply via SMS" #~ msgstr "Répondre par SMS" #~ msgid "Save" #~ msgstr "Enregistrer" #~ msgid "Send" #~ msgstr "Envoyer" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Rue" #~ msgid "Suffix" #~ msgstr "Suffixe" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "À :" #~ msgid "Today" #~ msgstr "Aujourd'hui" #~ msgid "Unknown Contact" #~ msgstr "Contact inconnu" #~ msgid "Unknown number" #~ msgstr "Numéro inconnu" #~ msgid "Voicemail" #~ msgstr "Messagerie vocale" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Travail" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Hier" #~ msgid "missed call" #~ msgstr "appel manqué" telephony-service-0.1+14.04.20140415/po/hu.po0000644000015301777760000000472712323307402021015 0ustar pbusernogroup00000000000000# Hungarian translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-02 21:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: approver/approver.cpp:241 msgid "Accept" msgstr "" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "" #: approver/approver.cpp:247 msgid "Decline" msgstr "" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "" telephony-service-0.1+14.04.20140415/po/ru.po0000644000015301777760000001556412323307402021030 0ustar pbusernogroup00000000000000# Russian translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-07-01 14:05+0000\n" "Last-Translator: Denis Kustov <06deku@gmail.com>\n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Launchpad-Export-Date: 2013-07-11 06:27+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 голосовое сообщение" msgstr[1] "%1 голосовых сообщения" msgstr[2] "%1 голосовых сообщений" #: approver/approver.cpp:241 msgid "Accept" msgstr "Принять" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "Номер абонента не доступен" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "Вызов от %1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "Приватный вызов" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "Звонок с неизвестного номера" #: approver/approver.cpp:247 msgid "Decline" msgstr "Отклонить" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "Я пропустил ваш звонок - вы можете позвонить мне сейчас?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "" #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "В данный момент я занят. Я позвоню тебе позже." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "Я опаздываю. Я уже в пути." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS от %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Извини, я всё еще занят. Я позвоню тебе позже." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "Неизвестный вызов" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "Голосовые сообщения" #~ msgid "#" #~ msgstr "#" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "ABC" #~ msgid "Add" #~ msgstr "Добавить" #~ msgid "Add a phone number" #~ msgstr "Добавить номер телефона" #~ msgid "Add a postal address" #~ msgstr "Добавить почтовый адрес" #~ msgid "Add an email address" #~ msgstr "Добавить адрес электронной почты" #~ msgid "Add an online account" #~ msgstr "Добавить сетевую учётную запись" #~ msgid "Address" #~ msgstr "Адрес" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "Вы действительно хотите удалить этот контакт?" #~ msgid "Call" #~ msgstr "Вызвать" #~ msgid "Calls" #~ msgstr "Вызовы" #~ msgid "Cancel" #~ msgstr "Отмена" #~ msgid "Communication" #~ msgstr "Связь" #~ msgid "Compose" #~ msgstr "Создать" #~ msgid "Contact Details" #~ msgstr "Контактная информация" #~ msgid "Contacts" #~ msgstr "Контакты" #~ msgid "Conversations" #~ msgstr "Диалоги" #~ msgid "Country" #~ msgstr "Страна" #~ msgid "DEF" #~ msgstr "DEF" #~ msgid "Delete" #~ msgstr "Удалить" #~ msgid "Delete Contact" #~ msgstr "Удалить контакт" #~ msgid "Dialing" #~ msgstr "Набор номера" #~ msgid "Duration %1" #~ msgstr "Длительность %1" #~ msgid "Edit" #~ msgstr "Изменить" #~ msgid "Email" #~ msgstr "Электронная почта" #~ msgid "Enter a number" #~ msgstr "Введите номер" #~ msgid "First" #~ msgstr "Первый" #~ msgid "GHI" #~ msgstr "GHI" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "Главная" #~ msgid "IM" #~ msgstr "IM" #~ msgid "JKL" #~ msgstr "JKL" #~ msgid "Last" #~ msgstr "Последний" #~ msgid "Locality" #~ msgstr "Местоположение" #~ msgid "MNO" #~ msgstr "MNO" #~ msgid "Messages" #~ msgstr "Сообщения" #~ msgid "Mobile" #~ msgstr "Мобильный" #~ msgid "New Contact" #~ msgstr "Новый контакт" #~ msgid "New Message" #~ msgstr "Новое сообщение" #~ msgid "Other" #~ msgstr "Прочее" #~ msgid "PQRS" #~ msgstr "PQRS" #~ msgid "Phone" #~ msgstr "Телефон" #~ msgid "Phone App" #~ msgstr "Телефон" #~ msgid "Postal Code" #~ msgstr "Почтовый индекс" #~ msgid "Prefix" #~ msgstr "Префикс" #~ msgid "Private number" #~ msgstr "Приватный номер" #~ msgid "Region" #~ msgstr "Регион" #~ msgid "Reply via SMS" #~ msgstr "Ответить по SMS" #~ msgid "Save" #~ msgstr "Сохранить" #~ msgid "Send" #~ msgstr "Отправить" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "Улица" #~ msgid "TUV" #~ msgstr "TUV" #~ msgid "To:" #~ msgstr "Кому:" #~ msgid "Today" #~ msgstr "Сегодня" #~ msgid "Unknown Contact" #~ msgstr "Неизвестный контакт" #~ msgid "Unknown number" #~ msgstr "Неизвестный номер" #~ msgid "Voicemail" #~ msgstr "Голосовая почта" #~ msgid "WXYZ" #~ msgstr "WXYZ" #~ msgid "Work" #~ msgstr "Рабочий" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "Вчера" #~ msgid "missed call" #~ msgstr "пропущенный вызов" telephony-service-0.1+14.04.20140415/po/he.po0000644000015301777760000001630512323307402020770 0ustar pbusernogroup00000000000000# Hebrew translation for telephony-service # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-22 17:59-0300\n" "PO-Revision-Date: 2013-06-13 09:42+0000\n" "Last-Translator: Yaron \n" "Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Launchpad-Export-Date: 2013-07-11 06:26+0000\n" "X-Generator: Launchpad (build 16696)\n" #: indicator/messagingmenu.cpp:166 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "שיחה %1 שלא נענתה" msgstr[1] "%1 שיחות שלא נענו" #: indicator/messagingmenu.cpp:253 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "הודעה %1 בתא הקולי" msgstr[1] "%1 הודעות בתא הקולי" #: approver/approver.cpp:241 msgid "Accept" msgstr "קבלה" #: approver/approver.cpp:226 msgid "Caller number is not available" msgstr "מספר המען אינו זמין" #: approver/approver.cpp:223 #, qt-format msgid "Calling from %1" msgstr "שיחה מ%1" #: approver/approver.cpp:219 msgid "Calling from private number" msgstr "שיחה ממספר פרטי" #: approver/approver.cpp:221 msgid "Calling from unknown number" msgstr "שיחה ממספר לא ידוע" #: approver/approver.cpp:247 msgid "Decline" msgstr "דחיה" #: indicator/messagingmenu.cpp:210 msgid "I missed your call - can you call me now?" msgstr "פספסתי את שיחתך - אפשר להתקשר אלי בחזרה?" #: indicator/messagingmenu.cpp:213 msgid "I'll be 20 minutes late." msgstr "אאחר ב־20 דקות." #: indicator/messagingmenu.cpp:212 msgid "I'm busy at the moment. I'll call you later." msgstr "אין לי אפשרות לענות כרגע. אתקשר מאוחר יותר." #: indicator/messagingmenu.cpp:211 msgid "I'm running late. I'm on my way." msgstr "אאחר. אני בדרך." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "שיחות טלפון" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:83 #, qt-format msgid "SMS from %1" msgstr "SMS מאת %1" #: indicator/messagingmenu.cpp:214 msgid "Sorry, I'm still busy. I'll call you later." msgstr "עדיין עסוק. אתקשר מאוחר יותר. סליחה." #: indicator/messagingmenu.cpp:52 indicator/messagingmenu.cpp:56 msgid "Telephony Service" msgstr "" #: approver/main.cpp:45 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:47 msgid "Telephony Service Indicator" msgstr "" #: approver/approver.cpp:213 msgid "Unknown caller" msgstr "מתקשר לא ידוע" #: indicator/messagingmenu.cpp:251 msgid "Voicemail messages" msgstr "הודעות בתא הקולי" #~ msgid "Handles incoming messages, calls and indicators" #~ msgstr "טיפול בהודעות נכנסות, בשיחות ובהתרעות" #~ msgid "Phone App Approver" #~ msgstr "מאשר יישום הטלפון" #~ msgid "#" #~ msgstr "מס׳" #~ msgid "%1 hour call" #~ msgid_plural "%1 hours call" #~ msgstr[0] "שיחה של שעה %1" #~ msgstr[1] "שיחה של %1 שעות" #~ msgid "%1 minute call" #~ msgid_plural "%1 minutes call" #~ msgstr[0] "שיחה של דקה %1" #~ msgstr[1] "שיחה של %1 דקות" #~ msgid "%1 second call" #~ msgid_plural "%1 seconds call" #~ msgstr[0] "שיחה של שנייה %1" #~ msgstr[1] "שיחה של %1 שניות" #~ msgid "*" #~ msgstr "*" #~ msgid "+" #~ msgstr "+" #~ msgid "0" #~ msgstr "0" #~ msgid "1" #~ msgstr "1" #~ msgid "2" #~ msgstr "2" #~ msgid "3" #~ msgstr "3" #~ msgid "4" #~ msgstr "4" #~ msgid "5" #~ msgstr "5" #~ msgid "6" #~ msgstr "6" #~ msgid "7" #~ msgstr "7" #~ msgid "8" #~ msgstr "8" #~ msgid "9" #~ msgstr "9" #~ msgid "ABC" #~ msgstr "אבג" #~ msgid "Add" #~ msgstr "הוספה" #~ msgid "Add a phone number" #~ msgstr "הוספת מספר טלפון" #~ msgid "Add a postal address" #~ msgstr "הוספת מען למכתבים" #~ msgid "Add an email address" #~ msgstr "הוספת כתובת דוא״ל" #~ msgid "Add an online account" #~ msgstr "הוספת חשבון מקוון" #~ msgid "Address" #~ msgstr "כתובת" #~ msgid "Are you sure you want to delete this contact?" #~ msgstr "האם אכן למחוק את איש הקשר?" #~ msgid "Call" #~ msgstr "להתקשר" #~ msgid "Calls" #~ msgstr "שיחות" #~ msgid "Cancel" #~ msgstr "ביטול" #~ msgid "Communication" #~ msgstr "תקשורת" #~ msgid "Compose" #~ msgstr "כתיבה" #~ msgid "Contact Details" #~ msgstr "פרטי איש קשר" #~ msgid "Contacts" #~ msgstr "אנשי קשר" #~ msgid "Conversations" #~ msgstr "דיונים" #~ msgid "Country" #~ msgstr "מדינה" #~ msgid "DEF" #~ msgstr "אבג" #~ msgid "Delete" #~ msgstr "מחיקה" #~ msgid "Delete Contact" #~ msgstr "מחיקת איש הקשר" #~ msgid "Dialing" #~ msgstr "בחיוג" #~ msgid "Duration %1" #~ msgstr "משך %1" #~ msgid "Edit" #~ msgstr "עריכה" #~ msgid "Email" #~ msgstr "דוא״ל" #~ msgid "Enter a number" #~ msgstr "נא להזין מספר" #~ msgid "First" #~ msgstr "ראשון" #~ msgid "GHI" #~ msgstr "מםנן" #~ msgid "Google Talk" #~ msgstr "Google Talk" #~ msgid "Home" #~ msgstr "בית" #~ msgid "IM" #~ msgstr "הודעה מיידית" #~ msgid "JKL" #~ msgstr "יכךל" #~ msgid "Last" #~ msgstr "אחרון" #~ msgid "Locality" #~ msgstr "מיקום" #~ msgid "MNO" #~ msgstr "זחט" #~ msgid "Messages" #~ msgstr "הודעות" #~ msgid "Middle" #~ msgstr "אמצע" #~ msgid "Mobile" #~ msgstr "נייד" #~ msgid "New Contact" #~ msgstr "איש קשר חדש" #~ msgid "New Message" #~ msgstr "הודעה חדשה" #~ msgid "On Call" #~ msgstr "בשיחה" #~ msgid "Other" #~ msgstr "אחר" #~ msgid "PQRS" #~ msgstr "רשת" #~ msgid "Phone" #~ msgstr "טלפון" #~ msgid "Phone App" #~ msgstr "יישום טלפון" #~ msgid "Phone application" #~ msgstr "יישום טלפון" #~ msgid "Postal Code" #~ msgstr "מיקוד" #~ msgid "Prefix" #~ msgstr "קידומת" #~ msgid "Private number" #~ msgstr "מספר פרטי" #~ msgid "Region" #~ msgstr "אזור" #~ msgid "Reply via SMS" #~ msgstr "תגובה ב־SMS" #~ msgid "Save" #~ msgstr "שמירה" #~ msgid "Send" #~ msgstr "שליחה" #~ msgid "Skype" #~ msgstr "Skype" #~ msgid "Street" #~ msgstr "רחוב" #~ msgid "Suffix" #~ msgstr "סיומת" #~ msgid "Swap Calls" #~ msgstr "החלפת שיחות" #~ msgid "TUV" #~ msgstr "צץק" #~ msgid "To:" #~ msgstr "אל:" #~ msgid "Today" #~ msgstr "היום" #~ msgid "Unknown Contact" #~ msgstr "איש קשר לא ידוע" #~ msgid "Unknown number" #~ msgstr "מספר לא ידוע" #~ msgid "Voicemail" #~ msgstr "תא קולי" #~ msgid "WXYZ" #~ msgstr "סעפף" #~ msgid "Work" #~ msgstr "עבודה" #~ msgid "Yahoo" #~ msgstr "Yahoo" #~ msgid "Yesterday" #~ msgstr "אתמול" #~ msgid "missed call" #~ msgstr "שיחה שלא נענתה" telephony-service-0.1+14.04.20140415/TODO0000644000015301777760000000123212323307402020077 0ustar pbusernogroup00000000000000General items - Formatting of phone numbers - Check how to import/export potfiles from the ts one Contact integration items: - Fix contact search when names contain accentuated characters Qt5 porting pendencies: - The count overlay on tabs needs to be reimplemented. - ModelSectionCounter is not working, needs investigation. - Check for code on tests that was disabled in the porting to Qt5 - Check how to test QContactId stuff Sharing code between the approver and the QML plugin: - the TelepathyHelper class needs to be adapted to be able to be used in both places - Change the ChannelObserver and the ChannelApprover code to allow using from both places. telephony-service-0.1+14.04.20140415/handler/0000755000015301777760000000000012323310021021015 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/handler/TelephonyServiceHandler.client0000644000015301777760000000071612323307402027020 0ustar pbusernogroup00000000000000[org.freedesktop.Telepathy.Client] Interfaces=org.freedesktop.Telepathy.Client.Handler; [org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=1 [org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 1] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Call1 telephony-service-0.1+14.04.20140415/handler/callhandler.cpp0000644000015301777760000002646712323307402024022 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "callhandler.h" #include "phoneutils.h" #include "telepathyhelper.h" #include #include #define TELEPATHY_MUTE_IFACE "org.freedesktop.Telepathy.Call1.Interface.Mute" #define DBUS_PROPERTIES_IFACE "org.freedesktop.DBus.Properties" #define PROPERTY_SPEAKERMODE "SpeakerMode" typedef QMap dbusQMap; Q_DECLARE_METATYPE(dbusQMap) CallHandler *CallHandler::instance() { static CallHandler *self = new CallHandler(); return self; } QVariantMap CallHandler::getCallProperties(const QString &objectPath) { QVariantMap properties; Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (!channel) { return properties; } QVariant property = channel->property("timestamp"); if (property.isValid()) { properties["timestamp"] = property; } property = channel->property("activeTimestamp"); if (property.isValid()) { properties["activeTimestamp"] = property; } property = channel->property("dtmfString"); if (property.isValid()) { properties["dtmfString"] = property; } return properties; } bool CallHandler::hasCalls() const { bool hasActiveCalls = false; Q_FOREACH(const Tp::CallChannelPtr channel, mCallChannels) { Tp::AccountPtr account = TelepathyHelper::instance()->accountForConnection(channel->connection()); bool incoming = channel->initiatorContact() != account->connection()->selfContact(); bool dialing = !incoming && (channel->callState() == Tp::CallStateInitialised); bool active = channel->callState() == Tp::CallStateActive; if (dialing || active) { hasActiveCalls = true; break; } } return hasActiveCalls; } CallHandler::CallHandler(QObject *parent) : QObject(parent) { } void CallHandler::startCall(const QString &phoneNumber, const QString &accountId) { // Request the contact to start audio call Tp::AccountPtr account = TelepathyHelper::instance()->accountForId(accountId); if (!account || account->connection() == NULL) { return; } connect(account->connection()->contactManager()->contactsForIdentifiers(QStringList() << phoneNumber), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactsAvailable(Tp::PendingOperation*))); } void CallHandler::hangUpCall(const QString &objectPath) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (channel.isNull()) { return; } Tp::PendingOperation *pending = channel->hangup(); mClosingChannels[pending] = channel; connect(pending, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onCallHangupFinished(Tp::PendingOperation*))); } void CallHandler::setHold(const QString &objectPath, bool hold) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (channel.isNull()) { return; } channel->requestHold(hold); } void CallHandler::setMuted(const QString &objectPath, bool muted) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (channel.isNull()) { return; } // FIXME: replace by a proper TpQt implementation of mute QDBusInterface muteInterface(channel->busName(), channel->objectPath(), TELEPATHY_MUTE_IFACE); muteInterface.call("RequestMuted", muted); } void CallHandler::setSpeakerMode(const QString &objectPath, bool enabled) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (channel.isNull() || !channel->property("hasSpeakerProperty").toBool()) { return; } QDBusInterface speakerInterface(channel->busName(), channel->objectPath(), CANONICAL_TELEPHONY_SPEAKER_IFACE); speakerInterface.call("turnOnSpeaker", enabled); } void CallHandler::sendDTMF(const QString &objectPath, const QString &key) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (channel.isNull()) { return; } // save the dtmfString to send to clients that request it QString dtmfString = channel->property("dtmfString").toString(); dtmfString += key; channel->setProperty("dtmfString", dtmfString); Q_FOREACH(const Tp::CallContentPtr &content, channel->contents()) { if (content->supportsDTMF()) { bool ok; Tp::DTMFEvent event = (Tp::DTMFEvent)key.toInt(&ok); if (!ok) { if (!key.compare("*")) { event = Tp::DTMFEventAsterisk; } else if (!key.compare("#")) { event = Tp::DTMFEventHash; } else { qWarning() << "Tone not recognized. DTMF failed"; return; } } content->startDTMFTone(event); } } Q_EMIT callPropertiesChanged(channel->objectPath(), getCallProperties(channel->objectPath())); } void CallHandler::createConferenceCall(const QStringList &objectPaths) { QList calls; Tp::AccountPtr account; Q_FOREACH(const QString &objectPath, objectPaths) { Tp::CallChannelPtr call = callFromObjectPath(objectPath); if (!call) { qWarning() << "Could not find a call channel for objectPath:" << objectPath; return; } if (account.isNull()) { account = TelepathyHelper::instance()->accountForConnection(call->connection()); } // make sure all call channels belong to the same connection if (call->connection() != account->connection()) { qWarning() << "It is not possible to merge channels from different accounts."; return; } calls.append(call); } if (calls.isEmpty() || account.isNull()) { qWarning() << "The list of calls was empty. Failed to create a conference."; return; } // there is no need to check the pending request. The new channel will arrive at some point. account->createConferenceCall(calls, QStringList(), QDateTime::currentDateTime(), TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler"); } void CallHandler::mergeCall(const QString &conferenceObjectPath, const QString &callObjectPath) { Tp::CallChannelPtr conferenceChannel = callFromObjectPath(conferenceObjectPath); Tp::CallChannelPtr callChannel = callFromObjectPath(callObjectPath); if (!conferenceChannel || !callChannel || !conferenceChannel->isConference()) { qWarning() << "No valid channels found."; return; } // there is no need to check for the result here. conferenceChannel->conferenceMergeChannel(callChannel); } void CallHandler::splitCall(const QString &objectPath) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); if (!channel) { return; } // we don't need to check the result of the operation here channel->conferenceSplitChannel(); } void CallHandler::onCallChannelAvailable(Tp::CallChannelPtr channel) { channel->accept(); // check if the channel has the speakermode property QDBusInterface callChannelIface(channel->busName(), channel->objectPath(), DBUS_PROPERTIES_IFACE); QDBusMessage reply = callChannelIface.call("GetAll", CANONICAL_TELEPHONY_SPEAKER_IFACE); QVariantList args = reply.arguments(); QMap map = qdbus_cast >(args[0]); channel->setProperty("hasSpeakerProperty", map.contains(PROPERTY_SPEAKERMODE)); channel->setProperty("timestamp", QDateTime::currentDateTimeUtc()); if (channel->callState() == Tp::CallStateActive) { channel->setProperty("activeTimestamp", QDateTime::currentDateTimeUtc()); } connect(channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)), SLOT(onCallChannelInvalidated())); connect(channel.data(), SIGNAL(callStateChanged(Tp::CallState)), SLOT(onCallStateChanged(Tp::CallState))); mCallChannels.append(channel); Q_EMIT callPropertiesChanged(channel->objectPath(), getCallProperties(channel->objectPath())); } void CallHandler::onContactsAvailable(Tp::PendingOperation *op) { Tp::PendingContacts *pc = qobject_cast(op); if (!pc) { qCritical() << "The pending object is not a Tp::PendingContacts"; return; } Tp::AccountPtr account = TelepathyHelper::instance()->accountForConnection(pc->manager()->connection()); // start call to the contacts Q_FOREACH(Tp::ContactPtr contact, pc->contacts()) { account->ensureAudioCall(contact, QLatin1String("audio"), QDateTime::currentDateTime(), TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler"); // hold the ContactPtr to make sure its refcounting stays bigger than 0 mContacts[contact->id()] = contact; } } void CallHandler::onCallHangupFinished(Tp::PendingOperation *op) { if (!mClosingChannels.contains(op)) { qCritical() << "Channel for pending hangup not found:" << op; return; } // Do NOT request the channel closing at this point. It will get closed automatically. // if you request it to be closed, the CallStateEnded will never be reached and the UI // and logging will be broken. Tp::CallChannelPtr channel = mClosingChannels.take(op); mCallChannels.removeAll(channel); } void CallHandler::onCallChannelInvalidated() { Tp::CallChannelPtr channel(qobject_cast(sender())); if (channel.isNull()) { return; } mCallChannels.removeAll(channel); } void CallHandler::onCallStateChanged(Tp::CallState state) { Tp::CallChannelPtr channel(qobject_cast(sender())); if (!channel) { return; } switch (state) { case Tp::CallStateActive: channel->setProperty("activeTimestamp", QDateTime::currentDateTimeUtc()); Q_EMIT callPropertiesChanged(channel->objectPath(), getCallProperties(channel->objectPath())); break; } } Tp::CallChannelPtr CallHandler::existingCall(const QString &phoneNumber) { Tp::CallChannelPtr channel; Q_FOREACH(const Tp::CallChannelPtr &ch, mCallChannels) { if (ch->isConference()) { continue; } if (PhoneUtils::comparePhoneNumbers(ch->targetContact()->id(), phoneNumber)) { channel = ch; break; } } return channel; } Tp::CallChannelPtr CallHandler::callFromObjectPath(const QString &objectPath) { Tp::CallChannelPtr channel; Q_FOREACH(const Tp::CallChannelPtr &ch, mCallChannels) { if (ch->objectPath() == objectPath) { channel = ch; break; } } return channel; } telephony-service-0.1+14.04.20140415/handler/handlerdbus.cpp0000644000015301777760000000714412323307402024033 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Ugo Riboni * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "callhandler.h" #include "handlerdbus.h" #include "handleradaptor.h" #include "texthandler.h" #include "telepathyhelper.h" // Qt #include static const char* DBUS_SERVICE = "com.canonical.TelephonyServiceHandler"; static const char* DBUS_OBJECT_PATH = "/com/canonical/TelephonyServiceHandler"; HandlerDBus::HandlerDBus(QObject* parent) : QObject(parent) { connect(CallHandler::instance(), SIGNAL(callPropertiesChanged(QString,QVariantMap)), SIGNAL(CallPropertiesChanged(QString,QVariantMap))); } HandlerDBus::~HandlerDBus() { } QVariantMap HandlerDBus::GetCallProperties(const QString &objectPath) { return CallHandler::instance()->getCallProperties(objectPath); } bool HandlerDBus::HasCalls() { return CallHandler::instance()->hasCalls(); } QStringList HandlerDBus::AccountIds() { return TelepathyHelper::instance()->accountIds(); } bool HandlerDBus::connectToBus() { bool ok = QDBusConnection::sessionBus().registerService(DBUS_SERVICE); if (!ok) { return false; } new TelephonyServiceHandlerAdaptor(this); QDBusConnection::sessionBus().registerObject(DBUS_OBJECT_PATH, this); return true; } void HandlerDBus::SendMessage(const QStringList &numbers, const QString &message, const QString &accountId) { TextHandler::instance()->sendMessage(numbers, message, accountId); } void HandlerDBus::AcknowledgeMessages(const QStringList &numbers, const QStringList &messageIds, const QString &accountId) { TextHandler::instance()->acknowledgeMessages(numbers, messageIds, accountId); } void HandlerDBus::StartCall(const QString &number, const QString &accountId) { CallHandler::instance()->startCall(number, accountId); } void HandlerDBus::HangUpCall(const QString &objectPath) { CallHandler::instance()->hangUpCall(objectPath); } void HandlerDBus::SetHold(const QString &objectPath, bool hold) { CallHandler::instance()->setHold(objectPath, hold); } void HandlerDBus::SetMuted(const QString &objectPath, bool muted) { CallHandler::instance()->setMuted(objectPath, muted); } void HandlerDBus::SetSpeakerMode(const QString &objectPath, bool enabled) { CallHandler::instance()->setSpeakerMode(objectPath, enabled); } void HandlerDBus::SendDTMF(const QString &objectPath, const QString &key) { CallHandler::instance()->sendDTMF(objectPath, key); } void HandlerDBus::CreateConferenceCall(const QStringList &objectPaths) { CallHandler::instance()->createConferenceCall(objectPaths); } void HandlerDBus::MergeCall(const QString &conferenceObjectPath, const QString &callObjectPath) { CallHandler::instance()->mergeCall(conferenceObjectPath, callObjectPath); } void HandlerDBus::SplitCall(const QString &objectPath) { CallHandler::instance()->splitCall(objectPath); } telephony-service-0.1+14.04.20140415/handler/tests/0000755000015301777760000000000012323310021022157 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/handler/tests/approver.h0000644000015301777760000000367412323307402024211 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann */ #ifndef APPROVER_H #define APPROVER_H #include #include #include #include #define TELEPHONY_SERVICE_HANDLER TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler" #define TELEPHONY_SERVICE_APPROVER TP_QT_IFACE_CLIENT + ".TelephonyTestApprover" class Approver : public QObject, public Tp::AbstractClientApprover { Q_OBJECT public: Approver(QObject *parent = 0); ~Approver(); Tp::ChannelClassSpecList channelFilters() const; void addDispatchOperation(const Tp::MethodInvocationContextPtr<> &context, const Tp::ChannelDispatchOperationPtr &dispatchOperation); Q_SIGNALS: void newCall(); public Q_SLOTS: void acceptCall(); void rejectCall(); private Q_SLOTS: void processChannels(); void onClaimFinished(Tp::PendingOperation* op); void onHangupFinished(Tp::PendingOperation* op); void onChannelReady(Tp::PendingOperation *op); protected: Tp::ChannelDispatchOperationPtr dispatchOperation(Tp::PendingOperation *op); private: QList mDispatchOps; QMap mChannels; }; #endif // APPROVER_H telephony-service-0.1+14.04.20140415/handler/tests/mock/0000755000015301777760000000000012323310021023110 5ustar pbusernogroup00000000000000telephony-service-0.1+14.04.20140415/handler/tests/mock/callchannel.cpp0000644000015301777760000002000212323307402026063 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #include "callchannel.h" MockCallChannel::MockCallChannel(MockConnection *conn, QString phoneNumber, QString state, uint targetHandle, QObject *parent): QObject(parent), mIncoming(false), mRequestedHangup(false), mConnection(conn), mPhoneNumber(phoneNumber), mTargetHandle(targetHandle), mState(state) { Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_CALL, targetHandle, Tp::HandleTypeContact); Tp::BaseChannelCallTypePtr callType = Tp::BaseChannelCallType::create(baseChannel.data(), true, Tp::StreamTransportTypeUnknown, true, false, "",""); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType)); mHoldIface = Tp::BaseChannelHoldInterface::create(); mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&MockCallChannel::onHoldStateChanged)); mMuteIface = Tp::BaseCallMuteInterface::create(); mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&MockCallChannel::onMuteStateChanged)); mSplittableIface = Tp::BaseChannelSplittableInterface::create(); mSplittableIface->setSplitCallback(Tp::memFun(this,&MockCallChannel::onSplit)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mHoldIface)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMuteIface)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mSplittableIface)); mBaseChannel = baseChannel; mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL)); mCallChannel->setHangupCallback(Tp::memFun(this,&MockCallChannel::onHangup)); mCallChannel->setAcceptCallback(Tp::memFun(this,&MockCallChannel::onAccept)); // init must be called after initialization, otherwise we will have no object path registered. QTimer::singleShot(0, this, SLOT(init())); } void MockCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error) { // TODO: use the parameters sent by telepathy mRequestedHangup = true; setCallState("disconnected"); } void MockCallChannel::onAccept(Tp::DBusError*) { setCallState("active"); } void MockCallChannel::init() { Tp::CallMemberMap memberFlags; Tp::HandleIdentifierMap identifiers; QVariantMap stateDetails; Tp::CallStateReason reason; mIncoming = mState == "incoming" || mState == "waiting"; identifiers[mTargetHandle] = mPhoneNumber; reason.actor = 0; reason.reason = Tp::CallStateChangeReasonProgressMade; reason.message = ""; reason.DBusReason = ""; if (mIncoming) { memberFlags[mTargetHandle] = 0; } else { memberFlags[mTargetHandle] = Tp::CallMemberFlagRinging; } mCallChannel->setCallState(Tp::CallStateInitialising, 0, reason, stateDetails); mCallContent = Tp::BaseCallContent::create(baseChannel()->dbusConnection(), baseChannel().data(), "audio", Tp::MediaStreamTypeAudio, Tp::MediaStreamDirectionNone); mDTMFIface = Tp::BaseCallContentDTMFInterface::create(); mCallContent->plugInterface(Tp::AbstractCallContentInterfacePtr::dynamicCast(mDTMFIface)); mCallChannel->addContent(mCallContent); mDTMFIface->setStartToneCallback(Tp::memFun(this,&MockCallChannel::onDTMFStartTone)); mDTMFIface->setStopToneCallback(Tp::memFun(this,&MockCallChannel::onDTMFStopTone)); mCallChannel->setMembersFlags(memberFlags, identifiers, Tp::UIntList(), reason); mCallChannel->setCallState(Tp::CallStateInitialised, 0, reason, stateDetails); QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater())); } void MockCallChannel::onOfonoMuteChanged(bool mute) { Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted; mMuteIface->setMuteState(state); } void MockCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error) { if (state == Tp::LocalHoldStateHeld && mState == "active") { setCallState("held"); } else if (state == Tp::LocalHoldStateUnheld && mState == "held") { setCallState("active"); } } void MockCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error) { #if 0 FIXME: reimplement if (state == Tp::LocalMuteStateMuted) { mConnection->callVolume()->setMuted(true); } else if (state == Tp::LocalMuteStateUnmuted) { mConnection->callVolume()->setMuted(false); } #endif } void MockCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error) { QString finalString; if (event == 10) { finalString = "*"; } else if (event == 11) { finalString = "#"; } else { finalString = QString::number(event); } qDebug() << "start tone" << finalString; } void MockCallChannel::onDTMFStopTone(Tp::DBusError *error) { } void MockCallChannel::onSplit(Tp::DBusError *error) { Q_EMIT splitted(); } QString MockCallChannel::objectPath() const { return mBaseChannel->objectPath(); } Tp::CallState MockCallChannel::callState() const { return (Tp::CallState) mCallChannel->callState(); } MockCallChannel::~MockCallChannel() { qDebug() << "call channel closed"; // TODO - for some reason the object is not being removed mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree); } Tp::BaseChannelPtr MockCallChannel::baseChannel() { return mBaseChannel; } void MockCallChannel::setCallState(const QString &state) { Tp::CallStateReason reason; QVariantMap stateDetails; reason.actor = 0; reason.reason = Tp::CallStateChangeReasonUserRequested; reason.message = ""; reason.DBusReason = ""; if (state == "disconnected") { qDebug() << "disconnected"; if (mIncoming && mState == "incoming" && !mRequestedHangup) { reason.reason = Tp::CallStateChangeReasonNoAnswer; } mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails); mBaseChannel->close(); } else if (state == "active") { qDebug() << "active"; mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone); if (mState == "dialing" || mState == "alerting" || mState == "incoming") { mCallChannel->setCallState(Tp::CallStateAccepted, 0, reason, stateDetails); } mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails); } else if (state == "held") { mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonNone); qDebug() << "held"; } else if (state == "dialing") { qDebug() << "dialing"; } else if (state == "alerting") { qDebug() << "alerting"; } else if (state == "incoming") { mIncoming = true; qDebug() << "incoming"; } else if (state == "waiting") { mIncoming = true; qDebug() << "waiting"; } mState = state; Q_EMIT callStateChanged(this, state); } telephony-service-0.1+14.04.20140415/handler/tests/mock/dbustypes.h0000644000015301777760000000227512323307402025322 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann */ #ifndef DBUSTYPES #define DBUSTYPES struct MessageStruct { QDBusObjectPath path; QVariantMap properties; }; struct AttachmentStruct { QString id; QString contentType; QString filePath; quint64 offset; quint64 length; }; typedef QList AttachmentList; Q_DECLARE_METATYPE(AttachmentStruct) Q_DECLARE_METATYPE(AttachmentList) typedef QList MessageList; Q_DECLARE_METATYPE(MessageStruct) Q_DECLARE_METATYPE(MessageList) #endif telephony-service-0.1+14.04.20140415/handler/tests/mock/speakeriface.h0000644000015301777760000000746612323307402025731 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Tiago Salem Herrmann */ #ifndef OFONOSPEAKERIFACE_H #define OFONOSPEAKERIFACE_H // telepathy-qt #include #include #include #include #include #define TP_QT_IFACE_CHANNEL_SPEAKER "com.canonical.Telephony.Speaker" class BaseChannelSpeakerInterface; typedef Tp::SharedPtr BaseChannelSpeakerInterfacePtr; class TP_QT_EXPORT BaseChannelSpeakerInterface : public Tp::AbstractChannelInterface { Q_OBJECT Q_DISABLE_COPY(BaseChannelSpeakerInterface) public: static BaseChannelSpeakerInterfacePtr create() { return BaseChannelSpeakerInterfacePtr(new BaseChannelSpeakerInterface()); } template static Tp::SharedPtr create() { return Tp::SharedPtr( new BaseChannelSpeakerInterfaceSubclass()); } QVariantMap immutableProperties() const; virtual ~BaseChannelSpeakerInterface(); bool speakerMode() const; typedef Tp::Callback2 turnOnSpeakerCallback; void setTurnOnSpeakerCallback(const turnOnSpeakerCallback &cb); public Q_SLOTS: void setSpeakerMode(bool active); protected: BaseChannelSpeakerInterface(); private: void createAdaptor(); class Adaptee; friend class Adaptee; struct Private; friend struct Private; Private *mPriv; }; class TP_QT_EXPORT ChannelInterfaceSpeakerAdaptor : public Tp::AbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CHANNEL_SPEAKER) Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") Q_PROPERTY(bool SpeakerMode READ SpeakerMode) public: ChannelInterfaceSpeakerAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent); virtual ~ChannelInterfaceSpeakerAdaptor(); typedef Tp::MethodInvocationContextPtr< bool > turnOnSpeakerContextPtr; public: // PROPERTIES bool SpeakerMode() const; public Q_SLOTS: // METHODS void turnOnSpeaker(bool active, const QDBusMessage& dbusMessage); Q_SIGNALS: // SIGNALS void SpeakerChanged(bool active); }; class TP_QT_NO_EXPORT BaseChannelSpeakerInterface::Adaptee : public QObject { Q_OBJECT Q_PROPERTY(bool speakerMode READ speakerMode) public: Adaptee(BaseChannelSpeakerInterface *interface); ~Adaptee(); bool speakerMode() const { return mInterface->speakerMode(); } private Q_SLOTS: void turnOnSpeaker(bool active, const ChannelInterfaceSpeakerAdaptor::turnOnSpeakerContextPtr &context); Q_SIGNALS: void speakerChanged(bool active); public: BaseChannelSpeakerInterface *mInterface; }; #endif telephony-service-0.1+14.04.20140415/handler/tests/mock/mockconnectiondbus.cpp0000644000015301777760000000542112323307402027516 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of history-service. * * history-service 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; version 3. * * history-service 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, see . */ #include "connection.h" #include "mockconnectiondbus.h" #include "mockconnectionadaptor.h" Q_DECLARE_METATYPE(QList< QVariantMap >) MockConnectionDBus::MockConnectionDBus(MockConnection *parent) : QObject(parent), mAdaptor(0), mConnection(parent) { connect(mConnection, SIGNAL(messageSent(QString,QVariantMap)), SIGNAL(MessageSent(QString,QVariantMap))); connect(mConnection, SIGNAL(callReceived(QString)), SIGNAL(CallReceived(QString))); connect(mConnection, SIGNAL(callEnded(QString)), SIGNAL(CallEnded(QString))); connect(mConnection, SIGNAL(callStateChanged(QString,QString,QString)), SIGNAL(CallStateChanged(QString,QString,QString))); connect(mConnection, SIGNAL(conferenceCreated(QString)), SIGNAL(ConferenceCreated(QString))); connect(mConnection, SIGNAL(channelMerged(QString)), SIGNAL(ChannelMerged(QString))); connect(mConnection, SIGNAL(channelSplitted(QString)), SIGNAL(ChannelSplitted(QString))); qDBusRegisterMetaType >(); connectToBus(); } bool MockConnectionDBus::connectToBus() { bool ok = QDBusConnection::sessionBus().registerService("com.canonical.MockConnection"); if (!ok) { return false; } if (!mAdaptor) { mAdaptor = new MockConnectionAdaptor(this); } return QDBusConnection::sessionBus().registerObject("/com/canonical/MockConnection", this); } void MockConnectionDBus::PlaceIncomingMessage(const QString &message, const QVariantMap &properties) { mConnection->placeIncomingMessage(message, properties); } QString MockConnectionDBus::PlaceCall(const QVariantMap &properties) { return mConnection->placeCall(properties); } void MockConnectionDBus::HangupCall(const QString &callerId) { mConnection->hangupCall(callerId); } void MockConnectionDBus::SetCallState(const QString &phoneNumber, const QString &state) { mConnection->setCallState(phoneNumber, state); } telephony-service-0.1+14.04.20140415/handler/tests/mock/conferencecallchannel.cpp0000644000015301777760000002365212323307402030131 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #include "conferencecallchannel.h" #include "callchannel.h" MockConferenceCallChannel::MockConferenceCallChannel(MockConnection *conn, QList callChannels, QObject *parent): mRequestedHangup(false), mConnection(conn), mDtmfLock(false), mCallChannels(callChannels) { Q_FOREACH(MockCallChannel *channel, mConnection->callChannels().values()) { if (channel->callState() == Tp::CallStateActive) { QDBusObjectPath path(channel->baseChannel()->objectPath()); mCallChannels << path; } } Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_CALL, 0, Tp::HandleTypeNone); Tp::BaseChannelCallTypePtr callType = Tp::BaseChannelCallType::create(baseChannel.data(), true, Tp::StreamTransportTypeUnknown, true, false, "",""); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType)); mHoldIface = Tp::BaseChannelHoldInterface::create(); mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&MockConferenceCallChannel::onHoldStateChanged)); mMuteIface = Tp::BaseCallMuteInterface::create(); mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&MockConferenceCallChannel::onMuteStateChanged)); mSpeakerIface = BaseChannelSpeakerInterface::create(); mSpeakerIface->setTurnOnSpeakerCallback(Tp::memFun(this,&MockConferenceCallChannel::onTurnOnSpeaker)); mConferenceIface = Tp::BaseChannelConferenceInterface::create(mCallChannels); mMergeableIface = Tp::BaseChannelMergeableConferenceInterface::create(); mMergeableIface->setMergeCallback(Tp::memFun(this,&MockConferenceCallChannel::onMerge)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mHoldIface)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMuteIface)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mSpeakerIface)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mConferenceIface)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMergeableIface)); mBaseChannel = baseChannel; mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL)); mCallChannel->setHangupCallback(Tp::memFun(this,&MockConferenceCallChannel::onHangup)); Tp::CallStateReason reason; QVariantMap stateDetails; reason.actor = 0; reason.reason = Tp::CallStateChangeReasonUserRequested; reason.message = ""; reason.DBusReason = ""; mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails); QObject::connect(mConnection, SIGNAL(channelSplitted(QDBusObjectPath)), SLOT(onChannelSplitted(QDBusObjectPath))); // init must be called after initialization, otherwise we will have no object path registered. QTimer::singleShot(0, this, SLOT(init())); } Tp::BaseChannelPtr MockConferenceCallChannel::baseChannel() { return mBaseChannel; } void MockConferenceCallChannel::onMerge(const QDBusObjectPath &channel, Tp::DBusError *error) { if (!mCallChannels.contains(channel)) { mCallChannels << channel; mConferenceIface->mergeChannel(channel, 0, QVariantMap()); Q_EMIT channelMerged(channel.path()); } } void MockConferenceCallChannel::onChannelSplitted(const QDBusObjectPath &path) { if (mCallChannels.contains(path)) { mCallChannels.removeAll(path); mConferenceIface->removeChannel(path, QVariantMap()); } if (mCallChannels.size() == 1) { // remove the call channel from the conference before closing it. mConferenceIface->removeChannel(mCallChannels.takeFirst(), QVariantMap()); Tp::CallStateReason reason; QVariantMap stateDetails; reason.actor = 0; reason.reason = Tp::CallStateChangeReasonUserRequested; reason.message = ""; reason.DBusReason = ""; mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails); mBaseChannel->close(); } } void MockConferenceCallChannel::onTurnOnSpeaker(bool active, Tp::DBusError *error) { //mConnection->setSpeakerMode(active); // FIXME: reimplement } void MockConferenceCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error) { //FIXME: reimplement Tp::CallStateReason theReason; QVariantMap stateDetails; theReason.actor = 0; theReason.reason = reason; theReason.message = message; theReason.DBusReason = ""; mCallChannel->setCallState(Tp::CallStateEnded, 0, theReason, stateDetails); mBaseChannel->close(); } void MockConferenceCallChannel::init() { QVariantMap stateDetails; Tp::CallStateReason reason; mObjPath = mBaseChannel->objectPath(); reason.actor = 0; reason.reason = Tp::CallStateChangeReasonProgressMade; reason.message = ""; reason.DBusReason = ""; mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails); mDTMFIface = Tp::BaseCallContentDTMFInterface::create(); mDTMFIface->setStartToneCallback(Tp::memFun(this,&MockConferenceCallChannel::onDTMFStartTone)); mDTMFIface->setStopToneCallback(Tp::memFun(this,&MockConferenceCallChannel::onDTMFStopTone)); QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater())); //QObject::connect(mConnection->callVolume(), SIGNAL(mutedChanged(bool)), SLOT(onOfonoMuteChanged(bool))); QObject::connect(mConnection, SIGNAL(speakerModeChanged(bool)), mSpeakerIface.data(), SLOT(setSpeakerMode(bool))); //QObject::connect(mConnection->voiceCallManager(), SIGNAL(sendTonesComplete(bool)), SLOT(onDtmfComplete(bool))); //mSpeakerIface->setSpeakerMode(mConnection->speakerMode()); QObject::connect(mConnection, SIGNAL(channelSplitted(const QDBusObjectPath&)), this, SLOT(onChannelSplitted(const QDBusObjectPath&))); QObject::connect(mConnection, SIGNAL(channelHangup(const QDBusObjectPath&)), this, SLOT(onChannelSplitted(const QDBusObjectPath&))); Q_EMIT initialized(); } void MockConferenceCallChannel::onOfonoMuteChanged(bool mute) { Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted; mMuteIface->setMuteState(state); } void MockConferenceCallChannel::setConferenceActive(bool active) { if (active) { mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone); } else { mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonNone); } } void MockConferenceCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error) { /*if (state == Tp::LocalHoldStateHeld && mHoldIface->getHoldState() == Tp::LocalHoldStateUnheld) { mConnection->voiceCallManager()->swapCalls(); } else if (state == Tp::LocalHoldStateUnheld && mHoldIface->getHoldState() == Tp::LocalHoldStateHeld) { mConnection->voiceCallManager()->swapCalls(); }*/ // FIXME: reimplement } void MockConferenceCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error) { /*if (state == Tp::LocalMuteStateMuted) { mConnection->callVolume()->setMuted(true); } else if (state == Tp::LocalMuteStateUnmuted) { mConnection->callVolume()->setMuted(false); }*/ // FIXME: reimplement } void MockConferenceCallChannel::sendNextDtmf() { /*if (mDtmfLock) { return; } if (!mDtmfPendingStrings.isEmpty()) { mDtmfLock = true; mConnection->voiceCallManager()->sendTones(mDtmfPendingStrings.front()); }*/ // FIXME: reimplement } void MockConferenceCallChannel::onDtmfComplete(bool success) { mDtmfLock = false; if (success) { mDtmfPendingStrings.removeFirst(); if (mDtmfPendingStrings.isEmpty()) { return; } sendNextDtmf(); } else { QTimer::singleShot(1000, this, SLOT(sendNextDtmf())); } } void MockConferenceCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error) { QString finalString; if (event == 10) { finalString = "*"; } else if (event == 11) { finalString = "#"; } else { finalString = QString::number(event); } qDebug() << "start tone" << finalString; // we can't append to the first item in the queue as it is being sent and // we dont know yet if it will succeed or not. if (mDtmfPendingStrings.count() > 1) { mDtmfPendingStrings[1] += finalString; } else { mDtmfPendingStrings << finalString; } sendNextDtmf(); } void MockConferenceCallChannel::onDTMFStopTone(Tp::DBusError *error) { } MockConferenceCallChannel::~MockConferenceCallChannel() { qDebug() << "conference call channel closed"; // TODO - for some reason the object is not being removed mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree); } telephony-service-0.1+14.04.20140415/handler/tests/mock/speakeriface.cpp0000644000015301777760000000770512323307402026260 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Tiago Salem Herrmann */ #include #include #include #include "speakeriface.h" // Chan.I.Speaker BaseChannelSpeakerInterface::Adaptee::Adaptee(BaseChannelSpeakerInterface *interface) : QObject(interface), mInterface(interface) { } struct TP_QT_NO_EXPORT BaseChannelSpeakerInterface::Private { Private(BaseChannelSpeakerInterface *parent) : speakerMode(false), adaptee(new BaseChannelSpeakerInterface::Adaptee(parent)) { } bool speakerMode; turnOnSpeakerCallback turnOnSpeakerCB; BaseChannelSpeakerInterface::Adaptee *adaptee; }; BaseChannelSpeakerInterface::Adaptee::~Adaptee() { } void BaseChannelSpeakerInterface::Adaptee::turnOnSpeaker(bool active, const ChannelInterfaceSpeakerAdaptor::turnOnSpeakerContextPtr &context) { if (!mInterface->mPriv->turnOnSpeakerCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; mInterface->mPriv->turnOnSpeakerCB(active, &error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(); } BaseChannelSpeakerInterface::BaseChannelSpeakerInterface() : AbstractChannelInterface(TP_QT_IFACE_CHANNEL_SPEAKER), mPriv(new Private(this)) { } BaseChannelSpeakerInterface::~BaseChannelSpeakerInterface() { delete mPriv; } bool BaseChannelSpeakerInterface::speakerMode() const { return mPriv->speakerMode; } void BaseChannelSpeakerInterface::setTurnOnSpeakerCallback(const turnOnSpeakerCallback &cb) { mPriv->turnOnSpeakerCB = cb; } void BaseChannelSpeakerInterface::setSpeakerMode(bool active) { mPriv->speakerMode = active; Q_EMIT mPriv->adaptee->speakerChanged(active); } QVariantMap BaseChannelSpeakerInterface::immutableProperties() const { QVariantMap map; return map; } void BaseChannelSpeakerInterface::createAdaptor() { (void) new ChannelInterfaceSpeakerAdaptor(dbusObject()->dbusConnection(), mPriv->adaptee, dbusObject()); } ChannelInterfaceSpeakerAdaptor::ChannelInterfaceSpeakerAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent) : Tp::AbstractAdaptor(bus, adaptee, parent) { connect(adaptee, SIGNAL(speakerChanged(bool)), SIGNAL(SpeakerChanged(bool))); } ChannelInterfaceSpeakerAdaptor::~ChannelInterfaceSpeakerAdaptor() { } void ChannelInterfaceSpeakerAdaptor::turnOnSpeaker(bool active, const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("turnOnSpeaker(bool,ChannelInterfaceSpeakerAdaptor::turnOnSpeakerContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return; } turnOnSpeakerContextPtr ctx = turnOnSpeakerContextPtr( new Tp::MethodInvocationContext< bool >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "turnOnSpeaker", Q_ARG(bool, active), Q_ARG(ChannelInterfaceSpeakerAdaptor::turnOnSpeakerContextPtr, ctx)); return; } bool ChannelInterfaceSpeakerAdaptor::SpeakerMode() const { return qvariant_cast< bool >(adaptee()->property("speakerMode")); } telephony-service-0.1+14.04.20140415/handler/tests/mock/mockconnectiondbus.h0000644000015301777760000000357212323307402027170 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Gustavo Pichorim Boiko */ #ifndef MOCKCONNECTIONDBUS_H #define MOCKCONNECTIONDBUS_H #include #include class MockConnectionAdaptor; class MockConnection; class MockConnectionDBus : public QObject, public QDBusContext { Q_OBJECT public: explicit MockConnectionDBus(MockConnection *parent); bool connectToBus(); void PlaceIncomingMessage(const QString &message, const QVariantMap &properties); QString PlaceCall(const QVariantMap &properties); void HangupCall(const QString &callerId); void SetCallState(const QString &phoneNumber, const QString &state); Q_SIGNALS: // signals that will be relayed into the bus void MessageSent(const QString &mesasge, const QVariantMap &properties); void CallReceived(const QString &callerId); void CallEnded(const QString &callerId); void CallStateChanged(const QString &callerId, const QString &objectPath, const QString &state); void ConferenceCreated(const QString &objectPath); void ChannelMerged(const QString &objectPath); void ChannelSplitted(const QString &objectPath); private: MockConnectionAdaptor *mAdaptor; MockConnection *mConnection; }; #endif // MOCKCONNECTIONDBUS_H telephony-service-0.1+14.04.20140415/handler/tests/mock/protocol.h0000644000015301777760000000216112323307402025133 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * * This file is part of telepathy-ofono. * * telepathy-ofono is free software; you can redistribute it and/or modify * it under the terms of the GNU LESSER General Public License as published by * the Free Software Foundation; version 3. * * telepathy-ofono 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 LESSER General Public License * along with this program. If not, see . */ #ifndef MOCKPROTOCOL_H #define MOCKPROTOCOL_H #include class Protocol : public Tp::BaseProtocol { Q_OBJECT Q_DISABLE_COPY(Protocol) public: Protocol(const QDBusConnection &dbusConnection, const QString &name); private: Tp::BaseConnectionPtr createConnection(const QVariantMap ¶meters, Tp::DBusError *error); }; #endif telephony-service-0.1+14.04.20140415/handler/tests/mock/conferencecallchannel.h0000644000015301777760000000557012323307402027575 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #ifndef MOCKCONFERENCECALLCHANNEL_H #define MOCKCONFERENCECALLCHANNEL_H #include #include #include #include #include #include "connection.h" #include "speakeriface.h" class MockConnection; class MockConferenceCallChannel : public QObject { Q_OBJECT public: MockConferenceCallChannel(MockConnection *conn, QList callChannels, QObject *parent = 0); ~MockConferenceCallChannel(); void onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError* error); void onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error); void onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error); void onDTMFStartTone(uchar event, Tp::DBusError *error); void onDTMFStopTone(Tp::DBusError *error); void onTurnOnSpeaker(bool active, Tp::DBusError *error); void onMerge(const QDBusObjectPath &channel, Tp::DBusError *error); Tp::BaseChannelPtr baseChannel(); void setConferenceActive(bool active); Q_SIGNALS: void channelMerged(const QString &objectPath); void initialized(); private Q_SLOTS: void onDtmfComplete(bool success); void sendNextDtmf(); void init(); void onOfonoMuteChanged(bool mute); void onChannelSplitted(const QDBusObjectPath &path); private: QString mObjPath; QString mPreviousState; bool mIncoming; bool mRequestedHangup; MockConnection *mConnection; QList mCallChannels; Tp::BaseChannelPtr mBaseChannel; Tp::BaseChannelHoldInterfacePtr mHoldIface; Tp::BaseChannelConferenceInterfacePtr mConferenceIface; Tp::BaseChannelMergeableConferenceInterfacePtr mMergeableIface; Tp::BaseCallMuteInterfacePtr mMuteIface; BaseChannelSpeakerInterfacePtr mSpeakerIface; Tp::BaseChannelCallTypePtr mCallChannel; Tp::BaseCallContentDTMFInterfacePtr mDTMFIface; bool mDtmfLock; QStringList mDtmfPendingStrings; }; #endif // MOCKCONFERENCECALLCHANNEL_H telephony-service-0.1+14.04.20140415/handler/tests/mock/connection.cpp0000644000015301777760000004434012323307402025771 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #include #include #include #include // telepathy-mock #include "connection.h" #include "phoneutils.h" #include "protocol.h" #include "conferencecallchannel.h" #include "mockconnectiondbus.h" MockConnection::MockConnection(const QDBusConnection &dbusConnection, const QString &cmName, const QString &protocolName, const QVariantMap ¶meters) : Tp::BaseConnection(dbusConnection, cmName, protocolName, parameters), mHandleCount(0), mConferenceCall(0) { setSelfHandle(newHandle("")); setConnectCallback(Tp::memFun(this,&MockConnection::connect)); setInspectHandlesCallback(Tp::memFun(this,&MockConnection::inspectHandles)); setRequestHandlesCallback(Tp::memFun(this,&MockConnection::requestHandles)); setCreateChannelCallback(Tp::memFun(this,&MockConnection::createChannel)); // initialise requests interface (Connection.Interface.Requests) requestsIface = Tp::BaseConnectionRequestsInterface::create(this); // set requestable text channel properties Tp::RequestableChannelClass text; text.fixedProperties[TP_QT_IFACE_CHANNEL+".ChannelType"] = TP_QT_IFACE_CHANNEL_TYPE_TEXT; text.fixedProperties[TP_QT_IFACE_CHANNEL+".TargetHandleType"] = Tp::HandleTypeContact; text.allowedProperties.append(TP_QT_IFACE_CHANNEL+".TargetHandle"); text.allowedProperties.append(TP_QT_IFACE_CHANNEL+".TargetID"); // set requestable call channel properties Tp::RequestableChannelClass call; call.fixedProperties[TP_QT_IFACE_CHANNEL+".ChannelType"] = TP_QT_IFACE_CHANNEL_TYPE_CALL; call.fixedProperties[TP_QT_IFACE_CHANNEL+".TargetHandleType"] = Tp::HandleTypeContact; call.fixedProperties[TP_QT_IFACE_CHANNEL_TYPE_CALL+".InitialAudio"] = true; call.allowedProperties.append(TP_QT_IFACE_CHANNEL+".TargetHandle"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL+".TargetID"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_TYPE_CALL+".InitialAudio"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_TYPE_CALL+".InitialVideo"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_TYPE_CALL+".InitialAudioName"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_TYPE_CALL+".InitialVideoName"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_TYPE_CALL+".InitialTransport"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_TYPE_CALL+".HardwareStreaming"); call.allowedProperties.append(TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialChannels")); requestsIface->requestableChannelClasses << text << call; plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(requestsIface)); // init presence interface simplePresenceIface = Tp::BaseConnectionSimplePresenceInterface::create(); simplePresenceIface->setSetPresenceCallback(Tp::memFun(this,&MockConnection::setPresence)); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(simplePresenceIface)); // Set Presence Tp::SimpleStatusSpec presenceOnline; presenceOnline.type = Tp::ConnectionPresenceTypeAvailable; presenceOnline.maySetOnSelf = true; presenceOnline.canHaveMessage = false; Tp::SimpleStatusSpec presenceOffline; presenceOffline.type = Tp::ConnectionPresenceTypeOffline; presenceOffline.maySetOnSelf = false; presenceOffline.canHaveMessage = false; Tp::SimpleStatusSpecMap statuses; statuses.insert(QLatin1String("available"), presenceOnline); statuses.insert(QLatin1String("offline"), presenceOffline); simplePresenceIface->setStatuses(statuses); mSelfPresence.type = Tp::ConnectionPresenceTypeOffline; mRequestedSelfPresence.type = Tp::ConnectionPresenceTypeOffline; contactsIface = Tp::BaseConnectionContactsInterface::create(); contactsIface->setGetContactAttributesCallback(Tp::memFun(this,&MockConnection::getContactAttributes)); contactsIface->setContactAttributeInterfaces(QStringList() << TP_QT_IFACE_CONNECTION << TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(contactsIface)); mDBus = new MockConnectionDBus(this); setOnline(true); } void MockConnection::addMMSToService(const QString &path, const QVariantMap &properties, const QString &servicePath) { qDebug() << "addMMSToService " << path << properties << servicePath; #if 0 FIXME: re-implement MMSDMessage *msg = new MMSDMessage(path, properties); QObject::connect(msg, SIGNAL(propertyChanged(QString,QVariant)), SLOT(onMMSPropertyChanged(QString,QVariant))); mServiceMMSList[servicePath].append(msg); if (properties["Status"] == "received") { const QString normalizedNumber = PhoneUtils::normalizePhoneNumber(properties["Sender"].toString()); // check if there is an open channel for this number and use it Q_FOREACH(const QString &phoneNumber, mTextChannels.keys()) { if (PhoneUtils::comparePhoneNumbers(normalizedNumber, phoneNumber)) { qDebug() << "existing channel" << mTextChannels[phoneNumber]; mTextChannels[phoneNumber]->mmsReceived(path, properties); return; } } Tp::DBusError error; bool yours; qDebug() << "new handle" << normalizedNumber; uint handle = newHandle(normalizedNumber); ensureChannel(TP_QT_IFACE_CHANNEL_TYPE_TEXT,Tp::HandleTypeContact, handle, yours, handle, false, &error); if(error.isValid()) { qCritical() << "Error creating channel for incoming message " << error.name() << error.message(); return; } mTextChannels[normalizedNumber]->mmsReceived(path, properties); } #endif } MockConnection::~MockConnection() { } uint MockConnection::setPresence(const QString& status, const QString& statusMessage, Tp::DBusError *error) { qDebug() << "setPresence" << status; if (status == "available") { mRequestedSelfPresence.type = Tp::ConnectionPresenceTypeAvailable; } return selfHandle(); } Tp::ContactAttributesMap MockConnection::getContactAttributes(const Tp::UIntList &handles, const QStringList &ifaces, Tp::DBusError *error) { qDebug() << "getContactAttributes" << handles << ifaces; Tp::ContactAttributesMap attributesMap; QVariantMap attributes; Q_FOREACH(uint handle, handles) { attributes[TP_QT_IFACE_CONNECTION+"/contact-id"] = inspectHandles(Tp::HandleTypeContact, Tp::UIntList() << handle, error).at(0); if (ifaces.contains(TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE)) { attributes[TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE+"/presence"] = QVariant::fromValue(mSelfPresence); } attributesMap[handle] = attributes; } return attributesMap; } void MockConnection::setOnline(bool online) { qDebug() << "setOnline" << online; Tp::SimpleContactPresences presences; if (online) { mSelfPresence.status = "available"; mSelfPresence.statusMessage = ""; mSelfPresence.type = Tp::ConnectionPresenceTypeAvailable; } else { mSelfPresence.status = "offline"; mSelfPresence.statusMessage = ""; mSelfPresence.type = Tp::ConnectionPresenceTypeOffline; } presences[selfHandle()] = mSelfPresence; simplePresenceIface->setPresences(presences); } uint MockConnection::newHandle(const QString &identifier) { mHandles[++mHandleCount] = identifier; return mHandleCount; } QMap MockConnection::callChannels() { return mCallChannels; } QStringList MockConnection::inspectHandles(uint handleType, const Tp::UIntList& handles, Tp::DBusError *error) { QStringList identifiers; if( handleType != Tp::HandleTypeContact ) { error->set(TP_QT_ERROR_INVALID_ARGUMENT,"Not supported"); return QStringList(); } qDebug() << "MockConnection::inspectHandles " << handles; Q_FOREACH( uint handle, handles) { if (mHandles.keys().contains(handle)) { identifiers.append(mHandles.value(handle)); } else { error->set(TP_QT_ERROR_INVALID_HANDLE, "Handle not found"); return QStringList(); } } qDebug() << "MockConnection::inspectHandles " << identifiers; return identifiers; } void MockConnection::connect(Tp::DBusError *error) { qDebug() << "MockConnection::connect"; setStatus(Tp::ConnectionStatusConnected, Tp::ConnectionStatusReasonRequested); } Tp::UIntList MockConnection::requestHandles(uint handleType, const QStringList& identifiers, Tp::DBusError* error) { qDebug() << "requestHandles"; Tp::UIntList handles; if( handleType != Tp::HandleTypeContact ) { error->set(TP_QT_ERROR_INVALID_ARGUMENT, "Not supported"); return Tp::UIntList(); } Q_FOREACH( const QString& identifier, identifiers) { if (mHandles.values().contains(identifier)) { handles.append(mHandles.key(identifier)); } else { handles.append(newHandle(identifier)); } } qDebug() << "requestHandles" << handles; return handles; } Tp::BaseChannelPtr MockConnection::createTextChannel(uint targetHandleType, uint targetHandle, Tp::DBusError *error) { Q_UNUSED(targetHandleType); Q_UNUSED(error); QString requestedId = mHandles.value(targetHandle); if (mTextChannels.contains(requestedId)) { return mTextChannels[requestedId]->baseChannel(); } MockTextChannel *channel = new MockTextChannel(this, requestedId, targetHandle); QObject::connect(channel, SIGNAL(messageRead(QString)), SLOT(onMessageRead(QString))); QObject::connect(channel, SIGNAL(destroyed()), SLOT(onTextChannelClosed())); QObject::connect(channel, SIGNAL(messageSent(QString,QVariantMap)), SIGNAL(messageSent(QString,QVariantMap))); qDebug() << channel; mTextChannels[requestedId] = channel; return channel->baseChannel(); } void MockConnection::onMessageRead(const QString &id) { // FIXME: implement } void MockConnection::onConferenceCallChannelClosed() { if (mConferenceCall) { mConferenceCall = NULL; } } void MockConnection::onCallChannelSplitted() { MockCallChannel *channel = qobject_cast(sender()); Q_EMIT channelSplitted(channel->baseChannel()->objectPath()); Q_EMIT channelSplitted(QDBusObjectPath(channel->baseChannel()->objectPath())); } Tp::BaseChannelPtr MockConnection::createCallChannel(uint targetHandleType, uint targetHandle, const QVariantMap &hints, Tp::DBusError *error) { Q_UNUSED(targetHandleType); QString requestedId = mHandles.value(targetHandle); if (hints.contains(TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialChannels")) && targetHandleType == Tp::HandleTypeNone && targetHandle == 0) { // conference call request if (mConferenceCall) { error->set(TP_QT_ERROR_NOT_AVAILABLE, "Conference call already exists"); return Tp::BaseChannelPtr(); } QDBusArgument arg = hints[TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialChannels")].value(); QList channels; arg >> channels; if (!channels.isEmpty()) { mConferenceCall = new MockConferenceCallChannel(this, channels); QObject::connect(mConferenceCall, SIGNAL(destroyed()), SLOT(onConferenceCallChannelClosed())); QObject::connect(mConferenceCall, SIGNAL(channelMerged(QString)), SIGNAL(channelMerged(QString))); // the object path is only availabe after we return to the event loop, so emit the conferenceCreated signal // only after that. QObject::connect(mConferenceCall, &MockConferenceCallChannel::initialized, [this]() { Q_EMIT conferenceCreated(mConferenceCall->baseChannel()->objectPath()); }); return mConferenceCall->baseChannel(); } error->set(TP_QT_ERROR_NOT_AVAILABLE, "Impossible to merge calls"); return Tp::BaseChannelPtr(); } Q_FOREACH(const QString &id, mCallChannels.keys()) { if (id == requestedId) { return mCallChannels[id]->baseChannel(); } } QString state = "dialing"; if (mInitialCallStatus.contains(requestedId)) { state = mInitialCallStatus.take(requestedId); } mCallChannels[requestedId] = new MockCallChannel(this, requestedId, state, targetHandle); QObject::connect(mCallChannels[requestedId], SIGNAL(destroyed()), SLOT(onCallChannelClosed())); QObject::connect(mCallChannels[requestedId], SIGNAL(callStateChanged(MockCallChannel*,QString)), SLOT(onCallStateChanged(MockCallChannel*,QString))); QObject::connect(mCallChannels[requestedId], SIGNAL(splitted()), SLOT(onCallChannelSplitted())); qDebug() << mCallChannels[requestedId]; if (!mIncomingCalls.contains(requestedId)) { Q_EMIT callReceived(requestedId); } return mCallChannels[requestedId]->baseChannel(); } Tp::BaseChannelPtr MockConnection::createChannel(const QString& channelType, uint targetHandleType, uint targetHandle, const QVariantMap &hints, Tp::DBusError *error) { qDebug() << "MockConnection::createChannel" << targetHandle; if (mSelfPresence.type != Tp::ConnectionPresenceTypeAvailable) { error->set(TP_QT_ERROR_NETWORK_ERROR, "No network available"); return Tp::BaseChannelPtr(); } if (channelType == TP_QT_IFACE_CHANNEL_TYPE_TEXT) { return createTextChannel(targetHandleType, targetHandle, error); } else if (channelType == TP_QT_IFACE_CHANNEL_TYPE_CALL) { return createCallChannel(targetHandleType, targetHandle, hints, error); } else { error->set(TP_QT_ERROR_NOT_IMPLEMENTED, "Channel type not available"); } return Tp::BaseChannelPtr(); } void MockConnection::placeIncomingMessage(const QString &message, const QVariantMap &info) { const QString sender = info["Sender"].toString(); // check if there is an open channel for this sender and use it Q_FOREACH(const QString &id, mTextChannels.keys()) { if (id == sender) { mTextChannels[id]->messageReceived(message, info); return; } } Tp::DBusError error; bool yours; uint handle = newHandle(sender); ensureChannel(TP_QT_IFACE_CHANNEL_TYPE_TEXT,Tp::HandleTypeContact, handle, yours, handle, false, QVariantMap(), &error); if(error.isValid()) { qWarning() << "Error creating channel for incoming message" << error.name() << error.message(); return; } mTextChannels[sender]->messageReceived(message, info); } void MockConnection::onTextChannelClosed() { MockTextChannel *channel = static_cast(sender()); if (channel) { QString key = mTextChannels.key(channel); qDebug() << "text channel closed for number " << key; mTextChannels.remove(key); } } void MockConnection::onCallChannelClosed() { qDebug() << "onCallChannelClosed()"; MockCallChannel *channel = static_cast(sender()); if (channel) { QString key = mCallChannels.key(channel); qDebug() << "call channel closed for number " << key; mCallChannels.remove(key); mIncomingCalls.removeAll(key); Q_EMIT callEnded(key); } } void MockConnection::onCallChannelDestroyed() { // FIXME: implement } void MockConnection::onCallStateChanged(MockCallChannel *channel, const QString &state) { const QString key = mCallChannels.key(channel); if (key.isEmpty()) { return; } Q_EMIT callStateChanged(key, channel->objectPath(), state); } uint MockConnection::ensureHandle(const QString &id) { if (mHandles.values().contains(id)) { return mHandles.key(id); } return newHandle(id); } QString MockConnection::placeCall(const QVariantMap &properties) { qDebug() << "new call" << properties; bool yours; Tp::DBusError error; QString callerId = properties["Caller"].toString(); QString state = properties["State"].toString(); if (mCallChannels.contains(callerId)) { return mCallChannels[callerId]->objectPath(); } uint handle = ensureHandle(callerId); uint initiatorHandle = 0; if (state == "incoming" || state == "waiting") { initiatorHandle = handle; } else { initiatorHandle = selfHandle(); } qDebug() << "initiatorHandle " <objectPath(); } void MockConnection::hangupCall(const QString &callerId) { if (!mCallChannels.contains(callerId)) { return; } mCallChannels[callerId]->setCallState("disconnected"); mIncomingCalls.removeAll(callerId); } void MockConnection::setCallState(const QString &phoneNumber, const QString &state) { if (!mCallChannels.contains(phoneNumber)) { return; } mCallChannels[phoneNumber]->setCallState(state); } telephony-service-0.1+14.04.20140415/handler/tests/mock/callchannel.h0000644000015301777760000000510312323307402025535 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann Gustavo Pichorim Boiko */ #ifndef MOCKCALLCHANNEL_H #define MOCKCALLCHANNEL_H #include #include #include #include #include #include "connection.h" class MockConnection; class MockCallChannel : public QObject { Q_OBJECT public: MockCallChannel(MockConnection *conn, QString phoneNumber, QString state, uint targetHandle, QObject *parent = 0); ~MockCallChannel(); Tp::BaseChannelPtr baseChannel(); void onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError* error); void onAccept(Tp::DBusError*); void onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error); void onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error); void onDTMFStartTone(uchar event, Tp::DBusError *error); void onDTMFStopTone(Tp::DBusError *error); void onSplit(Tp::DBusError *error); QString objectPath() const; Tp::CallState callState() const; public Q_SLOTS: void setCallState(const QString &state); void init(); void onOfonoMuteChanged(bool mute); Q_SIGNALS: void callStateChanged(MockCallChannel *channel, const QString &state); void splitted(); private: QString mObjPath; QString mState; bool mIncoming; bool mRequestedHangup; Tp::BaseChannelPtr mBaseChannel; QString mPhoneNumber; MockConnection *mConnection; uint mTargetHandle; Tp::BaseChannelHoldInterfacePtr mHoldIface; Tp::BaseCallMuteInterfacePtr mMuteIface; Tp::BaseChannelSplittableInterfacePtr mSplittableIface; Tp::BaseChannelCallTypePtr mCallChannel; Tp::BaseCallContentDTMFInterfacePtr mDTMFIface; Tp::BaseCallContentPtr mCallContent; }; #endif // MOCKCALLCHANNEL_H telephony-service-0.1+14.04.20140415/handler/tests/mock/textchannel.h0000644000015301777760000000402612323307402025611 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #ifndef MOCKTEXTCHANNEL_H #define MOCKTEXTCHANNEL_H #include #include #include #include #include #include "connection.h" class MockConnection; class MockTextChannel : public QObject { Q_OBJECT public: MockTextChannel(MockConnection *conn, QString phoneNumber, uint targetHandle, QObject *parent = 0); QString sendMessage(const Tp::MessagePartList& message, uint flags, Tp::DBusError* error); void messageReceived(const QString & message, const QVariantMap &info); Tp::BaseChannelPtr baseChannel(); void messageAcknowledged(const QString &id); void mmsReceived(const QString &id, const QVariantMap &properties); public Q_SLOTS: void placeDeliveryReport(const QString &messageId, const QString &status); Q_SIGNALS: void messageRead(const QString &id); void messageSent(const QString &message, const QVariantMap &info); private: ~MockTextChannel(); Tp::BaseChannelPtr mBaseChannel; QString mPhoneNumber; MockConnection *mConnection; uint mTargetHandle; Tp::BaseChannelMessagesInterfacePtr mMessagesIface; Tp::BaseChannelTextTypePtr mTextChannel; uint mMessageCounter; }; #endif // MOCKTEXTCHANNEL_H telephony-service-0.1+14.04.20140415/handler/tests/mock/textchannel.cpp0000644000015301777760000001775612323307402026162 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann * Gustavo Pichorim Boiko */ // telepathy-ofono #include "textchannel.h" QDBusArgument &operator<<(QDBusArgument &argument, const AttachmentStruct &attachment) { argument.beginStructure(); argument << attachment.id << attachment.contentType << attachment.filePath << attachment.offset << attachment.length; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, AttachmentStruct &attachment) { argument.beginStructure(); argument >> attachment.id >> attachment.contentType >> attachment.filePath >> attachment.offset >> attachment.length; argument.endStructure(); return argument; } MockTextChannel::MockTextChannel(MockConnection *conn, QString phoneNumber, uint targetHandle, QObject *parent): QObject(parent), mConnection(conn), mPhoneNumber(phoneNumber), mTargetHandle(targetHandle), mMessageCounter(1) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_TEXT, targetHandle, Tp::HandleTypeContact); Tp::BaseChannelTextTypePtr textType = Tp::BaseChannelTextType::create(baseChannel.data()); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(textType)); QStringList supportedContentTypes = QStringList() << "text/plain"; Tp::UIntList messageTypes = Tp::UIntList() << Tp::ChannelTextMessageTypeNormal << Tp::ChannelTextMessageTypeDeliveryReport; uint messagePartSupportFlags = 0; uint deliveryReportingSupport = Tp::DeliveryReportingSupportFlagReceiveSuccesses; mMessagesIface = Tp::BaseChannelMessagesInterface::create(textType.data(), supportedContentTypes, messageTypes, messagePartSupportFlags, deliveryReportingSupport); mMessagesIface->setSendMessageCallback(Tp::memFun(this,&MockTextChannel::sendMessage)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMessagesIface)); mBaseChannel = baseChannel; mTextChannel = Tp::BaseChannelTextTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_TEXT)); mTextChannel->setMessageAcknowledgedCallback(Tp::memFun(this,&MockTextChannel::messageAcknowledged)); QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater())); } MockTextChannel::~MockTextChannel() { } Tp::BaseChannelPtr MockTextChannel::baseChannel() { return mBaseChannel; } void MockTextChannel::messageAcknowledged(const QString &id) { Q_EMIT messageRead(id); } QString MockTextChannel::sendMessage(const Tp::MessagePartList& message, uint flags, Tp::DBusError* error) { Tp::MessagePart header = message.at(0); Tp::MessagePart body = message.at(1); static int serial = 0; // FIXME: check what other data we need to emit in the signal QString id = QString("sentmessage%1").arg(serial++); QString messageText = body["content"].variant().toString(); QVariantMap properties; properties["SentTime"] = QDateTime::currentDateTime().toString(Qt::ISODate); properties["Recipients"] = QStringList() << mPhoneNumber; properties["Id"] = id; Q_EMIT messageSent(messageText, properties); return id; } void MockTextChannel::placeDeliveryReport(const QString &messageId, const QString &status) { Tp::DeliveryStatus delivery_status; if (status == "sent") { delivery_status = Tp::DeliveryStatusDelivered; } else if(status == "failed") { delivery_status = Tp::DeliveryStatusPermanentlyFailed; } else if(status == "pending") { delivery_status = Tp::DeliveryStatusAccepted; } else { delivery_status = Tp::DeliveryStatusUnknown; } Tp::MessagePartList partList; Tp::MessagePart header; header["message-sender"] = QDBusVariant(mTargetHandle); header["message-sender-id"] = QDBusVariant(mPhoneNumber); header["message-type"] = QDBusVariant(Tp::ChannelTextMessageTypeDeliveryReport); header["delivery-status"] = QDBusVariant(delivery_status); header["delivery-token"] = QDBusVariant(messageId); partList << header; mTextChannel->addReceivedMessage(partList); } void MockTextChannel::messageReceived(const QString &message, const QVariantMap &info) { Tp::MessagePartList partList; Tp::MessagePart body; body["content-type"] = QDBusVariant("text/plain"); body["content"] = QDBusVariant(message); Tp::MessagePart header; header["message-token"] = QDBusVariant(info["SentTime"].toString() +"-" + QString::number(mMessageCounter++)); header["message-received"] = QDBusVariant(QDateTime::fromString(info["SentTime"].toString(), Qt::ISODate).toTime_t()); header["message-sender"] = QDBusVariant(mTargetHandle); header["message-sender-id"] = QDBusVariant(mPhoneNumber); header["message-type"] = QDBusVariant(Tp::ChannelTextMessageTypeNormal); partList << header << body; mTextChannel->addReceivedMessage(partList); } void MockTextChannel::mmsReceived(const QString &id, const QVariantMap &properties) { Tp::MessagePartList message; QString subject = properties["Subject"].toString(); QString smil = properties["Smil"].toString(); Tp::MessagePart header; header["message-token"] = QDBusVariant(id); header["message-sender"] = QDBusVariant(mTargetHandle); header["message-received"] = QDBusVariant(QDateTime::fromString(properties["Date"].toString(), Qt::ISODate).toTime_t()); header["message-type"] = QDBusVariant(Tp::DeliveryStatusDelivered); if (!subject.isEmpty()) { header["subject"] = QDBusVariant(subject); } message << header; AttachmentList mmsdAttachments = qdbus_cast(properties["Attachments"]); Q_FOREACH(const AttachmentStruct &attachment, mmsdAttachments) { QFile attachmentFile(attachment.filePath); if (!attachmentFile.open(QIODevice::ReadOnly)) { qWarning() << "fail to load attachment" << attachmentFile.errorString() << attachment.filePath; continue; } // FIXME check if we managed to read the total attachment file attachmentFile.seek(attachment.offset); QByteArray fileData = attachmentFile.read(attachment.length); Tp::MessagePart part; part["content-type"] = QDBusVariant(attachment.contentType); part["identifier"] = QDBusVariant(attachment.id); part["content"] = QDBusVariant(fileData); part["size"] = QDBusVariant(attachment.length); message << part; } if (!smil.isEmpty()) { Tp::MessagePart part; part["content-type"] = QDBusVariant(QString("application/smil")); part["identifier"] = QDBusVariant(QString("smil")); part["content"] = QDBusVariant(smil); part["size"] = QDBusVariant(smil.size()); message << part; } mTextChannel->addReceivedMessage(message); } telephony-service-0.1+14.04.20140415/handler/tests/mock/main.cpp0000644000015301777760000000252312323307402024553 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann */ #include #include #include #include "protocol.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Tp::registerTypes(); Tp::enableDebug(true); Tp::enableWarnings(true); Tp::BaseProtocolPtr proto = Tp::BaseProtocol::create( QDBusConnection::sessionBus(), QLatin1String("mock")); Tp::BaseConnectionManagerPtr cm = Tp::BaseConnectionManager::create( QDBusConnection::sessionBus(), QLatin1String("mock")); cm->addProtocol(proto); cm->registerObject(); return a.exec(); } telephony-service-0.1+14.04.20140415/handler/tests/mock/CMakeLists.txt0000644000015301777760000000130712323307402025662 0ustar pbusernogroup00000000000000include_directories( ${TP_QT5_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) find_library(TELEPATHY_QT5_SERVICE_LIBRARIES telepathy-qt5-service) set(mock_SRCS main.cpp protocol.cpp connection.cpp textchannel.cpp callchannel.cpp conferencecallchannel.cpp mockconnectiondbus.cpp speakeriface.cpp) qt5_add_dbus_adaptor(mock_SRCS MockConnection.xml mockconnectiondbus.h MockConnectionDBus) add_executable(telepathy-mock ${mock_SRCS}) qt5_use_modules(telepathy-mock Core DBus) target_link_libraries(telepathy-mock ${TP_QT5_LIBRARIES} ${TELEPATHY_QT5_SERVICE_LIBRARIES} ${OFONO_QT_LIBRARIES} ${PULSEAUDIO_LIBRARIES}) telephony-service-0.1+14.04.20140415/handler/tests/mock/protocol.cpp0000644000015301777760000000304212323307402025465 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann */ #include "protocol.h" #include "connection.h" #include #include Protocol::Protocol(const QDBusConnection &dbusConnection, const QString &name) : Tp::BaseProtocol(dbusConnection, name) { setRequestableChannelClasses(Tp::RequestableChannelClassSpecList() << Tp::RequestableChannelClassSpec::textChat() << Tp::RequestableChannelClassSpec::audioCall()); setCreateConnectionCallback(memFun(this, &Protocol::createConnection)); } Tp::BaseConnectionPtr Protocol::createConnection(const QVariantMap ¶meters, Tp::DBusError *error) { Q_UNUSED(error); return Tp::BaseConnection::create(QDBusConnection::sessionBus(), "mock", name().toLatin1(), parameters); } telephony-service-0.1+14.04.20140415/handler/tests/mock/MockConnection.xml0000644000015301777760000000646012323307402026562 0ustar pbusernogroup00000000000000 An interface to the fake connection manager telephony-service-0.1+14.04.20140415/handler/tests/mock/connection.h0000644000015301777760000001103012323307402025424 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #ifndef MOCKCONNECTION_H #define MOCKCONNECTION_H // qt #include // telepathy-qt #include #include #include #include #include // mock-cm #include "textchannel.h" #include "callchannel.h" #include "dbustypes.h" class MockTextChannel; class MockCallChannel; class MockConnectionDBus; class MockConferenceCallChannel; class MockConnection : public Tp::BaseConnection { Q_OBJECT Q_DISABLE_COPY(MockConnection) public: MockConnection(const QDBusConnection &dbusConnection, const QString &cmName, const QString &protocolName, const QVariantMap ¶meters); QStringList inspectHandles(uint handleType, const Tp::UIntList& handles, Tp::DBusError *error); Tp::UIntList requestHandles(uint handleType, const QStringList& identifiers, Tp::DBusError* error); Tp::BaseChannelPtr createChannel(const QString& channelType, uint targetHandleType, uint targetHandle, const QVariantMap& hints, Tp::DBusError *error); Tp::ContactAttributesMap getContactAttributes(const Tp::UIntList &handles, const QStringList &ifaces, Tp::DBusError *error); uint setPresence(const QString& status, const QString& statusMessage, Tp::DBusError *error); void connect(Tp::DBusError *error); void setOnline(bool online); Tp::BaseConnectionRequestsInterfacePtr requestsIface; Tp::BaseConnectionSimplePresenceInterfacePtr simplePresenceIface; Tp::BaseConnectionContactsInterfacePtr contactsIface; uint newHandle(const QString &identifier); QMap callChannels(); uint ensureHandle(const QString &id); Tp::BaseChannelPtr createTextChannel(uint targetHandleType, uint targetHandle, Tp::DBusError *error); Tp::BaseChannelPtr createCallChannel(uint targetHandleType, uint targetHandle, const QVariantMap &hints, Tp::DBusError *error); ~MockConnection(); QString placeCall(const QVariantMap &properties); Q_SIGNALS: void messageSent(const QString &message, const QVariantMap &info); void callReceived(const QString &callerId); void callEnded(const QString &callerId); void callStateChanged(const QString &callerId, const QString &objectPath, const QString &state); void conferenceCreated(const QString &objectPath); void channelMerged(const QString &objectPath); void channelSplitted(const QString &objectPath); void channelSplitted(const QDBusObjectPath &objectPath); public Q_SLOTS: void placeIncomingMessage(const QString &message, const QVariantMap &info); void hangupCall(const QString &callerId); void setCallState(const QString &phoneNumber, const QString &state); void onTextChannelClosed(); void onCallChannelClosed(); void onCallChannelDestroyed(); void onCallStateChanged(MockCallChannel *channel, const QString &state); void onMessageRead(const QString &id); void onConferenceCallChannelClosed(); void onCallChannelSplitted(); private: void addMMSToService(const QString &path, const QVariantMap &properties, const QString &servicePath); QMap mHandles; QMap mTextChannels; QMap mCallChannels; QMap mInitialCallStatus; QStringList mModems; uint mHandleCount; Tp::SimplePresence mSelfPresence; Tp::SimplePresence mRequestedSelfPresence; MockConnectionDBus *mDBus; QStringList mIncomingCalls; MockConferenceCallChannel *mConferenceCall; }; #endif telephony-service-0.1+14.04.20140415/handler/tests/telepathyhelper.cpp0000644000015301777760000002025512323307402026077 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #include "telepathyhelper.h" #include #include #include #include #include TelepathyHelper::TelepathyHelper(QObject *parent) : QObject(parent), //mChannelObserver(0), mFirstTime(true), mConnected(false), mHandlerInterface(0) { Tp::registerTypes(); mAccountFeatures << Tp::Account::FeatureCore; mContactFeatures << Tp::Contact::FeatureAlias << Tp::Contact::FeatureAvatarData << Tp::Contact::FeatureAvatarToken << Tp::Contact::FeatureCapabilities << Tp::Contact::FeatureSimplePresence; mConnectionFeatures << Tp::Connection::FeatureCore << Tp::Connection::FeatureSelfContact << Tp::Connection::FeatureSimplePresence; Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus()); channelFactory->addCommonFeatures(Tp::Channel::FeatureCore); mAccountManager = Tp::AccountManager::create( Tp::AccountFactory::create(QDBusConnection::sessionBus(), mAccountFeatures), Tp::ConnectionFactory::create(QDBusConnection::sessionBus(), mConnectionFeatures), channelFactory, Tp::ContactFactory::create(mContactFeatures)); connect(mAccountManager->becomeReady(Tp::AccountManager::FeatureCore), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady(Tp::PendingOperation*))); mClientRegistrar = Tp::ClientRegistrar::create(mAccountManager); } TelepathyHelper::~TelepathyHelper() { } TelepathyHelper *TelepathyHelper::instance() { static TelepathyHelper* helper = new TelepathyHelper(); return helper; } QString TelepathyHelper::accountId() const { if (mAccount) { return mAccount->uniqueIdentifier(); } return QString(); } Tp::AccountPtr TelepathyHelper::account() const { return mAccount; } /* ChannelObserver *TelepathyHelper::channelObserver() const { return mChannelObserver; } */ bool TelepathyHelper::connected() const { return mConnected; } /* void TelepathyHelper::registerChannelObserver(const QString &observerName) { QString name = observerName; if (name.isEmpty()) { name = "TelephonyPluginObserver"; } if (mChannelObserver) { mChannelObserver->deleteLater(); } mChannelObserver = new ChannelObserver(this); registerClient(mChannelObserver, name); // messages connect(mChannelObserver, SIGNAL(textChannelAvailable(Tp::TextChannelPtr)), ChatManager::instance(), SLOT(onTextChannelAvailable(Tp::TextChannelPtr))); // calls connect(mChannelObserver, SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), CallManager::instance(), SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); Q_EMIT channelObserverCreated(mChannelObserver); } void TelepathyHelper::unregisterChannelObserver() { Tp::AbstractClientPtr clientPtr(mChannelObserver); if (clientPtr) { mClientRegistrar->unregisterClient(clientPtr); } mChannelObserver->deleteLater(); mChannelObserver = NULL; Q_EMIT channelObserverUnregistered(); } */ QStringList TelepathyHelper::supportedProtocols() const { QStringList protocols; protocols << "mock"; return protocols; } void TelepathyHelper::initializeAccount() { // watch for account state and connection changes connect(mAccount.data(), SIGNAL(stateChanged(bool)), SLOT(onAccountStateChanged(bool))); connect(mAccount.data(), SIGNAL(connectionChanged(const Tp::ConnectionPtr&)), SLOT(onAccountConnectionChanged(const Tp::ConnectionPtr&))); // and make sure it is enabled and connected if (!mAccount->isEnabled()) { ensureAccountEnabled(); } else { ensureAccountConnected(); } } void TelepathyHelper::ensureAccountEnabled() { mAccount->setConnectsAutomatically(true); connect(mAccount->setEnabled(true), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountEnabled(Tp::PendingOperation*))); } void TelepathyHelper::ensureAccountConnected() { // if the account is not connected, request it to connect if (!mAccount->connection() || mAccount->connectionStatus() != Tp::ConnectionStatusConnected) { Tp::Presence presence(Tp::ConnectionPresenceTypeAvailable, "available", "online"); mAccount->setRequestedPresence(presence); } else { watchSelfContactPresence(); } if (mFirstTime) { Q_EMIT accountReady(); mFirstTime = false; } } void TelepathyHelper::watchSelfContactPresence() { if (mAccount.isNull() || mAccount->connection().isNull()) { return; } connect(mAccount->connection()->selfContact().data(), SIGNAL(presenceChanged(Tp::Presence)), SLOT(onPresenceChanged(Tp::Presence))); onPresenceChanged(mAccount->connection()->selfContact()->presence()); } void TelepathyHelper::registerClient(Tp::AbstractClient *client, QString name) { Tp::AbstractClientPtr clientPtr(client); bool succeeded = mClientRegistrar->registerClient(clientPtr, name); if (!succeeded) { name.append("%1"); int count = 0; // limit the number of registered clients to 20, that should be a safe margin while (!succeeded && count < 20) { succeeded = mClientRegistrar->registerClient(clientPtr, name.arg(++count)); if (succeeded) { name = name.arg(count); } } } if (succeeded) { QObject *object = dynamic_cast(client); if (object) { object->setProperty("clientName", TP_QT_IFACE_CLIENT + "." + name ); } } } void TelepathyHelper::onAccountManagerReady(Tp::PendingOperation *op) { Q_UNUSED(op) Tp::AccountSetPtr accountSet; // try to find an account of the one of supported protocols Q_FOREACH(const QString &protocol, supportedProtocols()) { accountSet = mAccountManager->accountsByProtocol(protocol); if (accountSet->accounts().count() > 0) { break; } } if (accountSet->accounts().count() == 0) { qCritical() << "No compatible telepathy account found!"; return; } mAccount = accountSet->accounts()[0]; // in case we have more than one account, the first one to show on the list is going to be used if (accountSet->accounts().count() > 1) { qWarning() << "There are more than just one account of type" << mAccount->protocolName(); } Q_EMIT accountIdChanged(); initializeAccount(); } void TelepathyHelper::onAccountEnabled(Tp::PendingOperation *op) { // we might need to do more stuff once the account is enabled, but making sure it is connected is a good start ensureAccountConnected(); } void TelepathyHelper::onAccountStateChanged(bool enabled) { if (!enabled) { ensureAccountEnabled(); } } void TelepathyHelper::onAccountConnectionChanged(const Tp::ConnectionPtr &connection) { if (connection.isNull()) { ensureAccountConnected(); } else { watchSelfContactPresence(); } Q_EMIT connectionChanged(); } void TelepathyHelper::onPresenceChanged(const Tp::Presence &presence) { mConnected = (presence.type() == Tp::ConnectionPresenceTypeAvailable); Q_EMIT connectedChanged(); } telephony-service-0.1+14.04.20140415/handler/tests/mockcontroller.h0000644000015301777760000000344212323307402025401 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #ifndef MOCKCONTROLLER_H #define MOCKCONTROLLER_H #include #include class MockController : public QObject { Q_OBJECT public: static MockController *instance(); Q_SIGNALS: void messageSent(const QString &message, const QVariantMap &properties); void callReceived(const QString &callerId); void callEnded(const QString &callerId); void callStateChanged(const QString &callerId, const QString &objectPath, const QString &state); void conferenceCreated(const QString &objectPath); void channelMerged(const QString &objectPath); void channelSplitted(const QString &objectPath); public Q_SLOTS: void placeIncomingMessage(const QString &message, const QVariantMap &properties); QString placeCall(const QVariantMap &properties); void hangupCall(const QString &callerId); void setCallState(const QString &phoneNumber, const QString &state); private: explicit MockController(QObject *parent = 0); QDBusInterface mMockInterface; }; #endif // MOCKCONTROLLER_H telephony-service-0.1+14.04.20140415/handler/tests/HandlerTest.cpp0000644000015301777760000002512012323307402025111 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include #include #include "handlercontroller.h" #include "mockcontroller.h" #include "approver.h" #include "telepathyhelper.h" class HandlerTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testMakingCalls(); void testHangUpCall(); void testCallHold(); void testCallProperties(); void testConferenceCall(); void testSendMessage(); private: void waitForCallActive(const QString &callerId); Approver *mApprover; }; void HandlerTest::initTestCase() { QSignalSpy spy(TelepathyHelper::instance(), SIGNAL(accountReady())); QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 10000); QTRY_VERIFY_WITH_TIMEOUT(TelepathyHelper::instance()->connected(), 10000); // register the approver mApprover = new Approver(this); TelepathyHelper::instance()->registerClient(mApprover, "TelephonyTestApprover"); // Tp-qt does not set registered status to approvers QTRY_VERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(TELEPHONY_SERVICE_APPROVER)); // we need to wait in order to give telepathy time to notify about the approver QTest::qWait(3000); } void HandlerTest::testMakingCalls() { QString callerId("1234567"); QSignalSpy callReceivedSpy(MockController::instance(), SIGNAL(callReceived(QString))); // FIXME: add support for multiple accounts HandlerController::instance()->startCall(callerId, TelepathyHelper::instance()->accountId()); QTRY_COMPARE(callReceivedSpy.count(), 1); QCOMPARE(callReceivedSpy.first().first().toString(), callerId); MockController::instance()->hangupCall(callerId); } void HandlerTest::testHangUpCall() { QString callerId("7654321"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall())); QString objectPath = MockController::instance()->placeCall(properties); QVERIFY(!objectPath.isEmpty()); // wait for the channel to hit the approver QTRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); waitForCallActive(callerId); // and finally request the hangup QSignalSpy callEndedSpy(MockController::instance(), SIGNAL(callEnded(QString))); HandlerController::instance()->hangUpCall(objectPath); QTRY_COMPARE(callEndedSpy.count(), 1); } void HandlerTest::testCallHold() { QString callerId("44444444"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall())); QString objectPath = MockController::instance()->placeCall(properties); QVERIFY(!objectPath.isEmpty()); // wait for the channel to hit the approver QTRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); waitForCallActive(callerId); QSignalSpy callStateSpy(MockController::instance(), SIGNAL(callStateChanged(QString,QString,QString))); // set the call on hold HandlerController::instance()->setHold(objectPath, true); QTRY_COMPARE(callStateSpy.count(), 1); QCOMPARE(callStateSpy.first()[2].toString(), QString("held")); // and now set it as unheld again callStateSpy.clear(); HandlerController::instance()->setHold(objectPath, false); QTRY_COMPARE(callStateSpy.count(), 1); QCOMPARE(callStateSpy.first()[2].toString(), QString("active")); MockController::instance()->hangupCall(callerId); } void HandlerTest::testCallProperties() { QString callerId("7654321"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall())); QSignalSpy handlerCallPropertiesSpy(HandlerController::instance(), SIGNAL(callPropertiesChanged(QString,QVariantMap))); MockController::instance()->placeCall(properties); // wait for the channel to hit the approver QTRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); // wait until the call properties are changed QTRY_VERIFY(handlerCallPropertiesSpy.count() > 0); QString objectPath = handlerCallPropertiesSpy.last()[0].toString(); QVariantMap propsFromSignal = handlerCallPropertiesSpy.last()[1].toMap(); QVERIFY(!propsFromSignal.isEmpty()); QDateTime activeTimestampFromSignal; QDateTime timestampFromSignal; propsFromSignal["activeTimestamp"].value() >> activeTimestampFromSignal; propsFromSignal["timestamp"].value() >> timestampFromSignal; QVERIFY(activeTimestampFromSignal.isValid()); QVERIFY(timestampFromSignal.isValid()); // and try to get the properties using the method QVariantMap propsFromMethod = HandlerController::instance()->getCallProperties(objectPath); QVERIFY(!propsFromMethod.isEmpty()); QDateTime activeTimestampFromMethod; QDateTime timestampFromMethod; propsFromMethod["activeTimestamp"].value() >> activeTimestampFromMethod; propsFromMethod["timestamp"].value() >> timestampFromMethod; QCOMPARE(activeTimestampFromSignal, activeTimestampFromMethod); QCOMPARE(timestampFromSignal, timestampFromMethod); // now send some DTMF tones and check if the property is properly updated handlerCallPropertiesSpy.clear(); QString dtmfString("1234*#"); for (int i = 0; i < dtmfString.length(); ++i) { HandlerController::instance()->sendDTMF(objectPath, QString(dtmfString[i])); } QTRY_COMPARE(handlerCallPropertiesSpy.count(), dtmfString.length()); propsFromSignal = handlerCallPropertiesSpy.last()[1].toMap(); propsFromMethod = HandlerController::instance()->getCallProperties(objectPath); QString dtmfStringFromSignal = propsFromSignal["dtmfString"].toString(); QString dtmfStringFromMethod = propsFromMethod["dtmfString"].toString(); QCOMPARE(dtmfStringFromSignal, dtmfString); QCOMPARE(dtmfStringFromMethod, dtmfString); HandlerController::instance()->hangUpCall(objectPath); } void HandlerTest::testConferenceCall() { QString callerId1("55555555"); QString callerId2("66666666"); QString callerId3("77777777"); QVariantMap properties; properties["Caller"] = callerId1; properties["State"] = "incoming"; QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall())); QString call1 = MockController::instance()->placeCall(properties); // wait for the channel to hit the approver QTRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); approverCallSpy.clear(); waitForCallActive(callerId1); // make a second call properties["Caller"] = callerId2; QString call2 = MockController::instance()->placeCall(properties); // wait for the channel to hit the approver QTRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); approverCallSpy.clear(); waitForCallActive(callerId2); // now create the conf call QSignalSpy conferenceCreatedSpy(MockController::instance(), SIGNAL(conferenceCreated(QString))); HandlerController::instance()->createConferenceCall(QStringList() << call1 << call2); QTRY_COMPARE(conferenceCreatedSpy.count(), 1); QString conferenceObjectPath = conferenceCreatedSpy.first().first().toString(); // now place a third call and try to merge it properties["Caller"] = callerId3; QString call3 = MockController::instance()->placeCall(properties); QTRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); approverCallSpy.clear(); waitForCallActive(callerId3); // merge that call on the conference QSignalSpy channelMergedSpy(MockController::instance(), SIGNAL(channelMerged(QString))); HandlerController::instance()->mergeCall(conferenceObjectPath, call3); QTRY_COMPARE(channelMergedSpy.count(), 1); QCOMPARE(channelMergedSpy.first().first().toString(), call3); // now try to split one of the channels QSignalSpy channelSplittedSpy(MockController::instance(), SIGNAL(channelSplitted(QString))); HandlerController::instance()->splitCall(call2); QTRY_COMPARE(channelSplittedSpy.count(), 1); QCOMPARE(channelSplittedSpy.first().first().toString(), call2); // now hangup the conference and the individual channels HandlerController::instance()->hangUpCall(conferenceObjectPath); HandlerController::instance()->hangUpCall(call1); HandlerController::instance()->hangUpCall(call2); HandlerController::instance()->hangUpCall(call3); } void HandlerTest::testSendMessage() { QString recipient("22222222"); QString message("Hello, world!"); QSignalSpy messageSentSpy(MockController::instance(), SIGNAL(messageSent(QString,QVariantMap))); // FIXME: add support for multiple accounts HandlerController::instance()->sendMessage(recipient, message, TelepathyHelper::instance()->accountId()); QTRY_COMPARE(messageSentSpy.count(), 1); QString sentMessage = messageSentSpy.first().first().toString(); QVariantMap messageProperties = messageSentSpy.first().last().value(); QCOMPARE(sentMessage, message); QCOMPARE(messageProperties["Recipients"].value().count(), 1); QCOMPARE(messageProperties["Recipients"].value().first(), recipient); } void HandlerTest::waitForCallActive(const QString &callerId) { // wait until the call state is "accepted" QSignalSpy callStateSpy(MockController::instance(), SIGNAL(callStateChanged(QString,QString,QString))); QString state; QString objectPath; QString caller; int tries = 0; while (state != "active" && caller != callerId && tries < 5) { QTRY_COMPARE(callStateSpy.count(), 1); caller = callStateSpy.first()[0].toString(); objectPath = callStateSpy.first()[1].toString(); state = callStateSpy.first()[2].toString(); callStateSpy.clear(); tries++; } QCOMPARE(caller, callerId); QCOMPARE(state, QString("active")); QVERIFY(!objectPath.isEmpty()); } QTEST_MAIN(HandlerTest) #include "HandlerTest.moc" telephony-service-0.1+14.04.20140415/handler/tests/telepathyhelper.h0000644000015301777760000000600212323307402025536 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #ifndef TELEPATHYHELPER_H #define TELEPATHYHELPER_H #include #include #include #include #include #include //#include "channelobserver.h" #define CANONICAL_TELEPHONY_VOICEMAIL_IFACE "com.canonical.Telephony.Voicemail" #define CANONICAL_TELEPHONY_SPEAKER_IFACE "com.canonical.Telephony.Speaker" class TelepathyHelper : public QObject { Q_OBJECT Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) Q_PROPERTY(QString accountId READ accountId NOTIFY accountIdChanged) public: ~TelepathyHelper(); static TelepathyHelper *instance(); Tp::AccountPtr account() const; //ChannelObserver *channelObserver() const; bool connected() const; QString accountId() const; void registerClient(Tp::AbstractClient *client, QString name); Q_SIGNALS: //void channelObserverCreated(ChannelObserver *observer); //void channelObserverUnregistered(); void accountReady(); void connectionChanged(); void connectedChanged(); void accountIdChanged(); public Q_SLOTS: //Q_INVOKABLE void registerChannelObserver(const QString &observerName = QString::null); //Q_INVOKABLE void unregisterChannelObserver(); protected: QStringList supportedProtocols() const; void initializeAccount(); void ensureAccountEnabled(); void ensureAccountConnected(); void watchSelfContactPresence(); private Q_SLOTS: void onAccountManagerReady(Tp::PendingOperation *op); void onAccountEnabled(Tp::PendingOperation *op); void onAccountStateChanged(bool enabled); void onAccountConnectionChanged(const Tp::ConnectionPtr &connection); void onPresenceChanged(const Tp::Presence &presence); private: explicit TelepathyHelper(QObject *parent = 0); Tp::AccountManagerPtr mAccountManager; Tp::Features mAccountManagerFeatures; Tp::Features mAccountFeatures; Tp::Features mContactFeatures; Tp::Features mConnectionFeatures; Tp::ClientRegistrarPtr mClientRegistrar; Tp::AccountPtr mAccount; //ChannelObserver *mChannelObserver; bool mFirstTime; bool mConnected; QDBusInterface *mHandlerInterface; }; #endif // TELEPATHYHELPER_H telephony-service-0.1+14.04.20140415/handler/tests/handlercontroller.cpp0000644000015301777760000000656312323307402026427 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: * Gustavo Pichorim Boiko */ #include #include "handlercontroller.h" #include #define HANDLER_SERVICE "com.canonical.TelephonyServiceHandler" #define HANDLER_OBJECT "/com/canonical/TelephonyServiceHandler" #define HANDLER_INTERFACE "com.canonical.TelephonyServiceHandler" HandlerController *HandlerController::instance() { static HandlerController *self = new HandlerController(); return self; } HandlerController::HandlerController(QObject *parent) : QObject(parent), mHandlerInterface(HANDLER_SERVICE, HANDLER_OBJECT, HANDLER_INTERFACE) { connect(&mHandlerInterface, SIGNAL(CallPropertiesChanged(QString, QVariantMap)), SIGNAL(callPropertiesChanged(QString, QVariantMap))); } QVariantMap HandlerController::getCallProperties(const QString &objectPath) { QVariantMap properties; QDBusReply reply = mHandlerInterface.call("GetCallProperties", objectPath); if (reply.isValid()) { properties = reply.value(); } return properties; } void HandlerController::startCall(const QString &number, const QString &accountId) { mHandlerInterface.call("StartCall", number, accountId); } void HandlerController::hangUpCall(const QString &objectPath) { mHandlerInterface.call("HangUpCall", objectPath); } void HandlerController::setHold(const QString &objectPath, bool hold) { mHandlerInterface.call("SetHold", objectPath, hold); } void HandlerController::setMuted(const QString &objectPath, bool muted) { mHandlerInterface.call("SetMuted", objectPath, muted); } void HandlerController::setSpeakerMode(const QString &objectPath, bool enabled) { mHandlerInterface.call("SetSpeakerMode", objectPath, enabled); } void HandlerController::sendDTMF(const QString &objectPath, const QString &key) { mHandlerInterface.call("SendDTMF", objectPath, key); } void HandlerController::createConferenceCall(const QStringList &objectPaths) { mHandlerInterface.call("CreateConferenceCall", objectPaths); } void HandlerController::mergeCall(const QString &conferenceObjectPath, const QString &callObjectPath) { mHandlerInterface.call("MergeCall", conferenceObjectPath, callObjectPath); } void HandlerController::splitCall(const QString &objectPath) { mHandlerInterface.call("SplitCall", objectPath); } void HandlerController::sendMessage(const QString &number, const QString &message, const QString &accountId) { mHandlerInterface.call("SendMessage", QStringList() << number, message, accountId); } void HandlerController::acknowledgeMessages(const QString &number, const QStringList &messageIds, const QString &accountId) { mHandlerInterface.call("AcknowledgeMessages", number, messageIds, accountId); } telephony-service-0.1+14.04.20140415/handler/tests/handlercontroller.h0000644000015301777760000000406312323307402026065 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: * Gustavo Pichorim Boiko */ #ifndef HANDLERCONTROLLER_H #define HANDLERCONTROLLER_H #include #include class HandlerController : public QObject { Q_OBJECT public: static HandlerController *instance(); QVariantMap getCallProperties(const QString &objectPath); public Q_SLOTS: // call methods void startCall(const QString &number, const QString &accountId); void hangUpCall(const QString &objectPath); void setHold(const QString &objectPath, bool hold); void setMuted(const QString &objectPath, bool muted); void setSpeakerMode(const QString &objectPath, bool enabled); void sendDTMF(const QString &objectPath, const QString &key); // conference call methods void createConferenceCall(const QStringList &objectPaths); void mergeCall(const QString &conferenceObjectPath, const QString &callObjectPath); void splitCall(const QString &objectPath); // messaging methods void sendMessage(const QString &number, const QString &message, const QString &accountId); void acknowledgeMessages(const QString &number, const QStringList &messageIds, const QString &accountId); Q_SIGNALS: void callPropertiesChanged(const QString &objectPath, const QVariantMap &properties); private: explicit HandlerController(QObject *parent = 0); QDBusInterface mHandlerInterface; }; #endif // HANDLERCONTROLLER_H telephony-service-0.1+14.04.20140415/handler/tests/CMakeLists.txt0000644000015301777760000000361112323307402024731 0ustar pbusernogroup00000000000000include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR} ) macro(generate_test TESTNAME USE_DBUS) add_executable(${TESTNAME} ${ARGN} ${TESTNAME}.cpp) qt5_use_modules(${TESTNAME} Core DBus Test) set(TEST_COMMAND ) if (${USE_DBUS}) set(TEST_COMMAND -p ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME} -p -xunitxml -p -o -p ${CMAKE_BINARY_DIR}/test_${TESTNAME}.xml) add_test(${TESTNAME} ${DBUS_RUNNER} --keep-env --task ${CMAKE_CURRENT_BINARY_DIR}/dbus-test-wrapper.sh ${TEST_COMMAND}) else (${USE_DBUS}) add_test(${TESTNAME} ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME} -xunitxml -o ${CMAKE_BINARY_DIR}/test_${TESTNAME}.xml) endif(${USE_DBUS}) # force telepathy not to use system approvers when available, # also force usage of memory backend in history-service set(TMPDIR "/tmp/telephony_service_test_home") set(TEST_ENVIRONMENT "HOME=${TMPDIR};" "HISTORY_SQLITE_DBPATH=:memory:;" "XDG_CONFIG_HOME=${TMPDIR}; XDG_DATA_HOME=${TMPDIR}; XDG_CACHE_DIR=${TMPDIR}; XDG_CACHE_HOME=${TMPDIR}; XDG_DATA_DIRS=${TMPDIR}; MC_ACCOUNT_DIR=${TMPDIR}; MC_MANAGER_DIR=${TMPDIR}") set_tests_properties(${TESTNAME} PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT}" TIMEOUT 30) target_link_libraries(${TESTNAME} ${TP_QT5_LIBRARIES} ) endmacro(generate_test) configure_file(dbus-test-wrapper.sh.in ${CMAKE_CURRENT_BINARY_DIR}/dbus-test-wrapper.sh) if (DBUS_RUNNER) generate_test(HandlerTest True telepathyhelper.cpp handlercontroller.cpp mockcontroller.cpp approver.cpp) endif(DBUS_RUNNER) add_subdirectory(mock) telephony-service-0.1+14.04.20140415/handler/tests/dbus-test-wrapper.sh.in0000755000015301777760000000130612323307402026524 0ustar pbusernogroup00000000000000#!/bin/sh -x # export the home folder to somewhere in /tmp TMPDIR=/tmp/telephony_service_test_home rm -rf $TMPDIR mkdir -p $TMPDIR export HOME=$TMPDIR # now run gnome-keyring gnome-keyring-daemon -r -d # we need to set this otherwise mission-control doesn't work properly dconf write /org/gnome/empathy/use-conn false # start the mock connection manager @CMAKE_CURRENT_BINARY_DIR@/mock/telepathy-mock & MOCK_PID=$! # wait 1 sec for the mock to start up sleep 1 mc-tool add mock/mock account0 @CMAKE_CURRENT_BINARY_DIR@/../telephony-service-handler & HANDLER_PID=$! $@ RESULT=$? # FIXME: check the variables and things that should not be started kill -9 $HANDLER_PID kill -9 $MOCK_PID return $RESULT telephony-service-0.1+14.04.20140415/handler/tests/mockcontroller.cpp0000644000015301777760000000547112323307402025740 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko */ #include "mockcontroller.h" #include #define MOCK_SERVICE "com.canonical.MockConnection" #define MOCK_OBJECT "/com/canonical/MockConnection" #define MOCK_INTERFACE "com.canonical.MockConnection" MockController::MockController(QObject *parent) : QObject(parent), mMockInterface(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE) { QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "MessageSent", this, SIGNAL(messageSent(QString, QVariantMap))); QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "CallReceived", this, SIGNAL(callReceived(QString))); QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "CallEnded", this, SIGNAL(callEnded(QString))); QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "CallStateChanged", this, SIGNAL(callStateChanged(QString,QString,QString))); QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "ConferenceCreated", this, SIGNAL(conferenceCreated(QString))); QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "ChannelMerged", this, SIGNAL(channelMerged(QString))); QDBusConnection::sessionBus().connect(MOCK_SERVICE, MOCK_OBJECT, MOCK_INTERFACE, "ChannelSplitted", this, SIGNAL(channelSplitted(QString))); } MockController *MockController::instance() { static MockController *self = new MockController(); return self; } void MockController::placeIncomingMessage(const QString &message, const QVariantMap &properties) { mMockInterface.call("PlaceIncomingMessage", message, properties); } QString MockController::placeCall(const QVariantMap &properties) { QDBusReply reply = mMockInterface.call("PlaceCall", properties); return reply; } void MockController::hangupCall(const QString &callerId) { mMockInterface.call("HangupCall", callerId); } void MockController::setCallState(const QString &phoneNumber, const QString &state) { mMockInterface.call("SetCallState", phoneNumber, state); } telephony-service-0.1+14.04.20140415/handler/tests/approver.cpp0000644000015301777760000001423112323307402024533 0ustar pbusernogroup00000000000000/** * Copyright (C) 2013 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, 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, see . * * Authors: Tiago Salem Herrmann */ #include "approver.h" #include #include #include #include #include #include Approver::Approver(QObject* parent) : QObject(parent), Tp::AbstractClientApprover(channelFilters()) { } Approver::~Approver() { } Tp::ChannelClassSpecList Approver::channelFilters() const { Tp::ChannelClassSpecList specList; specList << Tp::ChannelClassSpec::textChat() << Tp::ChannelClassSpec::audioCall(); return specList; } void Approver::addDispatchOperation(const Tp::MethodInvocationContextPtr<> &context, const Tp::ChannelDispatchOperationPtr &dispatchOperation) { bool willHandle = false; QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { // Text Channel Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if (!textChannel.isNull()) { // right now we are not using any of the text channel's features in the approver // so no need to call becomeReady() on it. willHandle = true; continue; } // Call Channel Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (!callChannel.isNull()) { Tp::PendingReady *pr = callChannel->becomeReady(Tp::Features() << Tp::CallChannel::FeatureCore << Tp::CallChannel::FeatureCallState << Tp::CallChannel::FeatureLocalHoldState); mChannels[pr] = callChannel; connect(pr, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onChannelReady(Tp::PendingOperation*))); callChannel->setProperty("accountId", QVariant(dispatchOperation->account()->uniqueIdentifier())); willHandle = true; continue; } } if (willHandle) { mDispatchOps.append(dispatchOperation); } context->setFinished(); // check if we need to approve channels already or if we should wait. processChannels(); } void Approver::processChannels() { Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { // approve only text channels Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if (textChannel.isNull()) { continue; } if (dispatchOperation->possibleHandlers().contains(TELEPHONY_SERVICE_HANDLER)) { dispatchOperation->handleWith(TELEPHONY_SERVICE_HANDLER); mDispatchOps.removeAll(dispatchOperation); } // FIXME: this shouldn't happen, but in any case, we need to check what to do when // the phone app client is not available } } } void Approver::acceptCall() { Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { if (dispatchOperation->possibleHandlers().contains(TELEPHONY_SERVICE_HANDLER)) { dispatchOperation->handleWith(TELEPHONY_SERVICE_HANDLER); mDispatchOps.removeAll(dispatchOperation); } } } } void Approver::rejectCall() { Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { if (dispatchOperation->possibleHandlers().contains(TELEPHONY_SERVICE_HANDLER)) { Tp::PendingOperation *claimop = dispatchOperation->claim(); mChannels[claimop] = dispatchOperation->channels().first(); connect(claimop, SIGNAL(finished(Tp::PendingOperation*)), this, SLOT(onClaimFinished(Tp::PendingOperation*))); } } } } void Approver::onClaimFinished(Tp::PendingOperation* op) { if(!op || op->isError()) { return; } Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(mChannels[op]); if (callChannel) { Tp::PendingOperation *hangupop = callChannel->hangup(Tp::CallStateChangeReasonUserRequested, TP_QT_ERROR_REJECTED, QString()); mChannels[hangupop] = callChannel; connect(hangupop, SIGNAL(finished(Tp::PendingOperation*)), this, SLOT(onHangupFinished(Tp::PendingOperation*))); } } void Approver::onHangupFinished(Tp::PendingOperation* op) { if(!op || op->isError()) { return; } mDispatchOps.removeAll(dispatchOperation(op)); mChannels.remove(op); } Tp::ChannelDispatchOperationPtr Approver::dispatchOperation(Tp::PendingOperation *op) { Tp::ChannelPtr channel = mChannels[op]; QString accountId = channel->property("accountId").toString(); Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { if (dispatchOperation->account()->uniqueIdentifier() == accountId) { return dispatchOperation; } } return Tp::ChannelDispatchOperationPtr(); } void Approver::onChannelReady(Tp::PendingOperation *op) { Q_EMIT newCall(); } ././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000telephony-service-0.1+14.04.20140415/handler/org.freedesktop.Telepathy.Client.TelephonyServiceHandler.service.intelephony-service-0.1+14.04.20140415/handler/org.freedesktop.Telepathy.Client.TelephonyServiceHandle0000644000015301777760000000023312323307402033626 0ustar pbusernogroup00000000000000[D-BUS Service] Name=org.freedesktop.Telepathy.Client.TelephonyServiceHandler Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-handler telephony-service-0.1+14.04.20140415/handler/Handler.xml0000644000015301777760000001153712323307402023134 0ustar pbusernogroup00000000000000 An interface to the phone handler helper application. telephony-service-0.1+14.04.20140415/handler/texthandler.cpp0000644000015301777760000001654412323307402024066 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "texthandler.h" #include "phoneutils.h" #include "telepathyhelper.h" #include "config.h" #include #include template<> bool qMapLessThanKey(const QStringList &key1, const QStringList &key2) { return key1.size() > key2.size(); // sort by operator> ! } TextHandler::TextHandler(QObject *parent) : QObject(parent) { // track when the account becomes available connect(TelepathyHelper::instance(), SIGNAL(connectedChanged()), SLOT(onConnectedChanged())); } void TextHandler::onConnectedChanged() { if (!TelepathyHelper::instance()->connected()) { return; } // now check which accounts are connected Q_FOREACH(const Tp::AccountPtr &account, TelepathyHelper::instance()->accounts()) { QString accountId = account->uniqueIdentifier(); if (!TelepathyHelper::instance()->isAccountConnected(account) || !mPendingMessages.contains(accountId)) { continue; } // create text channels to send the pending messages Q_FOREACH(const QStringList& phoneNumbers, mPendingMessages[accountId].keys()) { startChat(phoneNumbers, accountId); } } } TextHandler *TextHandler::instance() { static TextHandler *handler = new TextHandler(); return handler; } void TextHandler::startChat(const QStringList &phoneNumbers, const QString &accountId) { // Request the contact to start chatting to // FIXME: make it possible to select which account to use, for now, pick the first one Tp::AccountPtr account = TelepathyHelper::instance()->accountForId(accountId); if (!TelepathyHelper::instance()->isAccountConnected(account)) { qCritical() << "The selected account does not have a connection. AccountId:" << accountId; return; } connect(account->connection()->contactManager()->contactsForIdentifiers(phoneNumbers), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactsAvailable(Tp::PendingOperation*))); } void TextHandler::startChat(const Tp::AccountPtr &account, const Tp::Contacts &contacts) { if (contacts.size() == 1) { account->ensureTextChat(contacts.values()[0], QDateTime::currentDateTime(), TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler"); } else { account->createConferenceTextChat(QList(), contacts.toList(), QDateTime::currentDateTime(), TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler"); } // start chatting to the contacts Q_FOREACH(Tp::ContactPtr contact, contacts) { // hold the ContactPtr to make sure its refcounting stays bigger than 0 mContacts[contact->id()] = contact; } } void TextHandler::sendMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId) { Tp::AccountPtr account = TelepathyHelper::instance()->accountForId(accountId); if (!TelepathyHelper::instance()->isAccountConnected(account)) { mPendingMessages[accountId][phoneNumbers].append(message); return; } Tp::TextChannelPtr channel = existingChat(phoneNumbers, accountId); if (channel.isNull()) { mPendingMessages[accountId][phoneNumbers].append(message); startChat(phoneNumbers, accountId); return; } connect(channel->send(message), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onMessageSent(Tp::PendingOperation*))); } void TextHandler::acknowledgeMessages(const QStringList &phoneNumbers, const QStringList &messageIds, const QString &accountId) { Tp::TextChannelPtr channel = existingChat(phoneNumbers, accountId); if (channel.isNull()) { return; } QList messagesToAck; Q_FOREACH(const Tp::ReceivedMessage &message, channel->messageQueue()) { if (messageIds.contains(message.messageToken())) { messagesToAck.append(message); } } channel->acknowledge(messagesToAck); } void TextHandler::onTextChannelAvailable(Tp::TextChannelPtr channel) { Tp::AccountPtr account = TelepathyHelper::instance()->accountForConnection(channel->connection()); QString accountId = account->uniqueIdentifier(); mChannels.append(channel); // check for pending messages for this channel if (!mPendingMessages.contains(accountId)) { return; } QMap &pendingMessages = mPendingMessages[accountId]; QMap::iterator it = pendingMessages.begin(); while (it != pendingMessages.end()) { if (existingChat(it.key(), accountId) == channel) { Q_FOREACH(const QString &message, it.value()) { connect(channel->send(message), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onMessageSent(Tp::PendingOperation*))); } it = pendingMessages.erase(it); } else { ++it; } } } void TextHandler::onMessageSent(Tp::PendingOperation *op) { Tp::PendingSendMessage *psm = qobject_cast(op); if(!psm) { qWarning() << "The pending object was not a pending operation:" << op; return; } if (psm->isError()) { qWarning() << "Error sending message:" << psm->errorName() << psm->errorMessage(); return; } } Tp::TextChannelPtr TextHandler::existingChat(const QStringList &phoneNumbers, const QString &accountId) { Tp::TextChannelPtr channel; Q_FOREACH(const Tp::TextChannelPtr &channel, mChannels) { int count = 0; Tp::AccountPtr channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection()); if (channel->groupContacts(false).size() != phoneNumbers.size() || channelAccount->uniqueIdentifier() != accountId) { continue; } Q_FOREACH(const QString &phoneNumberNew, phoneNumbers) { Q_FOREACH(const Tp::ContactPtr &phoneNumberOld, channel->groupContacts(false)) { if (PhoneUtils::comparePhoneNumbers(phoneNumberOld->id(), phoneNumberNew)) { count++; } } } if (count == phoneNumbers.size()) { return channel; } } return channel; } void TextHandler::onContactsAvailable(Tp::PendingOperation *op) { Tp::PendingContacts *pc = qobject_cast(op); if (!pc) { qCritical() << "The pending object is not a Tp::PendingContacts"; return; } Tp::AccountPtr account = TelepathyHelper::instance()->accountForConnection(pc->manager()->connection()); startChat(account, pc->contacts().toSet()); } telephony-service-0.1+14.04.20140415/handler/handlerdbus.h0000644000015301777760000000470212323307402023475 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Ugo Riboni * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef HANDLERDBUS_H #define HANDLERDBUS_H #include #include #include "chatmanager.h" /** * DBus interface for the phone approver */ class HandlerDBus : public QObject, protected QDBusContext { Q_OBJECT public: HandlerDBus(QObject* parent=0); ~HandlerDBus(); QVariantMap GetCallProperties(const QString &objectPath); bool HasCalls(); QStringList AccountIds(); public Q_SLOTS: bool connectToBus(); // messages related Q_NOREPLY void SendMessage(const QStringList &number, const QString &message, const QString &accountId); Q_NOREPLY void AcknowledgeMessages(const QStringList &numbers, const QStringList &messageIds, const QString &accountId); // call related Q_NOREPLY void StartCall(const QString &number, const QString &accountId); Q_NOREPLY void HangUpCall(const QString &objectPath); Q_NOREPLY void SetHold(const QString &objectPath, bool hold); Q_NOREPLY void SetMuted(const QString &objectPath, bool muted); Q_NOREPLY void SetSpeakerMode(const QString &objectPath, bool enabled); Q_NOREPLY void SendDTMF(const QString &objectPath, const QString &key); // conference call related Q_NOREPLY void CreateConferenceCall(const QStringList &objectPaths); Q_NOREPLY void MergeCall(const QString &conferenceObjectPath, const QString &callObjectPath); Q_NOREPLY void SplitCall(const QString &objectPath); Q_SIGNALS: void onMessageSent(const QString &number, const QString &message); void CallPropertiesChanged(const QString &objectPath, const QVariantMap &properties); }; #endif // HANDLERDBUS_H telephony-service-0.1+14.04.20140415/handler/callhandler.h0000644000015301777760000000476412323307402023463 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Tiago Salem Herrmann * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef CALLHANDLER_H #define CALLHANDLER_H #include #include #include class TelepathyHelper; class CallHandler : public QObject { Q_OBJECT public: static CallHandler *instance(); QVariantMap getCallProperties(const QString &objectPath); bool hasCalls() const; public Q_SLOTS: void onCallChannelAvailable(Tp::CallChannelPtr channel); void startCall(const QString &phoneNumber, const QString &accountId); void hangUpCall(const QString &objectPath); void setHold(const QString &objectPath, bool hold); void setMuted(const QString &objectPath, bool muted); void setSpeakerMode(const QString &objectPath, bool enabled); void sendDTMF(const QString &objectPath, const QString &key); // conference call related void createConferenceCall(const QStringList &objectPaths); void mergeCall(const QString &conferenceObjectPath, const QString &callObjectPath); void splitCall(const QString &objectPath); Q_SIGNALS: void callPropertiesChanged(const QString &objectPath, const QVariantMap &properties); protected: Tp::CallChannelPtr existingCall(const QString &phoneNumber); Tp::CallChannelPtr callFromObjectPath(const QString &objectPath); protected Q_SLOTS: void onContactsAvailable(Tp::PendingOperation *op); void onCallHangupFinished(Tp::PendingOperation *op); void onCallChannelInvalidated(); void onCallStateChanged(Tp::CallState state); private: explicit CallHandler(QObject *parent = 0); QMap mContacts; QList mCallChannels; QMap mClosingChannels; }; #endif // CALLHANDLER_H telephony-service-0.1+14.04.20140415/handler/texthandler.h0000644000015301777760000000400612323307402023521 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef TEXTHANDLER_H #define TEXTHANDLER_H #include #include #include #include class TextHandler : public QObject { Q_OBJECT public: static TextHandler *instance(); void startChat(const QStringList &phoneNumber, const QString &accountId); void startChat(const Tp::AccountPtr &account, const Tp::Contacts &contacts); public Q_SLOTS: void sendMessage(const QStringList &phoneNumber, const QString &message, const QString &accountId); void acknowledgeMessages(const QStringList &phoneNumber, const QStringList &messageIds, const QString &accountId); protected Q_SLOTS: void onTextChannelAvailable(Tp::TextChannelPtr channel); void onContactsAvailable(Tp::PendingOperation *op); void onMessageSent(Tp::PendingOperation *op); void onConnectedChanged(); protected: Tp::TextChannelPtr existingChat(const QStringList &phoneNumber, const QString &accountId); private: explicit TextHandler(QObject *parent = 0); QList mChannels; QMap mContacts; // keys: accountId, participants values: pending messages QMap > mPendingMessages; }; #endif // TEXTHANDLER_H telephony-service-0.1+14.04.20140415/handler/main.cpp0000644000015301777760000000420512323307402022457 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "applicationutils.h" #include "callhandler.h" #include "handler.h" #include "handlerdbus.h" #include "telepathyhelper.h" #include "texthandler.h" #include #include #include #include #include int main(int argc, char **argv) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("telephony-service-handler"); Tp::registerTypes(); // check if there is already an instance of the handler running if (ApplicationUtils::checkApplicationRunning(TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler")) { qDebug() << "Found another instance of the handler. Quitting."; return 1; } Handler *handler = new Handler(); TelepathyHelper::instance()->registerClient(handler, "TelephonyServiceHandler"); QObject::connect(handler, SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), CallHandler::instance(), SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); QObject::connect(handler, SIGNAL(textChannelAvailable(Tp::TextChannelPtr)), TextHandler::instance(), SLOT(onTextChannelAvailable(Tp::TextChannelPtr))); HandlerDBus dbus; QObject::connect(TelepathyHelper::instance(), SIGNAL(accountReady()), &dbus, SLOT(connectToBus())); return app.exec(); } telephony-service-0.1+14.04.20140415/handler/handler.cpp0000644000015301777760000001143212323307402023150 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #include "handler.h" #include "telepathyhelper.h" #include #include #include #include #include Handler::Handler(QObject *parent) : QObject(parent), Tp::AbstractClientHandler(channelFilters()) { } bool Handler::bypassApproval() const { return false; } void Handler::handleChannels(const Tp::MethodInvocationContextPtr<> &context, const Tp::AccountPtr &account, const Tp::ConnectionPtr &connection, const QList &channels, const QList &requestsSatisfied, const QDateTime &userActionTime, const Tp::AbstractClientHandler::HandlerInfo &handlerInfo) { Q_UNUSED(account) Q_UNUSED(connection) Q_UNUSED(requestsSatisfied) Q_UNUSED(userActionTime) Q_UNUSED(handlerInfo) Q_FOREACH(const Tp::ChannelPtr channel, channels) { Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if (textChannel) { Tp::PendingReady *pr = textChannel->becomeReady(Tp::Features() << Tp::TextChannel::FeatureCore << Tp::TextChannel::FeatureChatState << Tp::TextChannel::FeatureMessageCapabilities << Tp::TextChannel::FeatureMessageQueue << Tp::TextChannel::FeatureMessageSentSignal); connect(pr, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onTextChannelReady(Tp::PendingOperation*))); mReadyRequests[pr] = textChannel; continue; } Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (callChannel) { Tp::PendingReady *pr = callChannel->becomeReady(Tp::Features() << Tp::CallChannel::FeatureCore << Tp::CallChannel::FeatureCallState << Tp::CallChannel::FeatureContents); connect(pr, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onCallChannelReady(Tp::PendingOperation*))); mReadyRequests[pr] = callChannel; continue; } } context->setFinished(); } Tp::ChannelClassSpecList Handler::channelFilters() { Tp::ChannelClassSpecList specList; specList << TelepathyHelper::audioConferenceSpec(); specList << Tp::ChannelClassSpec::audioCall(); specList << Tp::ChannelClassSpec::textChat(); return specList; } void Handler::onTextChannelReady(Tp::PendingOperation *op) { Tp::PendingReady *pr = qobject_cast(op); if (!pr) { qCritical() << "The pending object is not a Tp::PendingReady"; return; } Tp::ChannelPtr channel = mReadyRequests[pr]; Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel); if(!textChannel) { qCritical() << "The saved channel is not a Tp::TextChannel"; return; } mReadyRequests.remove(pr); Q_EMIT textChannelAvailable(textChannel); } void Handler::onCallChannelReady(Tp::PendingOperation *op) { Tp::PendingReady *pr = qobject_cast(op); if (!pr) { qCritical() << "The pending object is not a Tp::PendingReady"; return; } Tp::ChannelPtr channel = mReadyRequests[pr]; Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if(!callChannel) { qCritical() << "The saved channel is not a Tp::CallChannel"; return; } mReadyRequests.remove(pr); Q_EMIT callChannelAvailable(callChannel); } telephony-service-0.1+14.04.20140415/handler/com.canonical.TelephonyServiceHandler.service.in0000644000015301777760000000021012323307402032277 0ustar pbusernogroup00000000000000[D-BUS Service] Name=com.canonical.TelephonyServiceHandler Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-handler telephony-service-0.1+14.04.20140415/handler/CMakeLists.txt0000644000015301777760000000260512323307402023571 0ustar pbusernogroup00000000000000 set(qt_SRCS callhandler.cpp handler.cpp handlerdbus.cpp texthandler.cpp ) set(handler_SRCS main.cpp ${qt_SRCS}) qt5_add_dbus_adaptor(handler_SRCS Handler.xml handler/handlerdbus.h HandlerDBus) include_directories( ${TP_QT5_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_CURRENT_BINARY_DIR} ) add_executable(telephony-service-handler ${handler_SRCS} ${handler_HDRS}) qt5_use_modules(telephony-service-handler Contacts Core DBus Qml) target_link_libraries(telephony-service-handler ${TP_QT5_LIBRARIES} telephonyservice ) configure_file(com.canonical.TelephonyServiceHandler.service.in com.canonical.TelephonyServiceHandler.service) configure_file(org.freedesktop.Telepathy.Client.TelephonyServiceHandler.service.in org.freedesktop.Telepathy.Client.TelephonyServiceHandler.service) install(TARGETS telephony-service-handler RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.TelephonyServiceHandler.service DESTINATION share/dbus-1/services) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/com.canonical.TelephonyServiceHandler.service DESTINATION share/dbus-1/services) install(FILES TelephonyServiceHandler.client DESTINATION share/telepathy/clients) if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc*") message(STATUS "Tests disabled on ppc") else() add_subdirectory(tests) endif() telephony-service-0.1+14.04.20140415/handler/handler.h0000644000015301777760000000406512323307402022621 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012-2013 Canonical, Ltd. * * Authors: * Tiago Salem Herrmann * Gustavo Pichorim Boiko * * This file is part of telephony-service. * * telephony-service 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; version 3. * * telephony-service 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, see . */ #ifndef HANDLER_H #define HANDLER_H #include #include #include #include #include class Handler : public QObject, public Tp::AbstractClientHandler { Q_OBJECT public: Handler(QObject *parent = 0); ~Handler() { } bool bypassApproval() const; void handleChannels(const Tp::MethodInvocationContextPtr<> &context, const Tp::AccountPtr &account, const Tp::ConnectionPtr &connection, const QList &channels, const QList &requestsSatisfied, const QDateTime &userActionTime, const Tp::AbstractClientHandler::HandlerInfo &handlerInfo); Tp::ChannelClassSpecList channelFilters(); Q_SIGNALS: void textChannelAvailable(Tp::TextChannelPtr textChannel); void callChannelAvailable(Tp::CallChannelPtr callChannel); private Q_SLOTS: void onTextChannelReady(Tp::PendingOperation *op); void onCallChannelReady(Tp::PendingOperation *op); private: QMap mReadyRequests; }; #endif // HANDLER_H telephony-service-0.1+14.04.20140415/CMakeLists.txt0000644000015301777760000000544112323307402022155 0ustar pbusernogroup00000000000000project(telephony-service) cmake_minimum_required(VERSION 2.8) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) # Standard install paths include(GNUInstallDirs) # Check for include files include(CheckIncludeFileCXX) include(CheckIncludeFile) include(EnableCoverageReport) ##################################################################### # Enable code coverage calculation with gcov/gcovr/lcov # Usage: # * Switch build type to coverage (use ccmake or cmake-gui) # * Invoke make, make test, make coverage # * Find html report in subdir coveragereport # * Find xml report feasible for jenkins in coverage.xml ##################################################################### IF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE]) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs" ) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs" ) SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -coverage" ) SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -coverage" ) ENABLE_COVERAGE_REPORT(TARGETS ${PHONE_APP}) ENDIF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE]) # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) # Check if should build using ubuntu platform api check_include_file_cxx("ubuntu/ui/ubuntu_ui_session_service.h" USE_UBUNTU_PLATFORM_API) if (USE_UBUNTU_PLATFORM_API) add_definitions(-DUSE_UBUNTU_PLATFORM_API) endif (USE_UBUNTU_PLATFORM_API) find_program(DBUS_RUNNER dbus-test-runner) set(TELEPHONY_SERVICE_DIR ${CMAKE_INSTALL_DATADIR}/telephony-service) configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) find_package(Qt5Core) find_package(Qt5Contacts) find_package(Qt5DBus) #find_package(Qt5Gui) find_package(Qt5Multimedia) find_package(Qt5Qml) #find_package(Qt5Quick) find_package(Qt5Test) execute_process( COMMAND qmake -query QT_INSTALL_QML OUTPUT_VARIABLE QT_INSTALL_QML OUTPUT_STRIP_TRAILING_WHITESPACE ) find_package(PkgConfig REQUIRED) pkg_check_modules(TP_QT5 REQUIRED TelepathyQt5) pkg_check_modules(NOTIFY REQUIRED libnotify) pkg_check_modules(MESSAGING_MENU REQUIRED messaging-menu) pkg_check_modules(UserMetrics REQUIRED libusermetricsinput-1) pkg_check_modules(HISTORY REQUIRED history-service) add_definitions(-DQT_NO_KEYWORDS) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) enable_testing() add_definitions(-std=c++11) set(DATA_DIR "${CMAKE_SOURCE_DIR}/data") # install assets set(ASSETS_DIR assets) install(DIRECTORY ${ASSETS_DIR} DESTINATION ${TELEPHONY_SERVICE_DIR}) add_subdirectory(libtelephonyservice) add_subdirectory(Ubuntu) add_subdirectory(approver) add_subdirectory(handler) add_subdirectory(indicator) add_subdirectory(tools) add_subdirectory(icons) add_subdirectory(po) telephony-service-0.1+14.04.20140415/COPYING0000644000015301777760000010451312323307402020450 0ustar pbusernogroup00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . telephony-service-0.1+14.04.20140415/run_all_tests.sh0000755000015301777760000000007212323307402022625 0ustar pbusernogroup00000000000000#!/bin/sh export CTEST_OUTPUT_ON_FAILURE=1 make make test telephony-service-0.1+14.04.20140415/README0000644000015301777760000000007612323307402020274 0ustar pbusernogroup00000000000000This is the repository for developing the phone application