./0000755000015600001650000000000012677320772011112 5ustar jenkinsjenkins./COPYING.CC-BY-SA-30000644000015600001650000005333612677320771013413 0ustar jenkinsjenkinsCreative 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/. ./cmake/0000755000015600001650000000000012677320771012171 5ustar jenkinsjenkins./cmake/modules/0000755000015600001650000000000012677321002013625 5ustar jenkinsjenkins./cmake/modules/EnableCoverageReport.cmake0000644000015600001650000001531112677320771020702 0ustar jenkinsjenkins# - 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() ./cmake/modules/Findgcovr.cmake0000644000015600001650000000170212677320771016564 0ustar jenkinsjenkins# - 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) ./cmake/modules/GenerateTest.cmake0000644000015600001650000001440412677321002017224 0ustar jenkinsjenkins# # Copyright (C) 2015 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(CMakeParseArguments) find_program(DBUS_RUNNER dbus-test-runner) function(generate_test TESTNAME) set(options USE_DBUS USE_UI) set(oneValueArgs TIMEOUT WORKING_DIRECTORY QML_TEST WAIT_FOR) set(multiValueArgs TASKS LIBRARIES QT5_MODULES SOURCES ENVIRONMENT) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) MESSAGE(STATUS "Adding test: ${TESTNAME}") # set reasonable defaults for the arguments if (NOT DEFINED ARG_WORKING_DIRECTORY) set(ARG_WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) endif () if (NOT DEFINED ARG_TIMEOUT) set(ARG_TIMEOUT 60) endif () if (NOT DEFINED ARG_QT5_MODULES) set(ARG_QT5_MODULES Core Test) endif () if (${ARG_USE_UI}) if (${ARG_USE_DBUS}) set(PLATFORM -p -platform -p offscreen) else () set(PLATFORM -platform offscreen) endif () endif() # Generate QML tests if (DEFINED ARG_QML_TEST) add_test(NAME ${TESTNAME} WORKING_DIRECTORY ${ARG_WORKING_DIRECTORY} COMMAND qmltestrunner -platform offscreen -import ${CMAKE_BINARY_DIR} -input ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_QML_TEST}) set_tests_properties(${TESTNAME} PROPERTIES ENVIRONMENT "QT_QPA_FONTDIR=${CMAKE_BINARY_DIR}") else () # For sanity checking, make sure DBUS_RUNNER is available for DBUS tests if (${ARG_USE_DBUS} AND "${DBUS_RUNNER}" STREQUAL "") message(WARNING "Test ${TESTNAME} disabled because dbus-test-runner was not found.") return() endif () # No QML test, regular binary compiled test. add_executable(${TESTNAME} ${ARG_SOURCES}) qt5_use_modules(${TESTNAME} ${ARG_QT5_MODULES}) if (${ARG_USE_DBUS}) execute_process(COMMAND mktemp -d /tmp/${TESTNAME}.XXXXX OUTPUT_VARIABLE TMPDIR) string(REPLACE "\n" "" TMPDIR ${TMPDIR}) if (NOT DEFINED ARG_ENVIRONMENT) set(ARG_ENVIRONMENT HOME=${TMPDIR} HISTORY_SQLITE_DBPATH=:memory: MC_ACCOUNT_DIR=${TMPDIR} MC_MANAGER_DIR=${TMPDIR} MC_CLIENTS_DIR=${TMPDIR} TELEPHONY_SERVICE_TEST=1 TELEPHONY_SERVICE_PROTOCOLS_DIR=${CMAKE_SOURCE_DIR}/tests/common/protocols) endif () set(TEST_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME} ${PLATFORM} -p -o -p -,txt -p -o -p ${CMAKE_BINARY_DIR}/test_${TESTNAME}.xml,xunitxml) if (DEFINED ARG_WAIT_FOR) SET(TEST_COMMAND ${TEST_COMMAND} --wait-for ${ARG_WAIT_FOR}) endif () add_test(${TESTNAME} ${DBUS_RUNNER} --keep-env --dbus-config=${CMAKE_BINARY_DIR}/tests/common/dbus-session.conf --max-wait=${ARG_TIMEOUT} ${ARG_TASKS} --task ${TEST_COMMAND} --task-name ${TESTNAME}) else () add_test(${TESTNAME} ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME} ${PLATFORM} -o -,txt -o ${CMAKE_BINARY_DIR}/test_${TESTNAME}.xml,xunitxml) endif() set_tests_properties(${TESTNAME} PROPERTIES ENVIRONMENT "${ARG_ENVIRONMENT}" TIMEOUT ${ARG_TIMEOUT}) if (DEFINED ARG_LIBRARIES) target_link_libraries(${TESTNAME} ${ARG_LIBRARIES}) endif () enable_coverage(${TESTNAME}) endif () endfunction(generate_test) function(generate_telepathy_test TESTNAME) set(options "") set(oneValueArgs WAIT_FOR) set(multiValueArgs TASKS LIBRARIES QT5_MODULES) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) set(TASKS --task gnome-keyring-daemon -p -r -p -d --task-name gnome-keyring --ignore-return --task ${CMAKE_BINARY_DIR}/tests/common/NotificationsMock --task-name notifications --ignore-return --task /usr/lib/dconf/dconf-service --task-name dconf-service --ignore-return --task dconf -p write -p /org/gnome/empathy/use-conn -p false --task-name dconf-write --wait-for ca.desrt.dconf --ignore-return --task /usr/lib/telepathy/mission-control-5 --task-name mission-control --wait-for ca.desrt.dconf --ignore-return --task ${CMAKE_BINARY_DIR}/tests/common/mock/telepathy-mock --task-name telepathy-mock --wait-for org.freedesktop.Telepathy.MissionControl5 --ignore-return # FIXME: maybe it would be better to decide whether to run the handler in a per-test basis? --task ${CMAKE_BINARY_DIR}/handler/telephony-service-handler --task-name telephony-service-handler --wait-for org.freedesktop.Telepathy.ConnectionManager.mock --ignore-return ${ARG_TASKS}) if (NOT DEFINED ARG_LIBRARIES) set(ARG_LIBRARIES ${TP_QT5_LIBRARIES} telephonyservice mockcontroller telepathytest) endif(NOT DEFINED ARG_LIBRARIES) if (NOT DEFINED ARG_QT5_MODULES) set(ARG_QT5_MODULES Core DBus Test Qml) endif (NOT DEFINED ARG_QT5_MODULES) if (NOT DEFINED ARG_WAIT_FOR) set(ARG_WAIT_FOR org.freedesktop.Telepathy.Client.TelephonyServiceHandler) endif (NOT DEFINED ARG_WAIT_FOR) generate_test(${TESTNAME} ${ARG_UNPARSED_ARGUMENTS} TASKS ${TASKS} LIBRARIES ${ARG_LIBRARIES} QT5_MODULES ${ARG_QT5_MODULES} USE_DBUS USE_UI WAIT_FOR ${ARG_WAIT_FOR}) endfunction(generate_telepathy_test) ./cmake/modules/qt5.cmake0000644000015600001650000000310612677320771015354 0ustar jenkinsjenkins# shamelessly copied over from oxide’s build system # to enable ARM cross compilation if(CMAKE_CROSSCOMPILING) # QT_MOC_EXECUTABLE is set by Qt5CoreConfigExtras, but it sets it to # the target executable rather than the host executable, which is no # use for cross-compiling. For cross-compiling, we have a guess and # override it ourselves if(NOT TARGET Qt5::moc) find_program( QT_MOC_EXECUTABLE moc PATHS /usr/lib/qt5/bin /usr/lib/${HOST_ARCHITECTURE}/qt5/bin NO_DEFAULT_PATH) if(QT_MOC_EXECUTABLE STREQUAL "QT_MOC_EXECUTABLE-NOTFOUND") message(FATAL_ERROR "Can't find a moc executable for the host arch") endif() add_executable(Qt5::moc IMPORTED) set_target_properties(Qt5::moc PROPERTIES IMPORTED_LOCATION "${QT_MOC_EXECUTABLE}") endif() # Dummy targets - not used anywhere, but this stops Qt5CoreConfigExtras.cmake # from creating them and checking if the binary exists, which is broken when # cross-building because it checks for the target system binary. We need the # host system binaries installed, because they are in the same package as the # moc in Ubuntu (qtbase5-dev-tools), which is not currently multi-arch if(NOT TARGET Qt5::qmake) add_executable(Qt5::qmake IMPORTED) endif() if(NOT TARGET Qt5::rcc) add_executable(Qt5::rcc IMPORTED) endif() if(NOT TARGET Qt5::uic) add_executable(Qt5::uic IMPORTED) endif() if(NOT TARGET Qt5::DBus) add_executable(Qt5::DBus IMPORTED) endif() else() # This should be enough to initialize QT_MOC_EXECUTABLE find_package(Qt5Core) endif() ./cmake/modules/FindLibPhoneNumber.cmake0000644000015600001650000000141412677320771020315 0ustar jenkinsjenkinsset(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) include(GNUInstallDirs) include(LibFindMacros) # Include dir find_path(LibPhoneNumber_INCLUDE_DIR NAMES phonenumberutil.h PATHS "/usr/local/${CMAKE_INSTALL_INCLUDEDIR}" ${CMAKE_INSTALL_FULL_INCLUDEDIR} PATH_SUFFIXES "phonenumbers" ) # library itself find_library(LibPhoneNumber_LIBRARY NAMES phonenumber PATHS "/usr/local/${CMAKE_INSTALL_LIBDIR}" ${CMAKE_INSTALL_FULL_LIBDIR} ) # Set the include dir variables and the libraries and let libfind_process do the rest. # NOTE: Singular variables for this library, plural for libraries this this lib depends on. set(LibPhoneNumber_PROCESS_INCLUDES LibPhoneNumber_INCLUDE_DIR) set(LibPhoneNumber_PROCESS_LIBS LibPhoneNumber_LIBRARY) libfind_process(LibPhoneNumber) ./cmake/modules/ParseArguments.cmake0000644000015600001650000000340612677320771017606 0ustar jenkinsjenkins# 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) ./cmake/modules/LibFindMacros.cmake0000644000015600001650000001106012677320771017315 0ustar jenkinsjenkins# Version 1.0 (2013-04-12) # Public Domain, originally written by Lasse Kärkkäinen # Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries # If you improve the script, please modify the forementioned wiki page because # I no longer maintain my scripts (hosted as static files at zi.fi). Feel free # to remove this entire header if you use real version control instead. # Changelog: # 2013-04-12 Added version number (1.0) and this header, no other changes # 2009-10-08 Originally published # Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments # used for the current package. For this to work, the first parameter must be the # prefix of the current package, then the prefix of the new package etc, which are # passed to find_package. macro (libfind_package PREFIX) set (LIBFIND_PACKAGE_ARGS ${ARGN}) if (${PREFIX}_FIND_QUIETLY) set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET) endif (${PREFIX}_FIND_QUIETLY) if (${PREFIX}_FIND_REQUIRED) set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED) endif (${PREFIX}_FIND_REQUIRED) find_package(${LIBFIND_PACKAGE_ARGS}) endmacro (libfind_package) # CMake developers made the UsePkgConfig system deprecated in the same release (2.6) # where they added pkg_check_modules. Consequently I need to support both in my scripts # to avoid those deprecated warnings. Here's a helper that does just that. # Works identically to pkg_check_modules, except that no checks are needed prior to use. macro (libfind_pkg_check_modules PREFIX PKGNAME) if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) include(UsePkgConfig) pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS) else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) find_package(PkgConfig) if (PKG_CONFIG_FOUND) pkg_check_modules(${PREFIX} ${PKGNAME}) endif (PKG_CONFIG_FOUND) endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) endmacro (libfind_pkg_check_modules) # Do the final processing once the paths have been detected. # If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain # all the variables, each of which contain one include directory. # Ditto for ${PREFIX}_PROCESS_LIBS and library files. # Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. # Also handles errors in case library detection was required, etc. macro (libfind_process PREFIX) # Skip processing if already processed during this run if (NOT ${PREFIX}_FOUND) # Start with the assumption that the library was found set (${PREFIX}_FOUND TRUE) # Process all includes and set _FOUND to false if any are missing foreach (i ${${PREFIX}_PROCESS_INCLUDES}) if (${i}) set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}}) mark_as_advanced(${i}) else (${i}) set (${PREFIX}_FOUND FALSE) endif (${i}) endforeach (i) # Process all libraries and set _FOUND to false if any are missing foreach (i ${${PREFIX}_PROCESS_LIBS}) if (${i}) set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}}) mark_as_advanced(${i}) else (${i}) set (${PREFIX}_FOUND FALSE) endif (${i}) endforeach (i) # Print message and/or exit on fatal error if (${PREFIX}_FOUND) if (NOT ${PREFIX}_FIND_QUIETLY) message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}") endif (NOT ${PREFIX}_FIND_QUIETLY) else (${PREFIX}_FOUND) if (${PREFIX}_FIND_REQUIRED) foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS}) message("${i}=${${i}}") endforeach (i) message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.") endif (${PREFIX}_FIND_REQUIRED) endif (${PREFIX}_FOUND) endif (NOT ${PREFIX}_FOUND) endmacro (libfind_process) macro(libfind_library PREFIX basename) set(TMP "") if(MSVC80) set(TMP -vc80) endif(MSVC80) if(MSVC90) set(TMP -vc90) endif(MSVC90) set(${PREFIX}_LIBNAMES ${basename}${TMP}) if(${ARGC} GREATER 2) set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2}) string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES}) set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP}) endif(${ARGC} GREATER 2) find_library(${PREFIX}_LIBRARY NAMES ${${PREFIX}_LIBNAMES} PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS} ) endmacro(libfind_library) ./cmake/modules/FindLcov.cmake0000644000015600001650000000172012677320771016347 0ustar jenkinsjenkins# - 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) ./indicator/0000755000015600001650000000000012677320776013072 5ustar jenkinsjenkins./indicator/ussdindicator.h0000644000015600001650000000370212677320771016113 0ustar jenkinsjenkins/* * 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 "notificationmenu.h" #include "ofonoaccountentry.h" class USSDIndicator : public QObject { Q_OBJECT public: explicit USSDIndicator(QObject *parent = 0); void showUSSDNotification(const QString &message, bool replyRequired, USSDManager *ussdManager); 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); void clear(); private Q_SLOTS: void setupAccounts(); private: unsigned int m_notificationId; NotificationMenu m_menuRequest; NotificationMenu m_menuNotification; QString mPendingMessage; org::freedesktop::Notifications m_notifications; QMap mUSSDRequests; QList mAccounts; }; #endif // USSDINDICATOR_H ./indicator/Indicator.xml0000644000015600001650000000174012677320771015525 0ustar jenkinsjenkins An interface to the phone indicator application. ./indicator/org.freedesktop.Telepathy.Client.TelephonyServiceIndicator.service.in0000644000015600001650000000023712677320771030456 0ustar jenkinsjenkins[D-BUS Service] Name=org.freedesktop.Telepathy.Client.TelephonyServiceIndicator Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-indicator ./indicator/main.cpp0000644000015600001650000000736712677320771014532 0ustar jenkinsjenkins/* * 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 "indicatordbus.h" #include "metrics.h" #include "telepathyhelper.h" #include "textchannelobserver.h" #include "voicemailindicator.h" #include "ussdindicator.h" #include "authhandler.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; } #ifdef USE_UBUNTU_PLATFORM_API // required to make qtsensors work qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient"); #endif // we don't need to call anything on the indicator, it will work by itself // make sure we create the voicemail indicator before the telepathy helper VoiceMailIndicator voiceMailIndicator; Q_UNUSED(voiceMailIndicator); // create the dbus object and connect its signals USSDIndicator ussdIndicator; AuthHandler authHandler; IndicatorDBus dbus; QObject::connect(&dbus, SIGNAL(clearNotificationsRequested()), &ussdIndicator, SLOT(clear())); QObject::connect(&dbus, SIGNAL(clearNotificationsRequested()), &authHandler, SLOT(clear())); // register the observer QObject::connect(TelepathyHelper::instance(), &TelepathyHelper::setupReady, [&]() { 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))); QObject::connect(&dbus, SIGNAL(clearNotificationsRequested()), textObserver, SLOT(clearNotifications())); }); // instanciate the metrics helper Metrics::instance(); dbus.connectToBus(); return app.exec(); } ./indicator/textchannelobserver.h0000644000015600001650000000525412677320771017331 0ustar jenkinsjenkins/* * Copyright (C) 2012-2014 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 QTCONTACTS_USE_NAMESPACE class NotificationData; class TextChannelObserver : public QObject { Q_OBJECT public: explicit TextChannelObserver(QObject *parent = 0); ~TextChannelObserver(); public Q_SLOTS: void onTextChannelAvailable(Tp::TextChannelPtr textChannel); void sendMessage(const QStringList &recipients, const QString &text, const QString &accountId); void clearNotifications(); protected: void showNotificationForFlashMessage(const Tp::ReceivedMessage &message, const QString &accountId); void triggerNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds = QStringList()); void showNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds = QStringList(), const QContact &contact = QContact()); protected Q_SLOTS: void onTextChannelInvalidated(); void onMessageReceived(const Tp::ReceivedMessage &message); void onPendingMessageRemoved(const Tp::ReceivedMessage &message); void onReplyReceived(const QStringList &recipients, const QString &accountId, const QString &reply); void onMessageRead(const QStringList &recipients, const QString &accountId, const QString &encodedMessageId); void onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString); void updateNotifications(const QtContacts::QContact &contact); private: void processMessageReceived(const Tp::ReceivedMessage &message, const Tp::TextChannelPtr &textChannel); QList mChannels; QList mFlashChannels; QMap mNotifications; QList mUnreadMessages; }; #endif // TEXTCHANNELOBSERVER_H ./indicator/metrics.cpp0000644000015600001650000000716612677320771015251 0ustar jenkinsjenkins/* * 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"); #define GettextMarkExtraction(x) x using namespace UserMetricsInput; Metrics::Metrics(QObject *parent) : QObject(parent) { try { mMetricManager.reset(MetricManager::getInstance()); mMetrics[SentMessages] = mMetricManager->add(MetricParameters(MESSAGES_SENT_STATISTICS_ID).formatString(GettextMarkExtraction("%1 text messages sent today")) .emptyDataString(GettextMarkExtraction("No text messages sent today")).textDomain(APP_ID).minimum(0.0)); mMetrics[ReceivedMessages] = mMetricManager->add(MetricParameters(MESSAGES_RECEIVED_STATISTICS_ID).formatString(GettextMarkExtraction("%1 text messages received today")) .emptyDataString(GettextMarkExtraction("No text messages received today")).textDomain(APP_ID).minimum(0.0)); mMetrics[IncomingCalls] = mMetricManager->add(MetricParameters(DIALER_INCOMING_STATISTICS_ID).formatString(GettextMarkExtraction("%1 calls received today")) .emptyDataString(GettextMarkExtraction("No calls received today")).textDomain(APP_ID).minimum(0.0)); mMetrics[OutgoingCalls] = mMetricManager->add(MetricParameters(DIALER_OUTGOING_STATISTICS_ID).formatString(GettextMarkExtraction("%1 calls made today")) .emptyDataString(GettextMarkExtraction("No calls made today")).textDomain(APP_ID).minimum(0.0)); mMetrics[CallDurations] = mMetricManager->add(MetricParameters(DIALER_CALL_DURATION_STATISTICS_ID).formatString(GettextMarkExtraction("Spent %1 minutes in calls today")) .emptyDataString(GettextMarkExtraction("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(); } } ./indicator/metrics.h0000644000015600001650000000264512677320771014713 0ustar jenkinsjenkins/* * 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 ./indicator/TelephonyServiceIndicator.client0000644000015600001650000000201512677320771021410 0ustar jenkinsjenkins[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.ObserverChannelFilter 2] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=0 [org.freedesktop.Telepathy.Client.Observer.Capabilities] org.freedesktop.Telepathy.Channel.Type.Call1/audio=true org.freedesktop.Telepathy.Channel.Type.Call1/audio/speex=true [org.freedesktop.Telepathy.Client.Observer] Recover=true ./indicator/voicemailindicator.cpp0000644000015600001650000000510112677320771017433 0ustar jenkinsjenkins/* * 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 "accountentry.h" #include "ofonoaccountentry.h" #include #include VoiceMailIndicator::VoiceMailIndicator(QObject *parent) : QObject(parent), mConnection(QDBusConnection::sessionBus()) { connect(TelepathyHelper::instance(), SIGNAL(setupReady()), SLOT(onAccountReady())); connect(TelepathyHelper::instance(), SIGNAL(accountsChanged()), SLOT(onAccountReady())); } void VoiceMailIndicator::onAccountReady() { Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { OfonoAccountEntry *ofonoAccount = qobject_cast(account); if (!ofonoAccount) { continue; } // disconnect previous signals if any disconnect(ofonoAccount, SIGNAL(voicemailIndicatorChanged()), this, SLOT(onVoicemailIndicatorChanged())); disconnect(ofonoAccount, SIGNAL(voicemailCountChanged()), this, SLOT(onVoicemailIndicatorChanged())); connect(ofonoAccount, SIGNAL(voicemailIndicatorChanged()), this, SLOT(onVoicemailIndicatorChanged())); connect(ofonoAccount, SIGNAL(voicemailCountChanged()), this, SLOT(onVoicemailIndicatorChanged())); if (ofonoAccount->voicemailIndicator()) { MessagingMenu::instance()->showVoicemailEntry(account); } else { MessagingMenu::instance()->hideVoicemailEntry(account); } } } void VoiceMailIndicator::onVoicemailIndicatorChanged() { OfonoAccountEntry *ofonoAccount = qobject_cast(sender()); if (!ofonoAccount) { return; } if (ofonoAccount->voicemailIndicator()) { MessagingMenu::instance()->showVoicemailEntry(ofonoAccount); } else { MessagingMenu::instance()->hideVoicemailEntry(ofonoAccount); } } ./indicator/DBusTypes.h0000644000015600001650000000206512677320771015123 0ustar jenkinsjenkins/* * 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_ */ ./indicator/callchannelobserver.cpp0000644000015600001650000000753112677320771017613 0ustar jenkinsjenkins/* * 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 "accountentry.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; } AccountEntry *accountEntry = TelepathyHelper::instance()->accountForConnection(channel->connection()); if (!accountEntry) { return; } bool incoming = channel->initiatorContact() != accountEntry->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(), accountEntry->accountId(), 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); } } ./indicator/indicatordbus.h0000644000015600001650000000265012677320771016073 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 INDICATORDBUS_H #define INDICATORDBUS_H #include #include #include "chatmanager.h" /** * DBus interface for the phone approver */ class IndicatorDBus : public QObject, protected QDBusContext { Q_OBJECT public: IndicatorDBus(QObject* parent=0); ~IndicatorDBus(); bool connectToBus(); public Q_SLOTS: Q_NOREPLY void ClearNotifications(); Q_NOREPLY void ClearCallNotification(const QString &targetId, const QString &accountId); Q_SIGNALS: void clearNotificationsRequested(); }; #endif // INDICATORDBUS_H ./indicator/voicemailindicator.h0000644000015600001650000000222412677320771017103 0ustar jenkinsjenkins/* * 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 onVoicemailIndicatorChanged(); void onAccountReady(); private: QDBusConnection mConnection; }; #endif // VOICEMAILINDICATOR_H ./indicator/ussdindicator.cpp0000644000015600001650000001432612677320771016452 0ustar jenkinsjenkins/* * 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" #include "ofonoaccountentry.h" #include "telepathyhelper.h" USSDIndicator::USSDIndicator(QObject *parent) : QObject(parent), m_menuRequest("ussd", true), m_menuNotification("ussd", false), m_notificationId(-1), m_notifications("org.freedesktop.Notifications", "/org/freedesktop/Notifications", QDBusConnection::sessionBus()) { setupAccounts(); connect(TelepathyHelper::instance(), SIGNAL(accountsChanged()), this, SLOT(setupAccounts())); 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::setupAccounts() { Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { OfonoAccountEntry *ofonoAccount = qobject_cast(account); if (!ofonoAccount) { continue; } connect(ofonoAccount->ussdManager(), SIGNAL(notificationReceived(const QString &)), SLOT(onNotificationReceived(const QString &)), Qt::UniqueConnection); connect(ofonoAccount->ussdManager(), SIGNAL(requestReceived(const QString &)), SLOT(onRequestReceived(const QString &)), Qt::UniqueConnection); connect(ofonoAccount->ussdManager(), SIGNAL(initiateUSSDComplete(const QString &)), SLOT(onInitiateUSSDComplete(const QString &)), Qt::UniqueConnection); connect(ofonoAccount->ussdManager(), SIGNAL(respondComplete(bool, const QString &)), SLOT(onRespondComplete(bool, const QString &)), Qt::UniqueConnection); connect(ofonoAccount->ussdManager(), SIGNAL(stateChanged(const QString &)), SLOT(onStateChanged(const QString &)), Qt::UniqueConnection); } } void USSDIndicator::onNotificationReceived(const QString &message) { USSDManager *ussdManager = qobject_cast(sender()); if (!ussdManager) { return; } showUSSDNotification(message, false, ussdManager); } void USSDIndicator::onRequestReceived(const QString &message) { USSDManager *ussdManager = qobject_cast(sender()); if (!ussdManager) { return; } showUSSDNotification(message, true, ussdManager); } void USSDIndicator::onInitiateUSSDComplete(const QString &ussdResp) { USSDManager *ussdManager = qobject_cast(sender()); if (!ussdManager) { return; } showUSSDNotification(ussdResp, (ussdManager->state() == "user-response"), ussdManager); } void USSDIndicator::onRespondComplete(bool success, const QString &ussdResp) { USSDManager *ussdManager = qobject_cast(sender()); if (!ussdManager) { return; } if (success) { showUSSDNotification(ussdResp, (ussdManager->state() == "user-response"), ussdManager); } } void USSDIndicator::onStateChanged(const QString &state) { if (m_notificationId == -1) { return; } if (state == "idle") { m_notifications.CloseNotification(m_notificationId); } } void USSDIndicator::showUSSDNotification(const QString &message, bool replyRequired, USSDManager *ussdManager) { NotificationMenu *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"; notificationHints["x-canonical-snap-decisions-timeout"] = -1; 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); mUSSDRequests[m_notificationId] = ussdManager; Ringtone::instance()->playIncomingMessageSound(); } void USSDIndicator::actionInvoked(uint id, const QString &actionKey) { if (id != m_notificationId) { return; } USSDManager *ussdManager = mUSSDRequests.take(id); if (!ussdManager) { return; } m_notificationId = -1; if (actionKey == "reply_id") { ussdManager->respond(m_menuRequest.response()); } else if (actionKey == "cancel_id") { ussdManager->cancel(); } m_menuRequest.clearResponse(); } void USSDIndicator::notificationClosed(uint id, uint reason) { if (id != m_notificationId) { return; } m_notificationId = -1; } void USSDIndicator::clear() { if (m_notificationId != -1) { USSDManager *ussdManager = mUSSDRequests.take(m_notificationId); if (ussdManager) { ussdManager->cancel(); } m_notifications.CloseNotification(m_notificationId); m_notificationId = -1; } } ./indicator/icons/0000755000015600001650000000000012677320772014201 5ustar jenkinsjenkins./indicator/icons/notification-unavailable-image-call.svg0000644000015600001650000001212112677320771023656 0ustar jenkinsjenkins ./indicator/icons/notification-unknown-call.svg0000644000015600001650000001210212677320771022011 0ustar jenkinsjenkins ./indicator/icons/notification-group-call.svg0000644000015600001650000002533112677320771021456 0ustar jenkinsjenkins ./indicator/icons/CMakeLists.txt0000644000015600001650000000036312677320771016742 0ustar jenkinsjenkinsset (icon-theme Humanity) set(icons notification-group-call.svg notification-unavailable-image-call.svg notification-unknown-call.svg ) install(FILES ${icons} DESTINATION share/notify-osd/icons/${icon-theme}/scalable/status) ./indicator/notificationmenu.h0000644000015600001650000000247612677320771016622 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 NOTIFICATIONMENU_H_ #define NOTIFICATIONMENU_H_ #include #include class NotificationMenuPriv; class NotificationMenu { public: NotificationMenu(const QString &id, bool needsResponse = false, bool password = false); virtual ~NotificationMenu(); const QString & id() const; const QString & busName() const; const QString & response() const; const QString & actionPath() const; const QString & menuPath() const; void clearResponse(); protected: QScopedPointer p; }; #endif /* NOTIFICATIONMENU_H_ */ ./indicator/messagingmenu.h0000644000015600001650000000655412677320771016112 0ustar jenkinsjenkins/* * 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 #include "accountentry.h" class Call { public: Call() : count(0) { } QString targetId; int count; QString contactAlias; QUrl contactIcon; QString messageId; QString accountId; QDateTime timestamp; bool operator==(const Call &other) { return other.targetId == targetId; } }; class MessagingMenu : public QObject { Q_OBJECT public: static MessagingMenu *instance(); virtual ~MessagingMenu(); void addMessage(const QString &senderId, const QString &contactAlias, const QStringList &participantIds, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text); void addFlashMessage(const QString &senderId, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text); void removeMessage(const QString &messageId); void addCall(const QString &targetId, const QString &accountId, const QDateTime ×tamp); void removeCall(const QString &targetId, const QString &accountId); void addCallToMessagingMenu(Call call, const QString &text); 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(AccountEntry *account); void hideVoicemailEntry(AccountEntry *account); Q_SIGNALS: void replyReceived(const QStringList &recipients, const QString &accountId, const QString &reply); void messageRead(const QStringList &recipients, const QString &accountId, 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; QStringList mVoicemailIds; int mVoicemailCount; }; #endif // MESSAGINGMENU_H ./indicator/notificationmenu.cpp0000644000015600001650000001103412677320771017143 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "notificationmenu.h" #include #include #include static const QString ACTION_PATH("/action/%1"); static const QString MENU_PATH("/menu/%1"); class NotificationMenuPriv { public: NotificationMenuPriv() : m_connection(g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL)), m_exportedActionGroupId(0), m_exportedMenuModelId(0) { } ~NotificationMenuPriv() { g_object_unref(m_connection); } static void responseChangedCallback(GAction *responseAction, GVariant *variant, gpointer userData) { NotificationMenuPriv *self(reinterpret_cast(userData)); self->m_response = QString::fromUtf8(g_variant_get_string(variant, 0)); } GDBusConnection *m_connection; QString m_id; QString m_busName; QString m_actionPath; QString m_menuPath; unsigned int m_exportedActionGroupId; unsigned int m_exportedMenuModelId; QString m_response; }; NotificationMenu::NotificationMenu(const QString &id, bool needsResponse, bool password) : p(new NotificationMenuPriv()) { int exportrev; p->m_id = id; p->m_busName = QString::fromUtf8( g_dbus_connection_get_unique_name(p->m_connection)); // menu GMenu *menu(g_menu_new()); GMenuItem *item(g_menu_item_new("", QString("notifications.%1").arg(id).toLatin1().data())); if (needsResponse) { g_menu_item_set_attribute_value(item, "x-canonical-type", g_variant_new_string("com.canonical.snapdecision.textfield")); g_menu_item_set_attribute_value(item, "x-echo-mode-password", g_variant_new_boolean(password)); g_menu_append_item(menu, item); } // actions GActionGroup *actions(G_ACTION_GROUP(g_simple_action_group_new())); GAction *action(G_ACTION( g_simple_action_new_stateful(id.toLatin1().data(), G_VARIANT_TYPE_STRING, g_variant_new_string("")))); g_signal_connect(G_OBJECT(action), "change-state", G_CALLBACK(NotificationMenuPriv::responseChangedCallback), reinterpret_cast(p.data())); g_action_map_add_action(G_ACTION_MAP(actions), action); /* 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 = 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 = 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(item); g_object_unref(actions); g_object_unref(action); } NotificationMenu::~NotificationMenu() { 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 &NotificationMenu::id() const { return p->m_id; } const QString & NotificationMenu::busName() const { return p->m_busName; } const QString & NotificationMenu::response() const { return p->m_response; } const QString & NotificationMenu::actionPath() const { return p->m_actionPath; } const QString & NotificationMenu::menuPath() const { return p->m_menuPath; } void NotificationMenu::clearResponse() { p->m_response.clear(); } ./indicator/telephony-service-call.desktop.in0000644000015600001650000000025612677320771021446 0ustar jenkinsjenkins[Desktop Entry] Type=Application Name=tr("Phone Calls") Exec=telephony-service-indicator Icon=telephony-service-call NoDisplay=true X-Ubuntu-Gettext-Domain=telephony-service ./indicator/authhandler.cpp0000644000015600001650000001211712677320771016072 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "applicationutils.h" #include "authhandler.h" #include "telepathyhelper.h" // FIXME: port to libqmenumodel if possible AuthHandler::AuthHandler(QObject *parent) : QObject(parent), mMenuNotification("authentication", false), mNotifications("org.freedesktop.Notifications", "/org/freedesktop/Notifications", QDBusConnection::sessionBus()) { setupAccounts(); connect(TelepathyHelper::instance(), SIGNAL(setupReady()), this, SLOT(setupAccounts())); connect(TelepathyHelper::instance(), SIGNAL(accountsChanged()), this, SLOT(setupAccounts())); connect(&mNotifications, SIGNAL(ActionInvoked(uint, const QString &)), this, SLOT(actionInvoked(uint, const QString &))); connect(&mNotifications, SIGNAL(NotificationClosed(uint, uint)), this, SLOT(notificationClosed(uint, uint))); connect(TelepathyHelper::instance(), &TelepathyHelper::setupReady, [&]() { Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { processStatusChange(account, account->account()->connectionStatus()); } }); } void AuthHandler::setupAccounts() { Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { connect(account, SIGNAL(connectionStatusChanged(Tp::ConnectionStatus)), SLOT(onConnectionStatusChanged(Tp::ConnectionStatus)), Qt::UniqueConnection); } } void AuthHandler::onConnectionStatusChanged(Tp::ConnectionStatus status) { AccountEntry *account = qobject_cast(sender()); if (!account) { return; } processStatusChange(account, status); } void AuthHandler::processStatusChange(AccountEntry *account, Tp::ConnectionStatus status) { QString title; QString message = QString::fromUtf8(C::gettext("Authentication failed. Do you want to review your credentials?")); if (status == Tp::ConnectionStatusDisconnected && account->account()->connectionStatusReason() == Tp::ConnectionStatusReasonAuthenticationFailed && !mIgnoredAccounts.contains(account->accountId())) { QString serviceAndDisplayName; QString displayName = account->displayName(); if (displayName.isEmpty()) { serviceAndDisplayName = account->account()->serviceName(); } else { serviceAndDisplayName = QString("%1: %2").arg(account->account()->serviceName()).arg(displayName); } title = serviceAndDisplayName; } else { return; } NotificationMenu *menu = &mMenuNotification; QString yesActionId = "yes_id"; QString yesActionLabel = C::gettext("Yes"); QString noActionId = "no_id"; QString noActionLabel = C::gettext("No"); QStringList actions; actions << yesActionId << yesActionLabel << noActionId << noActionLabel; // 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; uint notificationId = mNotifications.Notify("telephony-service-indicator", 0, "", title, message, actions, notificationHints, 0); mAuthFailureRequests[notificationId] = account; } void AuthHandler::actionInvoked(uint id, const QString &actionKey) { if (!mAuthFailureRequests.keys().contains(id)) { return; } if (actionKey == "yes_id") { ApplicationUtils::openUrl(QString("settings:///system/online-accounts")); } else { mIgnoredAccounts << mAuthFailureRequests[id]->accountId(); } } void AuthHandler::notificationClosed(uint id, uint reason) { if (!mAuthFailureRequests.keys().contains(id)) { return; } mNotifications.CloseNotification(id); mAuthFailureRequests.remove(id); } void AuthHandler::clear() { Q_FOREACH (uint id, mAuthFailureRequests.keys()) { mAuthFailureRequests.remove(id); mNotifications.CloseNotification(id); } } ./indicator/messagingmenu.cpp0000644000015600001650000005775212677320771016453 0ustar jenkinsjenkins/* * 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 "accountentry.h" #include "ofonoaccountentry.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) { 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 &senderId, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text) { QUrl iconPath = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); QString contactAlias = senderId; 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["senderId"] = senderId; details["accountId"] = accountId; 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 &senderId, const QString &contactAlias, const QStringList &participantIds, const QString &accountId, 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"); AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return; } // FIXME: for accounts not based on phone number, we need to match other fields. // Right now we don't even bother trying to match contact data // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(senderId)); QVariantMap details; details["senderId"] = senderId; details["accountId"] = accountId; details["participantIds"] = participantIds; mMessages[messageId] = details; // 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, senderId, participantIds, accountId, messageId, text, timestamp, iconPath, contactAlias, this](QContactAbstractRequest::State newState) { GFile *file = NULL; GIcon *icon = NULL; // only process the results after the finished state is reached // also, if the ack happens before contacts service return the request we have to // simply skip this if (newState != QContactAbstractRequest::FinishedState || !mMessages.contains(messageId)) { return; } QString displayLabel; QString subTitle; QUrl avatar; if (senderId == OFONO_UNKNOWN_NUMBER) { displayLabel = C::gettext("Unknown number"); } else 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 (participantIds.size() > 1) { displayLabel = QString::fromUtf8(C::gettext("Message to group from %1")).arg(displayLabel); avatar = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/contact-group.svg"); } AccountEntry::addAccountLabel(accountId, displayLabel); if (avatar.isEmpty()) { avatar = iconPath; } if (!icon) { file = g_file_new_for_uri(avatar.toString().toUtf8().data()); icon = g_file_icon_new(file); } MessagingMenuMessage *message = messaging_menu_message_new(messageId.toUtf8().data(), icon, displayLabel.toUtf8().data(), subTitle.toUtf8().data(), text.toUtf8().data(), timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds messaging_menu_message_add_action(message, "quickReply", C::gettext("Send"), // label G_VARIANT_TYPE("s"), NULL // predefined values ); g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::messageActivateCallback), this); messaging_menu_app_append_message(mMessagesApp, message, SOURCE_ID, true); if (file) { g_object_unref(file); } g_object_unref(icon); g_object_unref(message); }); // FIXME: For accounts not based on phone numbers, don't try to match contacts for now if (account->type() == AccountEntry::PhoneAccount || account->type() == AccountEntry::MultimediaAccount) { request->setManager(ContactUtils::sharedManager()); request->start(); } else { // just emit the signal to pretend we did a contact search Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState); } } 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::addCallToMessagingMenu(Call call, const QString &text) { GVariant *messages = NULL; GFile *file = g_file_new_for_uri(call.contactIcon.toString().toUtf8().data()); GIcon *icon = g_file_icon_new(file); MessagingMenuMessage *message = messaging_menu_message_new(call.targetId.toUtf8().data(), icon, call.contactAlias.toUtf8().data(), NULL, text.toUtf8().data(), call.timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds call.messageId = messaging_menu_message_get_id(message); if (call.targetId != OFONO_PRIVATE_NUMBER && call.targetId != OFONO_UNKNOWN_NUMBER) { messaging_menu_message_add_action(message, "callBack", C::gettext("Call back"), // 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 }; messages = g_variant_new_strv(predefinedMessages, -1); messaging_menu_message_add_action(message, "replyWithMessage", C::gettext("Send"), // 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(call); g_object_unref(file); g_object_unref(icon); g_object_unref(message); } void MessagingMenu::addCall(const QString &targetId, const QString &accountId, const QDateTime ×tamp) { Call call; bool found = false; AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return; } Q_FOREACH(Call callMessage, mCalls) { // FIXME: we need a better strategy to group calls from different accounts if (account->compareIds(callMessage.targetId, targetId) && callMessage.accountId == accountId) { 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 = targetId; call.accountId = accountId; call.contactIcon = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); call.targetId = targetId; call.count = 0; } call.count++; call.timestamp = timestamp; QString text; text = QString::fromUtf8(C::ngettext("%1 missed call", "%1 missed calls", call.count)).arg(call.count); AccountEntry::addAccountLabel(accountId, text); if (targetId.startsWith(OFONO_PRIVATE_NUMBER)) { call.contactAlias = C::gettext("Private number"); addCallToMessagingMenu(call, text); return; } else if (targetId.startsWith(OFONO_UNKNOWN_NUMBER)) { call.contactAlias = C::gettext("Unknown number"); addCallToMessagingMenu(call, text); return; } // FIXME: we need to match other fields for accounts not based on phone numbers. // For now we are not even trying to match contact data // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(targetId)); //FIXME: on arm64 the connect() statement below fails at runtime with the following output: //QObject::connect: signal not found in QtContacts::QContactFetchRequest // so we just disable it #ifndef __aarch64__ // 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, this]() { // only process the results after the finished state is reached if (request->state() != QContactAbstractRequest::FinishedState) { return; } #endif 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; } } addCallToMessagingMenu(newCall, text); #ifndef __aarch64__ }); // FIXME: For accounts not based on phone numbers, don't try to match contacts for now if (account->type() == AccountEntry::PhoneAccount) { request->setManager(ContactUtils::sharedManager()); request->start(); } else { // just emit the signal to pretend we did a contact search Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState); } #endif } void MessagingMenu::removeCall(const QString &targetId, const QString &accountId) { Call call; bool found = false; AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { qWarning() << "Account not found for id" << accountId; return; } Q_FOREACH(Call callMessage, mCalls) { // FIXME: we need a better strategy to group calls from different accounts if (account->compareIds(callMessage.targetId, targetId) && callMessage.accountId == accountId) { 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; } } } void MessagingMenu::showVoicemailEntry(AccountEntry *account) { OfonoAccountEntry *ofonoAccount = qobject_cast(account); if (!ofonoAccount) { return; } messaging_menu_app_remove_message_by_id(mCallsApp, account->accountId().toUtf8().data()); mVoicemailIds.removeAll(account->accountId()); QString messageBody = C::gettext("Voicemail messages"); uint count = ofonoAccount->voicemailCount(); 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"); QString accountLabel(C::gettext("Voicemail")); AccountEntry::addAccountLabel(account->accountId(), accountLabel); MessagingMenuMessage *message = messaging_menu_message_new(account->accountId().toUtf8().data(), icon, accountLabel.toUtf8().data(), 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); mVoicemailIds.append(ofonoAccount->accountId()); g_object_unref(icon); g_object_unref(message); } void MessagingMenu::hideVoicemailEntry(AccountEntry *account) { mVoicemailIds.removeAll(account->accountId()); messaging_menu_app_remove_message_by_id(mCallsApp, account->accountId().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 (instance->mVoicemailIds.contains(messageId)) { 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) { QVariantMap message = mMessages[messageId]; QString senderId = message["senderId"].toString(); QString accountId = message["accountId"].toString(); QStringList participantIds = message["participantIds"].toStringList(); QStringList recipients; if (!senderId.isEmpty()) { recipients << senderId; } recipients << participantIds; recipients.removeDuplicates(); Q_EMIT replyReceived(recipients, accountId, reply); Q_EMIT messageRead(recipients, accountId, messageId); } void MessagingMenu::saveFlashMessage(const QString &messageId) { QVariantMap details = mMessages[messageId]; AccountEntry *account = TelepathyHelper::instance()->accountForId(details["accountId"].toString()); bool phoneNumberBased = account && (account->type() == AccountEntry::PhoneAccount); History::Thread thread = History::Manager::instance()->threadForParticipants(details["accountId"].toString(), History::EventTypeText, QStringList() << details["senderId"].toString(), phoneNumberBased ? History::MatchPhoneNumber : History::MatchCaseSensitive, true); History::TextEvent textEvent(details["accountId"].toString(), thread.threadId(), details["messageId"].toString(), details["senderId"].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) { QVariantMap message = mMessages[messageId]; QString senderId = message["senderId"].toString(); QString accountId = message["accountId"].toString(); QStringList participantIds = message["participantIds"].toStringList(); QStringList recipients; if (!senderId.isEmpty()) { recipients << senderId; } recipients << participantIds; recipients.removeDuplicates(); QString url(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(recipients.join(";"))))); AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (account && account->type() == AccountEntry::GenericAccount) { url += QString("?accountId=%1").arg(QString(QUrl::toPercentEncoding(accountId))); } ApplicationUtils::openUrl(url); } void MessagingMenu::callBack(const QString &messageId) { Call call = callFromMessageId(messageId); AccountEntry *account = TelepathyHelper::instance()->accountForId(call.accountId); if (!account) { qWarning() << "Could not find the account originating the call"; } qDebug() << "TelephonyService/MessagingMenu: Calling back" << call.targetId; // FIXME: support accounts not based on phone numbers if (account->type() == AccountEntry::PhoneAccount || account->type() == AccountEntry::MultimediaAccount) { ApplicationUtils::openUrl(QString("tel:///%1").arg(QString(QUrl::toPercentEncoding(call.targetId)))); } } void MessagingMenu::replyWithMessage(const QString &messageId, const QString &reply) { Call call = callFromMessageId(messageId); qDebug() << "TelephonyService/MessagingMenu: Replying to call" << call.targetId << "with text" << reply; Q_EMIT replyReceived(QStringList() << call.targetId, call.accountId, reply); } void MessagingMenu::callVoicemail(const QString &messageId) { QString voicemailNumber; // get the corresponding account OfonoAccountEntry *ofonoAccount = qobject_cast(TelepathyHelper::instance()->accountForId(messageId)); if (ofonoAccount) { voicemailNumber = ofonoAccount->voicemailNumber(); } qDebug() << "TelephonyService/MessagingMenu: Calling voicemail for messageId" << messageId; if (!voicemailNumber.isEmpty()) { // FIXME: we need to specify which account to use 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); } ./indicator/callchannelobserver.h0000644000015600001650000000245512677320771017260 0ustar jenkinsjenkins/* * 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 ./indicator/textchannelobserver.cpp0000644000015600001650000007564712677320776017706 0ustar jenkinsjenkins/* * Copyright (C) 2012-2014 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 "callmanager.h" #include "config.h" #include "contactutils.h" #include "ringtone.h" #include "telepathyhelper.h" #include "phoneutils.h" #include "accountentry.h" #include "ofonoaccountentry.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace C { #include } // notification handling class NotificationData { public: QString senderId; QStringList participantIds; QString accountId; QDateTime timestamp; QString text; QString eventId; QString alias; QString message; TextChannelObserver *observer; QMap *notificationList; }; void notification_closed(NotifyNotification *notification, QMap *map); void sim_selection_action(NotifyNotification* notification, char *action, gpointer data) { GError *error = NULL; QString accountId = action; NotificationData *notificationData = (NotificationData*) data; if (notificationData != NULL) { QStringList recipients; recipients << notificationData->participantIds; recipients.removeDuplicates(); notificationData->observer->sendMessage(recipients, notificationData->text, accountId); } notify_notification_close(notification, &error); g_object_unref(notification); } 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) { AccountEntry *account = TelepathyHelper::instance()->accountForId(notificationData->accountId); bool phoneNumberBased = account && (account->type() == AccountEntry::PhoneAccount || account->type() == AccountEntry::MultimediaAccount); QStringList recipients; recipients << notificationData->senderId << notificationData->participantIds; History::Thread thread = History::Manager::instance()->threadForParticipants(notificationData->accountId, History::EventTypeText, recipients, phoneNumberBased ? History::MatchPhoneNumber : History::MatchCaseSensitive, true); History::TextEvent textEvent(notificationData->accountId, thread.threadId(), notificationData->eventId, notificationData->senderId, 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 QStringList recipients; QString accountId = notificationData->accountId; if (!notificationData->senderId.isEmpty()) { recipients << notificationData->senderId; } recipients << notificationData->participantIds; recipients.removeDuplicates(); QString url(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(recipients.join(";"))))); AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (account && account->type() == AccountEntry::GenericAccount) { url += QString("?accountId=%1").arg(QString(QUrl::toPercentEncoding(accountId))); } ApplicationUtils::openUrl(url); notification_closed(notification, notificationData->notificationList); } 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(QStringList,QString,QString)), SLOT(onReplyReceived(QStringList,QString,QString))); connect(MessagingMenu::instance(), SIGNAL(messageRead(QStringList,QString,QString)), SLOT(onMessageRead(QStringList,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::sendMessage(const QStringList &recipients, const QString &text, const QString &accountId) { AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account || accountId.isEmpty()) { // fallback to the default account if (TelepathyHelper::instance()->defaultMessagingAccount() && TelepathyHelper::instance()->defaultMessagingAccount()->active()) { account = TelepathyHelper::instance()->defaultMessagingAccount(); } else if (TelepathyHelper::instance()->activeAccounts().size() > 0) { account = TelepathyHelper::instance()->activeAccounts()[0]; } } if (!account) { // we could not find any account, but in theory this case can never happen return; } // check if the account is available if (!account->connected()) { bool phoneNumberBased = account->type() == AccountEntry::PhoneAccount || account->type() == AccountEntry::MultimediaAccount; History::Thread thread = History::Manager::instance()->threadForParticipants(account->accountId(), History::EventTypeText, recipients, phoneNumberBased ? History::MatchPhoneNumber : History::MatchCaseSensitive, true); History::TextEvent textEvent(account->accountId(), thread.threadId(), QByteArray(QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm:ss.zzz").toUtf8()).toHex(), "self", QDateTime::currentDateTime(), false, text, History::MessageTypeText, History::MessageStatusPermanentlyFailed); History::Events events; events.append(textEvent); History::Manager::instance()->writeEvents(events); QString failureMessage; OfonoAccountEntry *ofonoAccount = qobject_cast(account); bool simLocked = (ofonoAccount && ofonoAccount->simLocked()); if (simLocked) { failureMessage = C::gettext("Unlock your sim card and try again from the messaging application."); } else if (ofonoAccount && TelepathyHelper::instance()->flightMode()) { failureMessage = C::gettext("Deactivate flight mode and try again from the messaging application."); } else { // generic error failureMessage = C::gettext("Try again from the messaging application."); } // notify user about the failure GIcon *icon = g_themed_icon_new("cancel"); gchar *iconPath = g_icon_to_string(icon); NotifyNotification *notification = notify_notification_new(C::gettext("The message could not be sent"), failureMessage.toStdString().c_str(), iconPath); g_object_unref(icon); g_free(iconPath); NotificationData *data = new NotificationData(); data->participantIds = recipients; data->accountId = account->accountId(); data->message = text; data->notificationList = &mNotifications; 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); GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show message notification:" << error->message; g_error_free (error); } return; } ChatManager::instance()->sendMessage(account->accountId(), recipients, text); } void TextChannelObserver::clearNotifications() { Q_FOREACH(NotifyNotification *notification, mNotifications.keys()) { GError *error = NULL; notify_notification_close(notification, &error); } } void TextChannelObserver::showNotificationForFlashMessage(const Tp::ReceivedMessage &message, const QString &accountId) { Tp::ContactPtr contact = message.sender(); QByteArray token(message.messageToken().toUtf8()); MessagingMenu::instance()->addFlashMessage(contact->id(), accountId, token.toHex(), message.received(), message.text()); // show the notification NotifyNotification *notification = notify_notification_new("", message.text().toStdString().c_str(), ""); NotificationData *data = new NotificationData(); data->senderId = contact->id(); data->accountId = accountId; 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::triggerNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds) { Tp::ContactPtr contact = message.sender(); QByteArray token(message.messageToken().toUtf8()); if (!mUnreadMessages.contains(token)) { Ringtone::instance()->playIncomingMessageSound(); return; } if (GreeterContacts::isGreeterMode()) { // we're in the greeter's session GreeterContacts::instance()->setContactFilter(QContactPhoneNumber::match(contact->id())); // in greeter mode we show the notification right away as the contact data might not be received showNotificationForMessage(message, accountId, participantIds); } else { AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return; } // try to match the contact info QContactFetchRequest *request = new QContactFetchRequest(this); request->setFilter(QContactPhoneNumber::match(contact->id())); QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request, accountId, participantIds, message](QContactAbstractRequest::State newState) { // only process the results after the finished state is reached if (newState != QContactAbstractRequest::FinishedState) { return; } QContact contact; if (request->contacts().size() > 0) { contact = request->contacts().at(0); // Notify greeter via AccountsService about this contact so it // can show the details if our session is locked. GreeterContacts::emitContact(contact); } // wait for the contact match request to finish before showing the notification showNotificationForMessage(message, accountId, participantIds, contact); }); // FIXME: For accounts not based on phone numbers, don't try to match contacts for now if (account->type() == AccountEntry::PhoneAccount || account->type() == AccountEntry::MultimediaAccount) { request->setManager(ContactUtils::sharedManager()); request->start(); } else { // just emit the signal to pretend we did a contact search Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState); } } } void TextChannelObserver::showNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds, const QContact &contact) { Tp::ContactPtr telepathyContact = message.sender(); QString messageText = message.text(); AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); Tp::MessagePartList messageParts = message.parts(); bool mms = message.header()["x-canonical-mms"].variant().toBool(); if (mms) { // remove header messageParts.pop_front(); Q_FOREACH(const Tp::MessagePart &part, messageParts) { if (part["content-type"].variant().toString().startsWith("text/plain")) { messageText = part["content"].variant().toString(); break; } } } // if messageText is empty, search for attachments if (messageText.isEmpty()) { int imageCount = 0; int videoCount = 0; int contactCount = 0; int audioCount = 0; int attachmentCount = 0; Q_FOREACH(const Tp::MessagePart &part, messageParts) { QString contentType = part["content-type"].variant().toString(); if (contentType.startsWith("image/")) { imageCount++; } else if (contentType.startsWith("video/")) { videoCount++; } else if (contentType.startsWith("audio/")) { audioCount++; } else if (contentType.startsWith("text/vcard") || contentType.startsWith("text/x-vcard")) { contactCount++; } } attachmentCount = imageCount + videoCount + contactCount; if (imageCount > 0 && attachmentCount == imageCount) { messageText = QString::fromUtf8(C::ngettext("Attachment: %1 image", "Attachments: %1 images", imageCount)).arg(imageCount); } else if (videoCount > 0 && attachmentCount == videoCount) { messageText = QString::fromUtf8(C::ngettext("Attachment: %1 video", "Attachments: %1 videos", videoCount)).arg(videoCount); } else if (contactCount > 0 && attachmentCount == contactCount) { messageText = QString::fromUtf8(C::ngettext("Attachment: %1 contact", "Attachments: %1 contacts", contactCount)).arg(contactCount); } else if (audioCount > 0 && attachmentCount == audioCount) { messageText = QString::fromUtf8(C::ngettext("Attachment: %1 audio clip", "Attachments: %1 audio clips", audioCount)).arg(audioCount); } else if (attachmentCount > 0) { messageText = QString::fromUtf8(C::ngettext("Attachment: %1 file", "Attachments: %1 files", attachmentCount)).arg(attachmentCount); } } // add the message to the messaging menu (use hex format to avoid invalid characters) QByteArray token(message.messageToken().toUtf8()); // if the message was already read, just play the ringtone and return // ignore logic if we are in greeter mode if (!mUnreadMessages.contains(token) && !GreeterContacts::isGreeterMode()) { Ringtone::instance()->playIncomingMessageSound(); return; } MessagingMenu::instance()->addMessage(telepathyContact->id(), telepathyContact->alias(), participantIds, accountId, token.toHex(), message.received(), messageText); QString alias; QString avatar; if (!contact.isEmpty()) { alias = contact.detail().label(); avatar = contact.detail().imageUrl().toEncoded(); } if (alias.isEmpty()) { alias = telepathyContact->alias(); if (alias == OFONO_UNKNOWN_NUMBER) { alias = C::gettext("Unknown number"); } } if (avatar.isEmpty()) { avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); } QString title; if (participantIds.size() > 1) { title = QString::fromUtf8(C::gettext("Message to group from %1")).arg(alias); GIcon *icon = g_themed_icon_new("contact-group"); avatar = g_icon_to_string(icon); g_object_unref(icon); } else { title = alias; } AccountEntry::addAccountLabel(accountId, title); // show the notification NotifyNotification *notification = notify_notification_new(title.toStdString().c_str(), messageText.toStdString().c_str(), avatar.toStdString().c_str()); // Bundle the data we need for later updating NotificationData *data = new NotificationData(); data->accountId = accountId; data->senderId = telepathyContact->id(); data->participantIds = participantIds; data->alias = alias; data->message = messageText; data->notificationList = &mNotifications; 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); 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(); AccountEntry *account = TelepathyHelper::instance()->accountForId(data->accountId); if (!account || (account->type() != AccountEntry::PhoneAccount && account->type() != AccountEntry::MultimediaAccount)) { return; } // FIXME: add support for contact matching for non phone number based accounts Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) { if (PhoneUtils::comparePhoneNumbers(data->senderId, phoneNumber.number()) > PhoneUtils::NO_MATCH) { QString displayLabel = contact.detail().label(); QString title = QString::fromUtf8(C::gettext("Message 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()) { AccountEntry *account = TelepathyHelper::instance()->accountForConnection(textChannel->connection()); if (!account) { return; } // class 0 sms mFlashChannels.append(textChannel); Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { showNotificationForFlashMessage(message, account->accountId()); } return; } else { mChannels.append(textChannel); } // notify all the messages from the channel Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { processMessageReceived(message, textChannel); } } void TextChannelObserver::onTextChannelInvalidated() { Tp::TextChannelPtr textChannel(qobject_cast(sender())); mChannels.removeAll(textChannel); mFlashChannels.removeAll(textChannel); } void TextChannelObserver::processMessageReceived(const Tp::ReceivedMessage &message, const Tp::TextChannelPtr &textChannel) { if (textChannel.isNull()) { qDebug() << "TextChannelObserver::processMessageReceived: no text channel"; return; } AccountEntry *account = TelepathyHelper::instance()->accountForConnection(textChannel->connection()); if (!account) { return; } // we do not notify messages sent by ourselves on other devices, unless we // are dealing with phone accounts: #1547462 if (!account->account()->connection().isNull() && message.sender()->handle().at(0) == account->account()->connection()->selfHandle() && account->type() != AccountEntry::PhoneAccount) { return; } // do not place notification items for scrollback messages if (mFlashChannels.contains(textChannel) && !message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { showNotificationForFlashMessage(message, account->accountId()); return; } QStringList participantIds; Q_FOREACH(const Tp::ContactPtr &contact, textChannel->groupContacts(false)) { participantIds << contact->id(); } if (!message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { QTimer *timer = new QTimer(this); timer->setInterval(1500); timer->setSingleShot(true); QByteArray token(message.messageToken().toUtf8()); mUnreadMessages.append(token); QObject::connect(timer, &QTimer::timeout, [=]() { triggerNotificationForMessage(message, account->accountId(), participantIds); Metrics::instance()->increment(Metrics::ReceivedMessages); timer->deleteLater(); }); timer->start(); } } void TextChannelObserver::onMessageReceived(const Tp::ReceivedMessage &message) { Tp::TextChannelPtr textChannel(qobject_cast(sender())); processMessageReceived(message, textChannel); } void TextChannelObserver::onPendingMessageRemoved(const Tp::ReceivedMessage &message) { QByteArray token(message.messageToken().toUtf8()); mUnreadMessages.removeAll(token); MessagingMenu::instance()->removeMessage(token.toHex()); } void TextChannelObserver::onReplyReceived(const QStringList &recipients, const QString &accountId, const QString &reply) { AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return; } // FIXME - we need to find a better way to deal with dual sim in the messaging-menu if (!TelepathyHelper::instance()->defaultMessagingAccount() && TelepathyHelper::instance()->activeAccounts().size() > 1 && account->type() != AccountEntry::GenericAccount) { NotifyNotification *notification = notify_notification_new(C::gettext("Please, select a SIM card:"), reply.toStdString().c_str(), ""); NotificationData *data = new NotificationData(); data->participantIds = recipients; data->accountId = accountId; data->text = reply; data->observer = this; mNotifications.insert(notification, data); Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->activeAccounts()) { notify_notification_add_action (notification, account->accountId().toStdString().c_str(), account->displayName().toStdString().c_str(), sim_selection_action, data, NULL); } g_signal_connect(notification, "closed", G_CALLBACK(notification_closed), &mNotifications); notify_notification_set_hint_string(notification, "x-canonical-snap-decisions", "true"); GError *error = NULL; if (!notify_notification_show(notification, &error)) { qWarning() << "Failed to show message notification:" << error->message; g_error_free (error); } return; } if (account->type() == AccountEntry::GenericAccount) { sendMessage(recipients, reply, accountId); } else { // FIXME: for now we dont specify any accountId sendMessage(recipients, reply, ""); } } void TextChannelObserver::onMessageRead(const QStringList &recipients, const QString &accountId, const QString &encodedMessageId) { QString messageId(QByteArray::fromHex(encodedMessageId.toUtf8())); ChatManager::instance()->acknowledgeMessage(recipients, messageId, accountId); } void TextChannelObserver::onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString) { Metrics::instance()->increment(Metrics::SentMessages); } ./indicator/telephony-service-sms.desktop.in0000644000015600001650000000025112677320771021330 0ustar jenkinsjenkins[Desktop Entry] Type=Application Name=tr("SMS") Exec=telephony-service-indicator Icon=telephony-service-message NoDisplay=true X-Ubuntu-Gettext-Domain=telephony-service ./indicator/CMakeLists.txt0000644000015600001650000000501612677320771015627 0ustar jenkinsjenkins set(qt_SRCS authhandler.cpp callchannelobserver.cpp messagingmenu.cpp metrics.cpp textchannelobserver.cpp ussdindicator.cpp notificationmenu.cpp voicemailindicator.cpp indicatordbus.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 ) qt5_add_dbus_adaptor(qt_SRCS Indicator.xml indicator/indicatordbus.h IndicatorDBus) 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 ) enable_coverage(telephony-service-indicator) 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) ./indicator/authhandler.h0000644000015600001650000000311312677320771015533 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 AUTHHANDLER_H #define AUTHHANDLER_H #include #include #include "indicator/NotificationsInterface.h" #include "accountentry.h" #include "notificationmenu.h" class AuthHandler : public QObject { Q_OBJECT public: explicit AuthHandler(QObject *parent = 0); public Q_SLOTS: void onConnectionStatusChanged(Tp::ConnectionStatus status); void actionInvoked(uint id, const QString &actionKey); void notificationClosed(uint id, uint reason); void clear(); private Q_SLOTS: void setupAccounts(); private: void processStatusChange(AccountEntry *account, Tp::ConnectionStatus status); NotificationMenu mMenuNotification; org::freedesktop::Notifications mNotifications; QMap mAuthFailureRequests; QStringList mIgnoredAccounts; }; #endif // AUTHHANDLER_H ./indicator/indicatordbus.cpp0000644000015600001650000000340512677320771016425 0ustar jenkinsjenkins/* * Copyright (C) 2012 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 "indicatordbus.h" #include "indicatoradaptor.h" #include "messagingmenu.h" // Qt #include static const char* DBUS_SERVICE = "com.canonical.TelephonyServiceIndicator"; static const char* DBUS_OBJECT_PATH = "/com/canonical/TelephonyServiceIndicator"; IndicatorDBus::IndicatorDBus(QObject* parent) : QObject(parent) { } IndicatorDBus::~IndicatorDBus() { } bool IndicatorDBus::connectToBus() { bool ok = QDBusConnection::sessionBus().registerService(DBUS_SERVICE); if (!ok) { return false; } new TelephonyServiceIndicatorAdaptor(this); QDBusConnection::sessionBus().registerObject(DBUS_OBJECT_PATH, this); return true; } void IndicatorDBus::ClearNotifications() { Q_EMIT clearNotificationsRequested(); } void IndicatorDBus::ClearCallNotification(const QString &targetId, const QString &accountId) { MessagingMenu::instance()->removeCall(targetId, accountId); } ./tests/0000755000015600001650000000000012677320771012253 5ustar jenkinsjenkins./tests/indicator/0000755000015600001650000000000012677320772014230 5ustar jenkinsjenkins./tests/indicator/AuthHandlerTest.cpp0000644000015600001650000000433712677320771020001 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "notificationmenu.h" #include "authhandler.h" #include "mockcontroller.h" class AuthHandlerTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testNotificationDisplayedForFailure(); private: AuthHandler mAuthHandler; Tp::AccountPtr mAccount; MockController *mMockController; }; void AuthHandlerTest::initTestCase() { initialize(); } void AuthHandlerTest::init() { mAccount = addAccount("mock", "mock", "theAccount"); mMockController = new MockController("mock", this); } void AuthHandlerTest::cleanup() { doCleanup(); mMockController->deleteLater(); } void AuthHandlerTest::testNotificationDisplayedForFailure() { QDBusInterface notificationMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications"); QSignalSpy notificationSpy(¬ificationMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); mMockController->SimulateAuthFailure(); TRY_COMPARE(notificationSpy.count(), 1); // now just check that the actions are there QStringList actions = notificationSpy.first()[5].toStringList(); QCOMPARE(actions.count(), 4); QCOMPARE(actions[0], QString("yes_id")); QCOMPARE(actions[2], QString("no_id")); } QTEST_MAIN(AuthHandlerTest) #include "AuthHandlerTest.moc" ./tests/indicator/NotificationMenuTest.cpp0000644000015600001650000001566012677320771021056 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "notificationmenu.h" class NotificationMenuTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testRegularMenu(); void testResponseMenu(); void testPasswordMenu(); void testResponseValue(); private: bool isRegistered(const QString &service); }; struct Menu { uint group; uint number; QList entries; }; Q_DECLARE_METATYPE(Menu) QDBusArgument &operator<<(QDBusArgument &argument, const Menu &menu) { argument.beginStructure(); argument << menu.group; argument << menu.number; argument.beginArray(); Q_FOREACH(const QVariantMap &entry, menu.entries) { argument << entry; } argument.endArray(); argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, Menu &menu) { argument.beginStructure(); argument >> menu.group; argument >> menu.number; argument.beginArray(); while (!argument.atEnd()) { QVariantMap entry; argument >> entry; menu.entries << entry; } argument.endArray(); argument.endStructure(); return argument; } void NotificationMenuTest::initTestCase() { qDBusRegisterMetaType>(); } void NotificationMenuTest::testRegularMenu() { QString id("regularmenu"); NotificationMenu menu(id, false, false); QVERIFY(isRegistered(menu.busName())); QDBusInterface menuInterface(menu.busName(), menu.menuPath(), "org.gtk.Menus"); QVERIFY(menuInterface.isValid()); // FIXME: check what else to verify in the menuInterface, for now checking that it is there is enough // as this is created by libgmenumodel QDBusInterface actionInterface(menu.busName(), menu.actionPath(), "org.gtk.Actions"); QVERIFY(actionInterface.isValid()); QDBusPendingReply listReply = actionInterface.asyncCall("List"); QTRY_VERIFY(listReply.isFinished()); QVERIFY(listReply.isValid()); // check that the actions contains the required id QStringList actionsList = listReply.value(); QCOMPARE(actionsList.count(), 1); QCOMPARE(actionsList.first(), id); } void NotificationMenuTest::testResponseMenu() { QString id("responsemenu"); NotificationMenu menu(id, true, false); QVERIFY(isRegistered(menu.busName())); QDBusInterface menuInterface(menu.busName(), menu.menuPath(), "org.gtk.Menus"); QVERIFY(menuInterface.isValid()); QDBusPendingReply> menuReply = menuInterface.asyncCall("Start", QVariant::fromValue(QList() << 0)); QTRY_VERIFY(menuReply.isFinished()); QVERIFY(menuReply.isValid()); // parse the reply QList menus = menuReply.value(); QCOMPARE(menus.count(), 1); Menu &theMenu = menus.first(); QCOMPARE(theMenu.entries.count(), 1); QVariantMap entry = theMenu.entries.first(); // check the properties QCOMPARE(entry["action"].toString(), QString("notifications.%1").arg(id)); QCOMPARE(entry["x-canonical-type"].toString(), QString("com.canonical.snapdecision.textfield")); QCOMPARE(entry["x-echo-mode-password"].toBool(), false); QDBusInterface actionInterface(menu.busName(), menu.actionPath(), "org.gtk.Actions"); QVERIFY(actionInterface.isValid()); QDBusPendingReply listReply = actionInterface.asyncCall("List"); QTRY_VERIFY(listReply.isFinished()); QVERIFY(listReply.isValid()); // check that the actions contains the required id QStringList actionsList = listReply.value(); QCOMPARE(actionsList.count(), 1); QCOMPARE(actionsList.first(), id); } void NotificationMenuTest::testPasswordMenu() { QString id("password"); NotificationMenu menu(id, true, true); QVERIFY(isRegistered(menu.busName())); QDBusInterface menuInterface(menu.busName(), menu.menuPath(), "org.gtk.Menus"); QVERIFY(menuInterface.isValid()); QDBusPendingReply> menuReply = menuInterface.asyncCall("Start", QVariant::fromValue(QList() << 0)); QTRY_VERIFY(menuReply.isFinished()); QVERIFY(menuReply.isValid()); // parse the reply QList menus = menuReply.value(); QCOMPARE(menus.count(), 1); Menu &theMenu = menus.first(); QCOMPARE(theMenu.entries.count(), 1); QVariantMap entry = theMenu.entries.first(); // check the properties QCOMPARE(entry["action"].toString(), QString("notifications.%1").arg(id)); QCOMPARE(entry["x-canonical-type"].toString(), QString("com.canonical.snapdecision.textfield")); QCOMPARE(entry["x-echo-mode-password"].toBool(), true); QDBusInterface actionInterface(menu.busName(), menu.actionPath(), "org.gtk.Actions"); QVERIFY(actionInterface.isValid()); QDBusPendingReply listReply = actionInterface.asyncCall("List"); QTRY_VERIFY(listReply.isFinished()); QVERIFY(listReply.isValid()); // check that the actions contains the required id QStringList actionsList = listReply.value(); QCOMPARE(actionsList.count(), 1); QCOMPARE(actionsList.first(), id); } void NotificationMenuTest::testResponseValue() { QString id("responsevalue"); QString response("theresponse"); NotificationMenu menu(id, true, false); QVERIFY(isRegistered(menu.busName())); // check that the response is empty by default QVERIFY(menu.response().isEmpty()); QDBusInterface actionInterface(menu.busName(), menu.actionPath(), "org.gtk.Actions"); QVERIFY(actionInterface.isValid()); QDBusPendingCall pendingCall = actionInterface.asyncCall("SetState", id, QVariant::fromValue(QDBusVariant(response)), QVariantMap()); QDBusPendingCallWatcher watcher(pendingCall); QTRY_VERIFY(watcher.isFinished()); QCOMPARE(menu.response(), response); // now clear the response and check it is cleared menu.clearResponse(); QVERIFY(menu.response().isEmpty()); } bool NotificationMenuTest::isRegistered(const QString &service) { bool result = false; QDBusReply reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(service); if (reply.isValid()) { result = reply.value(); } return result; } QTEST_MAIN(NotificationMenuTest) #include "NotificationMenuTest.moc" ./tests/indicator/MessagingMenuTest.cpp0000644000015600001650000001242512677320771020341 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "messagingmenu.h" #include "messagingmenumock.h" #include "telepathyhelper.h" #include "mockcontroller.h" class MessagingMenuTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void cleanup(); void testCallNotificationAdded(); void testCallNotificationRemoved(); void testTextMessagesNotificationAdded(); void testTextMessagesNotificationFromOwnNumber(); private: Tp::AccountPtr mOfonoAccount; Tp::AccountPtr mMultimediaAccount; MockController *mOfonoMockController; MockController *mMultimediaMockController; }; void MessagingMenuTest::initTestCase() { initialize(); // just trigger the creation of the mock singleton MessagingMenuMock::instance(); // use the memory contact backend ContactUtils::sharedManager("memory"); QSignalSpy accountAddedSpy(TelepathyHelper::instance(), SIGNAL(accountAdded(AccountEntry*))); mOfonoAccount = addAccount("mock", "ofono", "theOfonoAccount"); QTRY_COMPARE(accountAddedSpy.count(), 1); accountAddedSpy.clear(); mOfonoMockController = new MockController("ofono", this); mMultimediaAccount = addAccount("mock", "multimedia", "theMultimediaAccount"); QTRY_COMPARE(accountAddedSpy.count(), 1); mMultimediaMockController = new MockController("multimedia", this); } void MessagingMenuTest::cleanupTestCase() { doCleanup(); } void MessagingMenuTest::cleanup() { // just to prevent the doCleanup() to run on every test } void MessagingMenuTest::testCallNotificationAdded() { QString caller("12345"); QSignalSpy messageAddedSpy(MessagingMenuMock::instance(), SIGNAL(messageAdded(QString,QString,QString,bool))); MessagingMenu::instance()->addCall(caller, mOfonoAccount->uniqueIdentifier(), QDateTime::currentDateTime()); QTRY_COMPARE(messageAddedSpy.count(), 1); QCOMPARE(messageAddedSpy.first()[1].toString(), caller); } void MessagingMenuTest::testCallNotificationRemoved() { QString caller("2345678"); QSignalSpy messageRemovedSpy(MessagingMenuMock::instance(), SIGNAL(messageRemoved(QString,QString))); MessagingMenu::instance()->addCall(caller, mOfonoAccount->uniqueIdentifier(), QDateTime::currentDateTime()); MessagingMenu::instance()->removeCall(caller, mOfonoAccount->uniqueIdentifier()); QCOMPARE(messageRemovedSpy.count(), 1); QCOMPARE(messageRemovedSpy.first()[1].toString(), caller); } void MessagingMenuTest::testTextMessagesNotificationAdded() { QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); QSignalSpy notificationSpy(¬ificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); QVariantMap properties; properties["Sender"] = "12345"; properties["Recipients"] = (QStringList() << "12345"); QStringList messages; messages << "Hi there" << "How are you" << "Always look on the bright side of life"; Q_FOREACH(const QString &message, messages) { mMultimediaMockController->PlaceIncomingMessage(message, properties); } Q_FOREACH(const QString &message, messages) { mOfonoMockController->PlaceIncomingMessage(message, properties); } TRY_COMPARE(notificationSpy.count(), 6); } void MessagingMenuTest::testTextMessagesNotificationFromOwnNumber() { QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); QSignalSpy notificationSpy(¬ificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); QVariantMap properties; properties["Sender"] = "11112222"; properties["Recipients"] = (QStringList() << "11112222"); QStringList messages; messages << "Hi there" << "How are you" << "Always look on the bright side of life"; Q_FOREACH(const QString &message, messages) { mOfonoMockController->PlaceIncomingMessage(message, properties); } TRY_COMPARE(notificationSpy.count(), 3); notificationSpy.clear(); Q_FOREACH(const QString &message, messages) { mMultimediaMockController->PlaceIncomingMessage(message, properties); } // we need to make sure no notifications were displayed, using timers is always a bad idea, // but in this case there is no other easy way to test it. QTest::qWait(2000); QCOMPARE(notificationSpy.count(), 0); } QTEST_MAIN(MessagingMenuTest) #include "MessagingMenuTest.moc" ./tests/indicator/messagingmenumock.cpp0000644000015600001650000002706512677320771020461 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "messagingmenumock.h" #include "messaging-menu.h" #include #include MessagingMenuMock *MessagingMenuMock::instance() { static MessagingMenuMock *self = new MessagingMenuMock(); return self; } MessagingMenuMock::MessagingMenuMock(QObject *parent) : QObject(parent) { } /*** Mock implementation of messaging messaging-menu functions ***/ /*** MessagingMenuApp ***/ struct _MessagingMenuApp { GObject parent_instance; gchar *desktopId; }; G_DEFINE_TYPE(MessagingMenuApp, messaging_menu_app, G_TYPE_OBJECT) enum MessageProperties { PROP_0, PROP_ID, PROP_ICON, PROP_TITLE, PROP_SUBTITLE, PROP_BODY, PROP_TIME, PROP_DRAWS_ATTENTION, NUM_PROPERTIES }; #define PROP_DESKTOP_ID 1 static void messaging_menu_app_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { qDebug() << __PRETTY_FUNCTION__; if (prop_id == PROP_DESKTOP_ID) { MessagingMenuApp *app = MESSAGING_MENU_APP (object); app->desktopId = g_value_dup_string (value); } } static void messaging_menu_app_class_init (MessagingMenuAppClass *klass) { qDebug() << __PRETTY_FUNCTION__; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = messaging_menu_app_set_property; GParamSpec *prop = g_param_spec_string ("desktop-id", "Desktop Id", "The desktop id of the associated application", NULL, (GParamFlags)(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DESKTOP_ID, prop); } static void messaging_menu_app_init (MessagingMenuApp *app) { qDebug() << __PRETTY_FUNCTION__; Q_UNUSED(app) // FIXME: check what needs implementing } MessagingMenuApp *messaging_menu_app_new(const gchar *desktop_id) { qDebug() << __PRETTY_FUNCTION__; MessagingMenuApp *app = (MessagingMenuApp*)g_object_new (MESSAGING_MENU_TYPE_APP, "desktop-id", desktop_id, NULL); Q_EMIT MessagingMenuMock::instance()->appCreated(app->desktopId); return app; } void messaging_menu_app_register(MessagingMenuApp *app) { qDebug() << __PRETTY_FUNCTION__; Q_EMIT MessagingMenuMock::instance()->appRegistered(app->desktopId); } void messaging_menu_app_append_source(MessagingMenuApp *app, const gchar *id, GIcon *icon, const gchar *label) { qDebug() << __PRETTY_FUNCTION__; Q_EMIT MessagingMenuMock::instance()->sourceAdded(app->desktopId, id, g_icon_to_string(icon), label); } /*** MessagingMenuMessage ***/ struct _MessagingMenuMessage { GObject parent; gchar *id; GIcon *icon; gchar *title; gchar *subtitle; gchar *body; gint64 time; gboolean draws_attention; }; typedef GObjectClass MessagingMenuMessageClass; G_DEFINE_TYPE (MessagingMenuMessage, messaging_menu_message, G_TYPE_OBJECT) // MessagingMenuMessage's properties static GParamSpec *properties[NUM_PROPERTIES]; static void messaging_menu_message_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object); switch (property_id) { case PROP_ID: g_value_set_string (value, msg->id); break; case PROP_ICON: g_value_set_object (value, msg->icon); break; case PROP_TITLE: g_value_set_string (value, msg->title); break; case PROP_SUBTITLE: g_value_set_string (value, msg->subtitle); break; case PROP_BODY: g_value_set_string (value, msg->body); break; case PROP_TIME: g_value_set_int64 (value, msg->time); break; case PROP_DRAWS_ATTENTION: g_value_set_boolean (value, msg->draws_attention); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void messaging_menu_message_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { qDebug() << __PRETTY_FUNCTION__; MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object); switch (property_id) { case PROP_ID: msg->id = g_value_dup_string (value); break; case PROP_ICON: msg->icon = (GIcon*)g_value_dup_object (value); break; case PROP_TITLE: msg->title = g_value_dup_string (value); break; case PROP_SUBTITLE: msg->subtitle = g_value_dup_string (value); break; case PROP_BODY: msg->body = g_value_dup_string (value); break; case PROP_TIME: msg->time = g_value_get_int64 (value); break; case PROP_DRAWS_ATTENTION: msg->draws_attention = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void messaging_menu_message_class_init(MessagingMenuMessageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = messaging_menu_message_get_property; object_class->set_property = messaging_menu_message_set_property; properties[PROP_ID] = g_param_spec_string ("id", "Id", "Unique id of the message", NULL, (GParamFlags)(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_ICON] = g_param_spec_object ("icon", "Icon", "Icon of the message", G_TYPE_ICON, (GParamFlags)(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_TITLE] = g_param_spec_string ("title", "Title", "Title of the message", NULL, (GParamFlags)(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_SUBTITLE] = g_param_spec_string ("subtitle", "Subtitle", "Subtitle of the message", NULL, (GParamFlags)(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_BODY] = g_param_spec_string ("body", "Body", "First lines of the body of the message", NULL, (GParamFlags)(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_TIME] = g_param_spec_int64 ("time", "Time", "Time the message was sent, in microseconds", 0, G_MAXINT64, 0, (GParamFlags)(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_DRAWS_ATTENTION] = g_param_spec_boolean ("draws-attention", "Draws attention", "Whether the message should draw attention", TRUE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_properties (klass, NUM_PROPERTIES, properties); g_signal_new ("activate", MESSAGING_MENU_TYPE_MESSAGE, (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED), 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VARIANT); } static void messaging_menu_message_init(MessagingMenuMessage *self) { self->draws_attention = TRUE; } MessagingMenuMessage *messaging_menu_message_new(const gchar *id, GIcon *icon, const gchar *title, const gchar *subtitle, const gchar *body, gint64 time) { qDebug() << __PRETTY_FUNCTION__; MessagingMenuMessage *message = (MessagingMenuMessage*) g_object_new(MESSAGING_MENU_TYPE_MESSAGE, "id", id, "icon", icon, "title", title, "subtitle", subtitle, "body", body, "time", time, NULL); Q_EMIT MessagingMenuMock::instance()->messageCreated(QString(message->id), QString(g_icon_to_string(message->icon)), QString(message->title), QString(message->subtitle), QString(message->body), QDateTime::fromMSecsSinceEpoch(time / 1000)); return message; } void messaging_menu_message_add_action(MessagingMenuMessage *msg, const gchar *id, const gchar *label, const GVariantType *parameter_type, GVariant *parameter_hint) { qDebug() << __PRETTY_FUNCTION__; Q_EMIT MessagingMenuMock::instance()->actionAdded(msg->id, id, label); } void messaging_menu_app_remove_message_by_id(MessagingMenuApp *app, const gchar *id) { qDebug() << __PRETTY_FUNCTION__; Q_EMIT MessagingMenuMock::instance()->messageRemoved(app->desktopId, id); } const gchar *messaging_menu_message_get_id(MessagingMenuMessage *msg) { qDebug() << __PRETTY_FUNCTION__; return msg->id; } void messaging_menu_app_append_message(MessagingMenuApp *app, MessagingMenuMessage *msg, const gchar *source_id, gboolean notify) { qDebug() << __PRETTY_FUNCTION__; Q_EMIT MessagingMenuMock::instance()->messageAdded(QString(app->desktopId), QString(msg->id), QString(source_id), (bool)notify); } ./tests/indicator/CMakeLists.txt0000644000015600001650000000342212677320771016770 0ustar jenkinsjenkinsinclude_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../common ${CMAKE_CURRENT_BINARY_DIR}/../common ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_SOURCE_DIR}/indicator ${MESSAGING_MENU_INCLUDE_DIRS} ${NOTIFY_INCLUDE_DIRS} ${TP_QT5_INCLUDE_DIRS} ${HISTORY_INCLUDE_DIRS} ${GSETTINGS_QT_INCLUDE_DIRS} ) if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")) generate_telepathy_test(MessagingMenuTest SOURCES MessagingMenuTest.cpp messagingmenumock.cpp ${CMAKE_SOURCE_DIR}/indicator/messagingmenu.cpp LIBRARIES ${TP_QT5_LIBRARIES} telephonyservice mockcontroller telepathytest ${HISTORY_LIBRARIES} TASKS --task xvfb-run -p -a -p ${CMAKE_BINARY_DIR}/indicator/telephony-service-indicator --task-name telephony-service-indicator --wait-for com.canonical.TelephonyServiceHandler --ignore-return) endif() qt5_add_dbus_interface( qt_SRCS "${DATA_DIR}/org.freedesktop.Notifications.xml" NotificationsInterface ) generate_telepathy_test(AuthHandlerTest SOURCES AuthHandlerTest.cpp ${CMAKE_SOURCE_DIR}/indicator/authhandler.cpp ${CMAKE_SOURCE_DIR}/indicator/notificationmenu.cpp ${qt_SRCS} LIBRARIES ${TP_QT5_LIBRARIES} telephonyservice mockcontroller telepathytest ${HISTORY_LIBRARIES} ${NOTIFY_LIBRARIES}) generate_test(NotificationMenuTest SOURCES NotificationMenuTest.cpp ${CMAKE_SOURCE_DIR}/indicator/notificationmenu.cpp LIBRARIES ${NOTIFY_LIBRARIES} QT5_MODULES Core DBus Test USE_DBUS TRUE) ./tests/indicator/messagingmenumock.h0000644000015600001650000000350112677320771020113 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 . */ #ifndef MESSAGINGMENUMOCK_H #define MESSAGINGMENUMOCK_H #include class MessagingMenuMock : public QObject { Q_OBJECT public: static MessagingMenuMock *instance(); Q_SIGNALS: void appCreated(const QString &desktopId); void appRegistered(const QString &desktopId); void sourceAdded(const QString &app, const QString &id, const QString &icon, const QString &label); void messageCreated(const QString &id, const QString &icon, const QString &title, const QString &subtitle, const QString &body, const QDateTime &time); void messageAdded(const QString &app, const QString &messageId, const QString &sourceId, bool notify); void messageRemoved(const QString &app, const QString &id); void actionAdded(const QString &messageId, const QString &actionId, const QString &label); private: explicit MessagingMenuMock(QObject *parent = 0); }; #endif // MESSAGINGMENUMOCK_H ./tests/libtelephonyservice/0000755000015600001650000000000012677321002016316 5ustar jenkinsjenkins./tests/libtelephonyservice/ChatEntryTest.cpp0000644000015600001650000001277312677320771021611 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "telepathytest.h" #include "accountentry.h" #include "chatmanager.h" #include "telepathyhelper.h" #include "mockcontroller.h" class ChatEntryTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testContactChatState_data(); void testContactChatState(); private: Tp::AccountPtr mGenericTpAccount; MockController *mGenericMockController; Tp::AccountPtr mMultimediaTpAccount; MockController *mMultimediaMockController; }; void ChatEntryTest::initTestCase() { initialize(); TelepathyHelper::instance()->registerChannelObserver(); // just give telepathy some time to register the observer QTest::qWait(1000); } void ChatEntryTest::init() { // add two accounts mGenericTpAccount = addAccount("mock", "mock", "the generic account"); QTRY_VERIFY(!mGenericTpAccount->connection().isNull()); mMultimediaTpAccount = addAccount("mock", "multimedia", "the multimedia account"); QTRY_VERIFY(!mMultimediaTpAccount->connection().isNull()); // and create the mock controller mGenericMockController = new MockController("mock", this); // and create the mock controller mMultimediaMockController = new MockController("multimedia", this); } void ChatEntryTest::cleanup() { // the accounts are removed in the parent class. doCleanup(); mGenericMockController->deleteLater(); mMultimediaMockController->deleteLater(); } void ChatEntryTest::testContactChatState_data() { QTest::addColumn("accountId"); QTest::addColumn("participants"); QTest::newRow("chat state on generic account") << QString("mock/mock/account0") << (QStringList() << "user@domain.com"); QTest::newRow("group chat state on generic account") << QString("mock/mock/account0") << (QStringList() << "user@domain.com" << "user2@domain.com"); QTest::newRow("chat state on multimedia account") << QString("mock/multimedia/account0") << (QStringList() << "+1234567"); QTest::newRow("group state on multimedia account") << QString("mock/multimedia/account0") << (QStringList() << "+1234567" << "+111111"); } void ChatEntryTest::testContactChatState() { QFETCH(QString, accountId); QFETCH(QStringList, participants); MockController *mockController = accountId.startsWith("mock/mock") ? mGenericMockController : mMultimediaMockController; QSignalSpy chatEntryCreatedSpy(ChatManager::instance(), SIGNAL(chatEntryCreated(QString, QStringList,ChatEntry *))); ChatEntry *entry = ChatManager::instance()->chatEntryForParticipants(accountId, participants, true); QVERIFY(entry == NULL); QTRY_COMPARE(chatEntryCreatedSpy.count(), 1); entry = ChatManager::instance()->chatEntryForParticipants(accountId, participants, false); QVERIFY(entry != NULL); QList arguments = chatEntryCreatedSpy.takeFirst(); QCOMPARE(accountId, arguments.at(0).toString()); QCOMPARE(participants.toSet(), arguments.at(1).toStringList().toSet()); QCOMPARE(entry, arguments.at(2).value()); QQmlListProperty chatStates = entry->chatStates(); QCOMPARE(entry->chatStatesCount(&chatStates), participants.count()); // change state of contact 1 ContactChatState *contactChatState1 = entry->chatStatesAt(&chatStates, 0); QSignalSpy chatStateChangedSpy1(contactChatState1, SIGNAL(stateChanged())); mockController->ChangeChatState(participants, contactChatState1->contactId(), ChatEntry::ChannelChatStateComposing); QTRY_COMPARE(chatStateChangedSpy1.count(), 1); QCOMPARE(contactChatState1->state(), (int)ChatEntry::ChannelChatStateComposing); chatStateChangedSpy1.clear(); mockController->ChangeChatState(participants, contactChatState1->contactId(), ChatEntry::ChannelChatStatePaused); QTRY_COMPARE(chatStateChangedSpy1.count(), 1); QCOMPARE(entry->chatStatesAt(&chatStates, 0)->state(), (int)ChatEntry::ChannelChatStatePaused); if (participants.count() > 1) { // change state of contact 2 ContactChatState *contactChatState2 = entry->chatStatesAt(&chatStates, 1); QSignalSpy chatStateChangedSpy2(contactChatState2, SIGNAL(stateChanged())); mockController->ChangeChatState(participants, contactChatState2->contactId(), ChatEntry::ChannelChatStateComposing); QTRY_COMPARE(chatStateChangedSpy2.count(), 1); QCOMPARE(contactChatState2->state(), (int)ChatEntry::ChannelChatStateComposing); chatStateChangedSpy2.clear(); mockController->ChangeChatState(participants, contactChatState2->contactId(), ChatEntry::ChannelChatStatePaused); QTRY_COMPARE(chatStateChangedSpy2.count(), 1); QCOMPARE(contactChatState2->state(), (int)ChatEntry::ChannelChatStatePaused); } } QTEST_MAIN(ChatEntryTest) #include "ChatEntryTest.moc" ./tests/libtelephonyservice/AccountEntryFactoryTest.cpp0000644000015600001650000000421612677320771023647 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "accountentry.h" #include "accountentryfactory.h" #include "ofonoaccountentry.h" #include "telepathyhelper.h" class AccountEntryFactoryTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void testCorrectInstancesCreated(); void testNullAccount(); }; void AccountEntryFactoryTest::initTestCase() { initialize(); } void AccountEntryFactoryTest::testCorrectInstancesCreated() { Tp::AccountPtr genericTpAccount = addAccount("mock", "mock", "generic"); QVERIFY(!genericTpAccount.isNull()); AccountEntry *genericAccount = AccountEntryFactory::createEntry(genericTpAccount, this); QVERIFY(genericAccount); QCOMPARE(genericAccount->type(), AccountEntry::GenericAccount); QVERIFY(!qobject_cast(genericAccount)); Tp::AccountPtr ofonoTpAccount = addAccount("mock", "ofono", "phone account"); AccountEntry *ofonoAccount = AccountEntryFactory::createEntry(ofonoTpAccount, this); QVERIFY(ofonoAccount); QCOMPARE(ofonoAccount->type(), AccountEntry::PhoneAccount); QVERIFY(qobject_cast(ofonoAccount)); } void AccountEntryFactoryTest::testNullAccount() { AccountEntry *nullAccount = AccountEntryFactory::createEntry(Tp::AccountPtr(), this); QVERIFY(nullAccount); QVERIFY(nullAccount->accountId().isNull()); } QTEST_MAIN(AccountEntryFactoryTest) #include "AccountEntryFactoryTest.moc" ./tests/libtelephonyservice/ContactUtilsTest.cpp0000644000015600001650000000410112677320771022306 0ustar jenkinsjenkins/* * 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" ./tests/libtelephonyservice/CallEntryTest.cpp0000644000015600001650000001011712677321002021557 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "callentry.h" #include "callmanager.h" #include "telepathyhelper.h" #include "mockcontroller.h" #include "ofonoaccountentry.h" #include "accountentryfactory.h" Q_DECLARE_METATYPE(AccountEntry*) class CallEntryTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testIsVoicemail_data(); void testIsVoicemail(); protected Q_SLOTS: void onCallChannelAvailable(const Tp::CallChannelPtr &channel); private: Tp::AccountPtr mTpAccount; OfonoAccountEntry *mAccount; Tp::CallChannelPtr mCallChannel; MockController *mMockController; }; void CallEntryTest::initTestCase() { qRegisterMetaType(); initialize(); TelepathyHelper::instance()->registerChannelObserver(); connect(TelepathyHelper::instance()->channelObserver(), SIGNAL(callChannelAvailable(Tp::CallChannelPtr)), SLOT(onCallChannelAvailable(Tp::CallChannelPtr))); } void CallEntryTest::init() { QSignalSpy accountSpy(TelepathyHelper::instance(), SIGNAL(accountAdded(AccountEntry*))); mTpAccount = addAccount("mock", "ofono", "the account"); QVERIFY(!mTpAccount.isNull()); TRY_COMPARE(accountSpy.count(), 1); mAccount = qobject_cast(accountSpy.first().first().value()); QVERIFY(mAccount); TRY_VERIFY(mAccount->ready()); TRY_COMPARE(mAccount->status(), QString("available")); // and create the mock controller mMockController = new MockController("ofono", this); } void CallEntryTest::cleanup() { doCleanup(); mMockController->deleteLater(); mAccount->deleteLater(); mCallChannel = Tp::CallChannelPtr(); // wait until all the calls are gone before the next test TRY_VERIFY(!CallManager::instance()->hasCalls()); } void CallEntryTest::testIsVoicemail_data() { QTest::addColumn("voicemailNumber"); QTest::addColumn("callNumber"); QTest::addColumn("isVoicemail"); QTest::newRow("calling voicemail") << "*1234" << "*1234" << true; QTest::newRow("calling other number") << "*1234" << "5555555" << false; } void CallEntryTest::testIsVoicemail() { QFETCH(QString, voicemailNumber); QFETCH(QString, callNumber); QFETCH(bool, isVoicemail); mMockController->SetVoicemailNumber(voicemailNumber); TRY_COMPARE(mAccount->voicemailNumber(), voicemailNumber); // now place a call to a number that is not the voicemail number QVariantMap properties; properties["Caller"] = callNumber; properties["State"] = "incoming"; mMockController->placeCall(properties); TRY_VERIFY(!mCallChannel.isNull()); QCOMPARE(mCallChannel->targetContact()->id(), callNumber); CallEntry *callEntry = new CallEntry(mCallChannel); QCOMPARE(callEntry->isVoicemail(), isVoicemail); TRY_VERIFY(CallManager::instance()->hasCalls()); callEntry->endCall(); callEntry->deleteLater(); } void CallEntryTest::onCallChannelAvailable(const Tp::CallChannelPtr &channel) { channel->accept(); connect(channel->becomeReady(Tp::Features() << Tp::CallChannel::FeatureCore << Tp::CallChannel::FeatureCallState), &Tp::PendingOperation::finished, [this, channel] { mCallChannel = channel; }); } QTEST_MAIN(CallEntryTest) #include "CallEntryTest.moc" ./tests/libtelephonyservice/ProtocolManagerTest.cpp0000644000015600001650000001374512677320771023004 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "config.h" #include "protocolmanager.h" Q_DECLARE_METATYPE(Protocols) Q_DECLARE_METATYPE(Protocol::Features) // inheriting just to make the constructor public for testing class ProtocolManagerWrapper : public ProtocolManager { Q_OBJECT public: ProtocolManagerWrapper(const QString &dir, QObject *parent = 0) : ProtocolManager(dir, parent) { } }; class ProtocolManagerTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testNumberOfProtocols(); void testFooProtocolLoaded(); void testProtocolNames(); void testProtocolByName(); void testProtocolsForFeatures_data(); void testProtocolsForFeatures(); void testTextProtocols(); void testVoiceProtocols(); void testIsProtocolSupported_data(); void testIsProtocolSupported(); void testFileSystemWatch(); }; void ProtocolManagerTest::initTestCase() { qRegisterMetaType(); qRegisterMetaType(); } void ProtocolManagerTest::testNumberOfProtocols() { QDir dir(protocolsDir()); int count = dir.entryList(QDir::Files).count(); QCOMPARE(ProtocolManager::instance()->protocols().count(), count); } void ProtocolManagerTest::testFooProtocolLoaded() { Protocol *fooProtocol = 0; Q_FOREACH(Protocol *proto, ProtocolManager::instance()->protocols()) { QVERIFY(proto); if (proto->name() == "foo") { fooProtocol = proto; break; } } QVERIFY(fooProtocol); } void ProtocolManagerTest::testProtocolNames() { Protocols protocols = ProtocolManager::instance()->protocols(); QStringList protocolNames = ProtocolManager::instance()->protocolNames(); for (int i = 0; i < protocols.count(); ++i) { QCOMPARE(protocols[i]->name(), protocolNames[i]); } } void ProtocolManagerTest::testProtocolByName() { Protocol *invalid = ProtocolManager::instance()->protocolByName("invalid"); QVERIFY(!invalid); Protocol *bar = ProtocolManager::instance()->protocolByName("bar"); QVERIFY(bar); QCOMPARE(bar->name(), QString("bar")); } void ProtocolManagerTest::testProtocolsForFeatures_data() { QTest::addColumn("features"); QTest::addColumn("protocols"); Protocols protocols; protocols = ProtocolManager::instance()->protocols(); QTest::newRow("both text and voice") << Protocol::Features(Protocol::TextChats | Protocol::VoiceCalls) << protocols; protocols.clear(); protocols << ProtocolManager::instance()->protocolByName("foo") << ProtocolManager::instance()->protocolByName("bar") << ProtocolManager::instance()->protocolByName("text"); QTest::newRow("only text") << Protocol::Features(Protocol::TextChats) << protocols; protocols.clear(); protocols << ProtocolManager::instance()->protocolByName("foo") << ProtocolManager::instance()->protocolByName("bar") << ProtocolManager::instance()->protocolByName("voice"); QTest::newRow("only voice") << Protocol::Features(Protocol::VoiceCalls) << protocols; QTest::newRow("no features") << Protocol::Features() << Protocols(); } void ProtocolManagerTest::testProtocolsForFeatures() { QFETCH(Protocol::Features, features); QFETCH(Protocols, protocols); Protocols filtered = ProtocolManager::instance()->protocolsForFeatures(features); QCOMPARE(filtered.count(), protocols.count()); Q_FOREACH(Protocol *protocol, protocols) { QVERIFY(filtered.contains(protocol)); } } void ProtocolManagerTest::testTextProtocols() { QCOMPARE(ProtocolManager::instance()->textProtocols(), ProtocolManager::instance()->protocolsForFeatures(Protocol::TextChats)); } void ProtocolManagerTest::testVoiceProtocols() { QCOMPARE(ProtocolManager::instance()->voiceProtocols(), ProtocolManager::instance()->protocolsForFeatures(Protocol::VoiceCalls)); } void ProtocolManagerTest::testIsProtocolSupported_data() { QTest::addColumn("protocolName"); QTest::addColumn("supported"); QTest::newRow("foo") << QString("foo") << true; QTest::newRow("bar") << QString("bar") << true; QTest::newRow("text") << QString("text") << true; QTest::newRow("voice") << QString("voice") << true; QTest::newRow("invalid") << QString("invalid") << false; } void ProtocolManagerTest::testIsProtocolSupported() { QFETCH(QString, protocolName); QFETCH(bool, supported); QCOMPARE(ProtocolManager::instance()->isProtocolSupported(protocolName), supported); } void ProtocolManagerTest::testFileSystemWatch() { QTemporaryDir tempDir; tempDir.setAutoRemove(true); QVERIFY(tempDir.isValid()); QDir dir(tempDir.path()); ProtocolManagerWrapper manager(tempDir.path()); QSignalSpy protocolsChangedSpy(&manager, SIGNAL(protocolsChanged())); QFile foobar(dir.absoluteFilePath("foobar.protocol")); QVERIFY(foobar.open(QFile::WriteOnly)); foobar.write("[Protocol]\nName=foobar\nFeatures=read,write\n"); QVERIFY(foobar.flush()); foobar.close(); QTRY_COMPARE(protocolsChangedSpy.count(), 1); QCOMPARE(manager.protocols().count(), 1); QCOMPARE(manager.protocols()[0]->name(), QString("foobar")); } QTEST_MAIN(ProtocolManagerTest) #include "ProtocolManagerTest.moc" ./tests/libtelephonyservice/TelepathyHelperTest.cpp0000644000015600001650000003003512677320771022776 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "accountentry.h" #include "accountentryfactory.h" #include "telepathyhelper.h" #include "mockcontroller.h" Q_DECLARE_METATYPE(AccountEntry*) class TelepathyHelperTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testAccounts(); void testPhoneAccounts(); void testAccountSorting(); void testAccountIds(); void testActiveAccounts(); void testAccountForId(); void testAccountForConnection(); void testEmergencyCallsAvailable(); protected: Tp::AccountPtr addAccountAndWait(const QString &manager, const QString &protocol, const QString &displayName, const QVariantMap ¶meters = QVariantMap()); private: Tp::AccountPtr mGenericTpAccount; Tp::AccountPtr mPhoneTpAccount; MockController *mGenericController; MockController *mPhoneController; }; void TelepathyHelperTest::initTestCase() { qRegisterMetaType(); initialize(); QSignalSpy setupReadySpy(TelepathyHelper::instance(), SIGNAL(setupReady())); TRY_COMPARE(setupReadySpy.count(), 1); } void TelepathyHelperTest::init() { // add two accounts mGenericTpAccount = addAccountAndWait("mock", "mock", "the generic account"); QVERIFY(!mGenericTpAccount.isNull()); mPhoneTpAccount = addAccountAndWait("mock", "ofono", "the phone account"); QVERIFY(!mPhoneTpAccount.isNull()); // and create the mock controller mGenericController = new MockController("mock", this); mPhoneController = new MockController("ofono", this); } void TelepathyHelperTest::cleanup() { // the accounts are removed in the parent class. doCleanup(); mGenericController->deleteLater(); mPhoneController->deleteLater(); } void TelepathyHelperTest::testAccounts() { QCOMPARE(TelepathyHelper::instance()->accounts().count(), 2); AccountEntry *first = TelepathyHelper::instance()->accounts()[0]; AccountEntry *second = TelepathyHelper::instance()->accounts()[1]; QVERIFY(first->accountId() != second->accountId()); // now check that new accounts are captured QSignalSpy accountsChangedSpy(TelepathyHelper::instance(), SIGNAL(accountsChanged())); Tp::AccountPtr newAccount = addAccountAndWait("mock", "mock", "extra"); QVERIFY(!newAccount.isNull()); TRY_COMPARE(accountsChangedSpy.count(), 1); QCOMPARE(TelepathyHelper::instance()->accounts().count(), 3); bool accountFound = false; Q_FOREACH(AccountEntry *entry, TelepathyHelper::instance()->accounts()) { if (entry->accountId() == newAccount->uniqueIdentifier()) { accountFound = true; break; } } QVERIFY(accountFound); // now remove the extra account and make sure it is properly removed accountsChangedSpy.clear(); QVERIFY(removeAccount(newAccount)); TRY_COMPARE(accountsChangedSpy.count(), 1); QCOMPARE(TelepathyHelper::instance()->accounts().count(), 2); QCOMPARE(TelepathyHelper::instance()->accounts()[0]->accountId(), first->accountId()); QCOMPARE(TelepathyHelper::instance()->accounts()[1]->accountId(), second->accountId()); } void TelepathyHelperTest::testPhoneAccounts() { QCOMPARE(TelepathyHelper::instance()->phoneAccounts().count(), 1); AccountEntry *phoneAccount = TelepathyHelper::instance()->phoneAccounts()[0]; QVERIFY(phoneAccount->accountId() == mPhoneTpAccount->uniqueIdentifier()); // now check that new phone accounts are captured QSignalSpy phoneAccountsChangedSpy(TelepathyHelper::instance(), SIGNAL(phoneAccountsChanged())); Tp::AccountPtr newAccount = addAccount("mock", "ofono", "extra"); QVERIFY(!newAccount.isNull()); QTRY_COMPARE(phoneAccountsChangedSpy.count(), 1); QCOMPARE(TelepathyHelper::instance()->phoneAccounts().count(), 2); bool accountFound = false; Q_FOREACH(AccountEntry *entry, TelepathyHelper::instance()->phoneAccounts()) { if (entry->accountId() == newAccount->uniqueIdentifier()) { accountFound = true; break; } } QVERIFY(accountFound); // now remove the extra phone account and make sure it is properly removed phoneAccountsChangedSpy.clear(); QVERIFY(removeAccount(newAccount)); QTRY_COMPARE(phoneAccountsChangedSpy.count(), 1); QCOMPARE(TelepathyHelper::instance()->phoneAccounts().count(), 1); QCOMPARE(TelepathyHelper::instance()->phoneAccounts()[0]->accountId(), phoneAccount->accountId()); } void TelepathyHelperTest::testAccountSorting() { // create two accounts with modem-objpath parameters and make sure they are listed first QVariantMap parameters; parameters["modem-objpath"] = "/phonesim1"; Tp::AccountPtr firstAccount = addAccountAndWait("mock", "ofono", "firstPhoneAccount", parameters); QVERIFY(!firstAccount.isNull()); parameters["modem-objpath"] = "/phonesim2"; Tp::AccountPtr secondAccount = addAccountAndWait("mock", "ofono", "secondPhoneAccount", parameters); QVERIFY(!secondAccount.isNull()); // wait for the accounts to appear; TRY_COMPARE(TelepathyHelper::instance()->accounts().count(), 4); // and check the order QCOMPARE(TelepathyHelper::instance()->accounts()[0]->accountId(), firstAccount->uniqueIdentifier()); QCOMPARE(TelepathyHelper::instance()->accounts()[1]->accountId(), secondAccount->uniqueIdentifier()); // now add a third account that should go before the two others parameters["modem-objpath"] = "/phonesim0"; Tp::AccountPtr thirdAccount = addAccountAndWait("mock", "ofono", "thirdPhoneAccount", parameters); QVERIFY(!thirdAccount.isNull()); // wait for the accounts to appear; TRY_COMPARE(TelepathyHelper::instance()->accounts().count(), 5); QCOMPARE(TelepathyHelper::instance()->accounts()[0]->accountId(), thirdAccount->uniqueIdentifier()); // and remove the created accounts QVERIFY(removeAccount(firstAccount)); QVERIFY(removeAccount(secondAccount)); QVERIFY(removeAccount(thirdAccount)); } void TelepathyHelperTest::testAccountIds() { QCOMPARE(TelepathyHelper::instance()->accountIds().count(), 2); // now check that new accounts are captured QSignalSpy accountIdsChangedSpy(TelepathyHelper::instance(), SIGNAL(accountIdsChanged())); Tp::AccountPtr newAccount = addAccountAndWait("mock", "mock", "extra"); QVERIFY(!newAccount.isNull()); TRY_COMPARE(accountIdsChangedSpy.count(), 1); QCOMPARE(TelepathyHelper::instance()->accountIds().count(), 3); // just to make sure check that each account id matches one account for (int i = 0; i < 3; ++i) { QCOMPARE(TelepathyHelper::instance()->accountIds()[i], TelepathyHelper::instance()->accounts()[i]->accountId()); } // now remove the extra account and make sure it is properly removed accountIdsChangedSpy.clear(); QVERIFY(removeAccount(newAccount)); TRY_COMPARE(accountIdsChangedSpy.count(), 1); QCOMPARE(TelepathyHelper::instance()->accountIds().count(), 2); QCOMPARE(TelepathyHelper::instance()->accountIds()[0], TelepathyHelper::instance()->accounts()[0]->accountId()); QCOMPARE(TelepathyHelper::instance()->accountIds()[1], TelepathyHelper::instance()->accounts()[1]->accountId()); } void TelepathyHelperTest::testActiveAccounts() { QSignalSpy activeAccountsSpy(TelepathyHelper::instance(), SIGNAL(activeAccountsChanged())); // at startup, all accounts are active, so make sure we got two active accounts QCOMPARE(TelepathyHelper::instance()->activeAccounts().count(), 2); // now set one of the accounts as offline and make sure it is captured mGenericController->SetOnline(false); TRY_VERIFY(activeAccountsSpy.count() >= 1); QTRY_COMPARE(TelepathyHelper::instance()->activeAccounts().count(), 1); QCOMPARE(TelepathyHelper::instance()->activeAccounts()[0]->accountId(), mPhoneTpAccount->uniqueIdentifier()); // set the other account offline to make sure activeAccountsSpy.clear(); mPhoneController->SetOnline(false); TRY_VERIFY(activeAccountsSpy.count() >= 1); QVERIFY(TelepathyHelper::instance()->activeAccounts().isEmpty()); // and set both accounts online again activeAccountsSpy.clear(); mGenericController->SetOnline(true); mPhoneController->SetOnline(true); TRY_VERIFY(activeAccountsSpy.count() >= 2); QCOMPARE(TelepathyHelper::instance()->activeAccounts().count(), 2); } void TelepathyHelperTest::testAccountForId() { AccountEntry *genericAccount = TelepathyHelper::instance()->accountForId(mGenericTpAccount->uniqueIdentifier()); QVERIFY(genericAccount); QCOMPARE(genericAccount->accountId(), mGenericTpAccount->uniqueIdentifier()); AccountEntry *phoneAccount = TelepathyHelper::instance()->accountForId(mPhoneTpAccount->uniqueIdentifier()); QVERIFY(phoneAccount); QCOMPARE(phoneAccount->accountId(), mPhoneTpAccount->uniqueIdentifier()); } void TelepathyHelperTest::testAccountForConnection() { Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { AccountEntry *entry = TelepathyHelper::instance()->accountForConnection(account->account()->connection()); QVERIFY(entry); QCOMPARE(entry, account); } } void TelepathyHelperTest::testEmergencyCallsAvailable() { QSignalSpy emergencyCallsSpy(TelepathyHelper::instance(), SIGNAL(emergencyCallsAvailableChanged())); // check that calls are available by default TRY_VERIFY(TelepathyHelper::instance()->emergencyCallsAvailable()); // set the generic account as "flightmode" and make sure it doesn't affect the emergencyCallsAvailable mGenericController->SetPresence("flightmode", ""); QTest::qWait(500); QCOMPARE(emergencyCallsSpy.count(), 0); QVERIFY(TelepathyHelper::instance()->emergencyCallsAvailable()); // now set the phone account as "flightmode", and see if the emergencyCallsAvailable value mPhoneController->SetPresence("flightmode", ""); TRY_VERIFY(emergencyCallsSpy.count() > 0); QVERIFY(!TelepathyHelper::instance()->emergencyCallsAvailable()); // set the generic account online and check if it affects the value emergencyCallsSpy.clear(); mGenericController->SetOnline(true); QTest::qWait(500); QCOMPARE(emergencyCallsSpy.count(), 0); QVERIFY(!TelepathyHelper::instance()->emergencyCallsAvailable()); // and finally set the phone account back online mPhoneController->SetOnline(true); TRY_VERIFY(emergencyCallsSpy.count() > 0); QVERIFY(TelepathyHelper::instance()->emergencyCallsAvailable()); } Tp::AccountPtr TelepathyHelperTest::addAccountAndWait(const QString &manager, const QString &protocol, const QString &displayName, const QVariantMap ¶meters) { QSignalSpy accountAddedSpy(TelepathyHelper::instance(), SIGNAL(accountAdded(AccountEntry*))); Tp::AccountPtr account = addAccount(manager, protocol, displayName, parameters); WAIT_FOR(accountAddedSpy.count() == 1); AccountEntry *accountEntry = accountAddedSpy.first().first().value(); WAIT_FOR(accountEntry->ready()); // and make sure the status and status message are the ones we expect WAIT_FOR(accountEntry->status() == QString("available")); return account; } QTEST_MAIN(TelepathyHelperTest) #include "TelepathyHelperTest.moc" ./tests/libtelephonyservice/MultimediaAccountEntryTest.cpp0000644000015600001650000000426612677320771024337 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "multimediaaccountentry.h" #include "accountentryfactory.h" #include "mockcontroller.h" class MultimediaAccountEntryTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testAccountType(); private: MultimediaAccountEntry *mAccount; Tp::AccountPtr mMultimediaAccount; MockController *mMockController; }; void MultimediaAccountEntryTest::initTestCase() { initialize(); } void MultimediaAccountEntryTest::init() { mMultimediaAccount = addAccount("mock", "multimedia", "multimedia account"); QVERIFY(!mMultimediaAccount.isNull()); mAccount = qobject_cast(AccountEntryFactory::createEntry(mMultimediaAccount, this)); QVERIFY(mAccount); TRY_VERIFY(mAccount->ready()); // make sure the connection is available TRY_VERIFY(mAccount->connected()); // and make sure the status and status message are the ones we expect TRY_COMPARE(mAccount->status(), QString("available")); // create the mock controller mMockController = new MockController("multimedia", this); } void MultimediaAccountEntryTest::cleanup() { doCleanup(); mAccount->deleteLater(); mMockController->deleteLater(); } void MultimediaAccountEntryTest::testAccountType() { QCOMPARE(mAccount->type(), AccountEntry::MultimediaAccount); } QTEST_MAIN(MultimediaAccountEntryTest) #include "MultimediaAccountEntryTest.moc" ./tests/libtelephonyservice/CallNotificationTest.cpp0000644000015600001650000000430312677320771023120 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "callnotification.h" #define INDICATOR_DBUS_SERVICE_NAME "com.canonical.TelephonyServiceIndicator" #define INDICATOR_DBUS_OBJ_PATH "/com/canonical/TelephonyServiceIndicator" class CallNotificationTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void testClearCallNotification(); private: QDBusInterface *mIndicatorInterface; }; void CallNotificationTest::initTestCase() { mIndicatorInterface = new QDBusInterface(INDICATOR_DBUS_SERVICE_NAME, INDICATOR_DBUS_OBJ_PATH, INDICATOR_DBUS_SERVICE_NAME, QDBusConnection::sessionBus(), this); } void CallNotificationTest::cleanupTestCase() { mIndicatorInterface->deleteLater(); } void CallNotificationTest::testClearCallNotification() { QSignalSpy clearNotificationSpy(mIndicatorInterface, SIGNAL(ClearCallNotificationRequested(QString, QString))); QString targetId("theTargetId"); QString accountId("theAccountId"); CallNotification::instance()->clearCallNotification(targetId, accountId); QTRY_COMPARE(clearNotificationSpy.count(), 1); QCOMPARE(clearNotificationSpy.first()[0].toString(), targetId); QCOMPARE(clearNotificationSpy.first()[1].toString(), accountId); } QTEST_MAIN(CallNotificationTest) #include "CallNotificationTest.moc" ./tests/libtelephonyservice/OfonoAccountEntryTest.cpp0000644000015600001650000002160712677320771023323 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "ofonoaccountentry.h" #include "accountentryfactory.h" #include "mockcontroller.h" class OfonoAccountEntryTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testAccountType(); void testConnected(); void testCompareIds_data(); void testCompareIds(); void testEmergencyNumbers(); void testCountryCode(); void testSerial(); void testVoicemailIndicator(); void testVoicemailNumber(); void testVoicemailCount(); void testSimLocked(); void testEmergencyCallsAvailable_data(); void testEmergencyCallsAvailable(); void testNetworkName(); void testAddressableVCardFields(); private: OfonoAccountEntry *mAccount; Tp::AccountPtr mTpAccount; MockController *mMockController; }; void OfonoAccountEntryTest::initTestCase() { initialize(); } void OfonoAccountEntryTest::init() { mTpAccount = addAccount("mock", "ofono", "phone account"); QVERIFY(!mTpAccount.isNull()); mAccount = qobject_cast(AccountEntryFactory::createEntry(mTpAccount, this)); QVERIFY(mAccount); TRY_VERIFY(mAccount->ready()); // make sure the connection is available TRY_VERIFY(mAccount->connected()); // and make sure the status and status message are the ones we expect TRY_COMPARE(mAccount->status(), QString("available")); // create the mock controller mMockController = new MockController("ofono", this); } void OfonoAccountEntryTest::cleanup() { doCleanup(); mAccount->deleteLater(); mMockController->deleteLater(); } void OfonoAccountEntryTest::testAccountType() { QCOMPARE(mAccount->type(), AccountEntry::PhoneAccount); } void OfonoAccountEntryTest::testConnected() { // the mock account is enabled/connected by default, so make sure it is like that TRY_VERIFY(mAccount->connected()); // right now the ofono account connection status behave exactly like the generic class, // but as the code path is different, test it again QSignalSpy connectedChangedSpy(mAccount, SIGNAL(connectedChanged())); // now set the account offline and see if the active flag changes correctly mMockController->SetOnline(false); TRY_VERIFY(connectedChangedSpy.count() > 0); TRY_VERIFY(!mAccount->connected()); // now re-enable the account and check that the entry is updated connectedChangedSpy.clear(); mMockController->SetOnline(true); // because of the way the mock was implemented, sometimes this can return two connectedChanged() signals. TRY_VERIFY(connectedChangedSpy.count() > 0); TRY_VERIFY(mAccount->connected()); } void OfonoAccountEntryTest::testCompareIds_data() { QTest::addColumn("first"); QTest::addColumn("second"); QTest::addColumn("expectedResult"); QTest::newRow("identical values") << "1234567" << "1234567" << true; QTest::newRow("case difference") << "TestId" << "testid" << false; QTest::newRow("phone prefix") << "1234567" << "1231234567" << true; } void OfonoAccountEntryTest::testCompareIds() { QFETCH(QString, first); QFETCH(QString, second); QFETCH(bool, expectedResult); QCOMPARE(mAccount->compareIds(first, second), expectedResult); } void OfonoAccountEntryTest::testEmergencyNumbers() { // check that the list is not empty at startup QTRY_VERIFY(!mAccount->emergencyNumbers().isEmpty()); QSignalSpy emergencyNumbersChangedSpy(mAccount, SIGNAL(emergencyNumbersChanged())); QStringList numbers; numbers << "111" << "190" << "911"; qSort(numbers); mMockController->SetEmergencyNumbers(numbers); TRY_COMPARE(emergencyNumbersChangedSpy.count(), 1); QStringList emergencyNumbers = mAccount->emergencyNumbers(); qSort(emergencyNumbers); QCOMPARE(emergencyNumbers, numbers); } void OfonoAccountEntryTest::testCountryCode() { QSignalSpy countryCodeChangedSpy(mAccount, SIGNAL(countryCodeChanged())); // check that the countryCode is not empty at startup QTRY_VERIFY(!mAccount->countryCode().isEmpty()); QCOMPARE(mAccount->countryCode(), QString("US")); countryCodeChangedSpy.clear(); QString countryCode("BR"); mMockController->SetCountryCode("BR"); TRY_COMPARE(countryCodeChangedSpy.count(), 1); QString cc = mAccount->countryCode(); QCOMPARE(cc, countryCode); } void OfonoAccountEntryTest::testSerial() { TRY_COMPARE(mAccount->serial(), mMockController->serial()); } void OfonoAccountEntryTest::testVoicemailIndicator() { // voicemail indicator is off by default on the mock CM QVERIFY(!mAccount->voicemailIndicator()); QSignalSpy voiceMailIndicatorSpy(mAccount, SIGNAL(voicemailIndicatorChanged())); // set to true mMockController->SetVoicemailIndicator(true); TRY_COMPARE(voiceMailIndicatorSpy.count(), 1); QVERIFY(mAccount->voicemailIndicator()); // and set back to false voiceMailIndicatorSpy.clear(); mMockController->SetVoicemailIndicator(false); TRY_COMPARE(voiceMailIndicatorSpy.count(), 1); QVERIFY(!mAccount->voicemailIndicator()); } void OfonoAccountEntryTest::testVoicemailNumber() { // check that the number is not empty at startup TRY_VERIFY(!mAccount->voicemailNumber().isEmpty()); QSignalSpy voicemailNumberSpy(mAccount, SIGNAL(voicemailNumberChanged())); // try changing the number QString number("12345"); mMockController->SetVoicemailNumber(number); TRY_COMPARE(voicemailNumberSpy.count(), 1); QCOMPARE(mAccount->voicemailNumber(), number); } void OfonoAccountEntryTest::testVoicemailCount() { QSignalSpy voicemailCountSpy(mAccount, SIGNAL(voicemailCountChanged())); // check that the count is zero at startup QCOMPARE((int)mAccount->voicemailCount(), 0); // set it to a bigger value int count = 10; mMockController->SetVoicemailCount(count); TRY_COMPARE(voicemailCountSpy.count(), 1); QCOMPARE((int)mAccount->voicemailCount(), count); // and back to zero voicemailCountSpy.clear(); mMockController->SetVoicemailCount(0); TRY_COMPARE(voicemailCountSpy.count(), 1); QCOMPARE((int)mAccount->voicemailCount(), 0); } void OfonoAccountEntryTest::testSimLocked() { QSignalSpy simLockedSpy(mAccount, SIGNAL(simLockedChanged())); // check that it is not locked by default QVERIFY(!mAccount->simLocked()); // now try to set the status to simlocked mMockController->SetPresence("simlocked", "simlocked"); TRY_COMPARE(simLockedSpy.count(), 1); QVERIFY(mAccount->simLocked()); } void OfonoAccountEntryTest::testEmergencyCallsAvailable_data() { QTest::addColumn("status"); QTest::addColumn("available"); QTest::newRow("available") << "available" << true; QTest::newRow("away") << "away" << true; QTest::newRow("simlocked") << "simlocked" << true; QTest::newRow("flightmode") << "flightmode" << false; QTest::newRow("nosim") << "nosim" << true; QTest::newRow("nomodem") << "nomodem" << false; QTest::newRow("registered") << "registered" << true; QTest::newRow("roaming") << "roaming" << true; QTest::newRow("unregistered") << "unregistered" << true; QTest::newRow("denied") << "denied" << true; QTest::newRow("unknown") << "unknown" << true; QTest::newRow("searching") << "searching" << true; } void OfonoAccountEntryTest::testEmergencyCallsAvailable() { QFETCH(QString, status); QFETCH(bool, available); mMockController->SetPresence(status, ""); TRY_COMPARE(mAccount->status(), status); QCOMPARE(mAccount->emergencyCallsAvailable(), available); } void OfonoAccountEntryTest::testNetworkName() { QSignalSpy networkNameChangedSpy(mAccount, SIGNAL(statusMessageChanged())); // set the value QString statusMessage("SomeNetwork"); mMockController->SetPresence("available", statusMessage); TRY_COMPARE(networkNameChangedSpy.count(), 1); QCOMPARE(mAccount->networkName(), statusMessage); } void OfonoAccountEntryTest::testAddressableVCardFields() { QVERIFY(!mAccount->addressableVCardFields().isEmpty()); QCOMPARE(mAccount->addressableVCardFields(), mTpAccount->protocolInfo().addressableVCardFields()); } QTEST_MAIN(OfonoAccountEntryTest) #include "OfonoAccountEntryTest.moc" ./tests/libtelephonyservice/GreeterContactsTestServer.cpp0000644000015600001650000001606112677320771024165 0ustar jenkinsjenkins/* * 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 #include bool listGetCalled = false; bool userGetCalled = false; QString userPath = "/org/freedesktop/Accounts/User" + QString::number(getuid()); 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; }; class GreeterInterface : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.canonical.UnityGreeter") Q_PROPERTY(bool IsActive READ IsActive WRITE SetIsActive) public: GreeterInterface(QObject *parent = 0); bool IsActive() const; void SetIsActive(bool active); private: bool mIsActive; }; AccountsInterface::AccountsInterface(QObject *parent) : QObject(parent) { } QList AccountsInterface::ListCachedUsers() const { return QList() << QDBusObjectPath(userPath); } 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(userPath, "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(userPath, &telepathy, QDBusConnection::ExportScriptableContents); ListInterface list(&telepathy); connection.registerObject("/list", &list, QDBusConnection::ExportScriptableContents); GreeterInterface greeter; connection.registerObject("/", &greeter, QDBusConnection::ExportScriptableContents); connection.registerService("com.canonical.UnityGreeter"); connection.registerService("org.freedesktop.Accounts"); return a.exec(); } #include "GreeterContactsTestServer.moc" GreeterInterface::GreeterInterface(QObject *parent) : QObject(parent), mIsActive(false) { } bool GreeterInterface::IsActive() const { return mIsActive; } void GreeterInterface::SetIsActive(bool active) { mIsActive = active; QDBusMessage message; message = QDBusMessage::createSignal("/", "org.freedesktop.DBus.Properties", "PropertiesChanged"); message << "com.canonical.UnityGreeter"; QVariantMap changedProps; changedProps.insert("IsActive", QVariant(active)); message << changedProps; message << QStringList(); QDBusConnection::sessionBus().send(message); } ./tests/libtelephonyservice/PhoneUtilsTest.cpp0000644000015600001650000000732012677320771021772 0ustar jenkinsjenkins/* * 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" Q_DECLARE_METATYPE(PhoneUtils::PhoneNumberMatchType) 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 slash") << "+421 2/123 456 78" << 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" << PhoneUtils::NSN_MATCH; QTest::newRow("number with dash") << "1234-5678" << "12345678" << PhoneUtils::NSN_MATCH; QTest::newRow("number with area code") << "1231234567" << "1234567" << PhoneUtils::SHORT_NSN_MATCH; QTest::newRow("number with extension") << "12345678#123" << "12345678" << PhoneUtils::SHORT_NSN_MATCH; QTest::newRow("both numbers with extension") << "(123)12345678#1" << "12345678#1" << PhoneUtils::SHORT_NSN_MATCH; QTest::newRow("numbers with different extension") << "1234567#1" << "1234567#2" << PhoneUtils::NO_MATCH; QTest::newRow("short/emergency numbers") << "190" << "190" << PhoneUtils::EXACT_MATCH; QTest::newRow("different short/emergency numbers") << "911" << "11" << PhoneUtils::NO_MATCH; QTest::newRow("different numbers") << "12345678" << "1234567" << PhoneUtils::NO_MATCH; QTest::newRow("both non phone numbers") << "abcdefg" << "abcdefg" << PhoneUtils::EXACT_MATCH; QTest::newRow("different non phone numbers") << "abcdefg" << "bcdefg" << PhoneUtils::INVALID_NUMBER; QTest::newRow("phone number and custom string") << "abc12345678" << "12345678" << PhoneUtils::NSN_MATCH; QTest::newRow("phone number with slash") << "+421 2/123 456 78" << "212345678" << PhoneUtils::NSN_MATCH; // FIXME: check what other cases we need to test here" } void PhoneUtilsTest::testComparePhoneNumbers() { QFETCH(QString, number1); QFETCH(QString, number2); QFETCH(PhoneUtils::PhoneNumberMatchType, expectedResult); PhoneUtils::PhoneNumberMatchType result = PhoneUtils::comparePhoneNumbers(number1, number2); QCOMPARE(result, expectedResult); } QTEST_MAIN(PhoneUtilsTest) #include "PhoneUtilsTest.moc" ./tests/libtelephonyservice/TelepathyHelperSetupTest.cpp0000644000015600001650000000623712677320771024026 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "accountentry.h" #include "telepathyhelper.h" // inheriting just to make the constructor public for testing class TelepathyHelperWrapper : public TelepathyHelper { Q_OBJECT public: TelepathyHelperWrapper(QObject *parent = 0) : TelepathyHelper(parent) { } }; class TelepathyHelperSetupTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void cleanup(); void testTelepathyHelperReadyNoAccounts(); void testTelepathyHelperReady(); protected: Tp::AccountPtr addAccountAndWait(const QString &manager, const QString &protocol, const QString &displayName, const QVariantMap ¶meters = QVariantMap()); private: Tp::AccountPtr mGenericTpAccount1; Tp::AccountPtr mGenericTpAccount2; Tp::AccountPtr mPhoneTpAccount1; Tp::AccountPtr mPhoneTpAccount2; }; void TelepathyHelperSetupTest::initTestCase() { initialize(); } void TelepathyHelperSetupTest::testTelepathyHelperReadyNoAccounts() { TelepathyHelperWrapper telepathyHelper; QSignalSpy setupReadySpy(&telepathyHelper, SIGNAL(setupReady())); TRY_COMPARE(setupReadySpy.count(), 1); QVERIFY(telepathyHelper.ready()); QCOMPARE(telepathyHelper.accounts().size(), 0); } void TelepathyHelperSetupTest::testTelepathyHelperReady() { // add four accounts mGenericTpAccount1 = addAccount("mock", "mock", "the generic account 1"); QVERIFY(!mGenericTpAccount1.isNull()); mGenericTpAccount2 = addAccount("mock", "mock", "the generic account 2"); QVERIFY(!mGenericTpAccount2.isNull()); mPhoneTpAccount1 = addAccount("mock", "ofono", "the phone account 1"); QVERIFY(!mPhoneTpAccount1.isNull()); mPhoneTpAccount2 = addAccount("mock", "ofono", "the phone account 2"); QVERIFY(!mPhoneTpAccount2.isNull()); TelepathyHelperWrapper telepathyHelper; QSignalSpy setupReadySpy(&telepathyHelper, SIGNAL(setupReady())); TRY_COMPARE(setupReadySpy.count(), 1); QVERIFY(telepathyHelper.ready()); QCOMPARE(telepathyHelper.accounts().size(), 4); Q_FOREACH(const AccountEntry* account, telepathyHelper.accounts()) { QVERIFY(account->ready()); } } void TelepathyHelperSetupTest::cleanup() { // the accounts are removed in the parent class. doCleanup(); } QTEST_MAIN(TelepathyHelperSetupTest) #include "TelepathyHelperSetupTest.moc" ./tests/libtelephonyservice/ProtocolTest.cpp0000644000015600001650000000547012677320771021505 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "config.h" #include "protocol.h" // just to make the constructor public class TestProtocol : public Protocol { Q_OBJECT public: TestProtocol(const QString &name, Protocol::Features features, const QString &fallbackProtocol, const QString &backgroundFile, const QString &icon, const QString &serviceName = QString::null, QObject *parent = 0) : Protocol(name, features, fallbackProtocol, backgroundFile, icon, serviceName, parent) { } }; class ProtocolTest : public QObject { Q_OBJECT private Q_SLOTS: void testBasicInfo(); void testFromFile(); }; void ProtocolTest::testBasicInfo() { QString name("foobar"); Protocol::Features features(Protocol::TextChats); QString fallbackProtocol("theFallback"); QString backgroundImage("/tmp/background.png"); QString icon("/tmp/icon.png"); QString serviceName("The service"); TestProtocol protocol(name, features, fallbackProtocol, backgroundImage, icon, serviceName, this); QCOMPARE(protocol.name(), name); QCOMPARE(protocol.features(), features); QCOMPARE(protocol.fallbackProtocol(), fallbackProtocol); QCOMPARE(protocol.backgroundImage(), backgroundImage); QCOMPARE(protocol.icon(), icon); QCOMPARE(protocol.serviceName(), serviceName); QCOMPARE(protocol.parent(), this); } void ProtocolTest::testFromFile() { // check that calling fromFile() on an invalid path returns 0 Protocol *nullProtocol = Protocol::fromFile("/non/existent/path/to/a/dummy.protocol"); QVERIFY(!nullProtocol); // and now check a valid protocol Protocol *protocol = Protocol::fromFile(protocolsDir() + "/foo.protocol"); QVERIFY(protocol); QCOMPARE(protocol->name(), QString("foo")); QCOMPARE(protocol->features(), Protocol::Features(Protocol::TextChats | Protocol::VoiceCalls)); QCOMPARE(protocol->fallbackProtocol(), QString("bar")); QCOMPARE(protocol->backgroundImage(), QString("/tmp/background.png")); QCOMPARE(protocol->icon(), QString("/tmp/icon.png")); QCOMPARE(protocol->serviceName(), QString("The Service")); } QTEST_MAIN(ProtocolTest) #include "ProtocolTest.moc" ./tests/libtelephonyservice/ToneGeneratorMock.cpp0000644000015600001650000000361712677320771022433 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 #define TONEGEN_DBUS_SERVICE_NAME "com.Nokia.Telephony.Tones" #define TONEGEN_DBUS_OBJ_PATH "/com/Nokia/Telephony/Tones" class ToneGeneratorMock : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", TONEGEN_DBUS_SERVICE_NAME) public: Q_SCRIPTABLE void StartEventTone(uint key, int volume, uint duration); Q_SCRIPTABLE void StopTone(); Q_SIGNALS: Q_SCRIPTABLE void StartEventToneRequested(uint key, int volume, uint duration); Q_SCRIPTABLE void StopToneRequested(); }; void ToneGeneratorMock::StartEventTone(uint key, int volume, uint duration) { Q_EMIT StartEventToneRequested(key, volume, duration); } void ToneGeneratorMock::StopTone() { Q_EMIT StopToneRequested(); } int main(int argc, char **argv) { QCoreApplication a(argc, argv); QDBusConnection connection = QDBusConnection::sessionBus(); ToneGeneratorMock toneGen; connection.registerObject(TONEGEN_DBUS_OBJ_PATH, &toneGen, QDBusConnection::ExportScriptableContents); connection.registerService(TONEGEN_DBUS_SERVICE_NAME); return a.exec(); } #include "ToneGeneratorMock.moc" ./tests/libtelephonyservice/ChatManagerTest.cpp0000644000015600001650000002210612677320771022051 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "telepathytest.h" #include "accountentry.h" #include "chatmanager.h" #include "telepathyhelper.h" #include "mockcontroller.h" class ChatManagerTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testSendMessage_data(); void testSendMessage(); void testSendMessageWithAttachments_data(); void testSendMessageWithAttachments(); void testMessageReceived(); void testAcknowledgeMessages(); void testChatEntry(); private: Tp::AccountPtr mGenericTpAccount; Tp::AccountPtr mPhoneTpAccount; MockController *mGenericMockController; MockController *mPhoneMockController; }; void ChatManagerTest::initTestCase() { initialize(); // set to false so group chat messages are not sent as MMS mPhoneSettings.set("mmsGroupChatEnabled", false); TelepathyHelper::instance()->registerChannelObserver(); // just give telepathy some time to register the observer QTest::qWait(1000); } void ChatManagerTest::init() { // add two accounts mGenericTpAccount = addAccount("mock", "mock", "the generic account"); QVERIFY(!mGenericTpAccount.isNull()); mPhoneTpAccount = addAccount("mock", "ofono", "the phone account"); QVERIFY(!mPhoneTpAccount.isNull()); // and create the mock controller mGenericMockController = new MockController("mock", this); mPhoneMockController = new MockController("ofono", this); } void ChatManagerTest::cleanup() { // the accounts are removed in the parent class. doCleanup(); mGenericMockController->deleteLater(); mPhoneMockController->deleteLater(); } void ChatManagerTest::testSendMessage_data() { QTest::addColumn("recipients"); QTest::addColumn("message"); QTest::addColumn("accountId"); QTest::newRow("message via the generic account") << (QStringList() << "recipient1") << QString("Hello world") << QString("mock/mock/account0"); QTest::newRow("message via the phone account") << (QStringList() << "recipient2") << QString("Hello Phone World") << QString("mock/ofono/account0"); QTest::newRow("multiple recipients") << (QStringList() << "123" << "456" << "789") << QString("Hi friends!") << QString("mock/mock/account0"); } void ChatManagerTest::testSendMessage() { QFETCH(QStringList, recipients); QFETCH(QString, message); QFETCH(QString, accountId); // just to make it easier, sort the recipients qSort(recipients); MockController *controller = accountId.startsWith("mock/mock") ? mGenericMockController : mPhoneMockController; QSignalSpy controllerMessageSentSpy(controller, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); QSignalSpy messageSentSpy(ChatManager::instance(), SIGNAL(messageSent(QStringList,QString))); ChatManager::instance()->sendMessage(accountId, recipients, message); TRY_COMPARE(controllerMessageSentSpy.count(), 1); QString messageText = controllerMessageSentSpy.first()[0].toString(); QVariantMap messageProperties = controllerMessageSentSpy.first()[2].toMap(); QStringList messageRecipients = messageProperties["Recipients"].toStringList(); qSort(messageRecipients); QCOMPARE(messageText, message); QCOMPARE(messageRecipients, recipients); TRY_COMPARE(messageSentSpy.count(), 1); messageRecipients = messageSentSpy.first()[0].toStringList(); qSort(messageRecipients); messageText = messageSentSpy.first()[1].toString(); QCOMPARE(messageText, message); QCOMPARE(messageRecipients, recipients); } void ChatManagerTest::testMessageReceived() { QSignalSpy messageReceivedSpy(ChatManager::instance(), SIGNAL(messageReceived(QString,QString,QDateTime,QString,bool))); QVariantMap properties; properties["Sender"] = "12345"; properties["Recipients"] = (QStringList() << "12345"); QString message("Hi there"); mGenericMockController->PlaceIncomingMessage(message, properties); TRY_COMPARE(messageReceivedSpy.count(), 1); QString sender = messageReceivedSpy.first()[0].toString(); QString receivedMessage = messageReceivedSpy.first()[1].toString(); QCOMPARE(sender, properties["Sender"].toString()); QCOMPARE(receivedMessage, message); } void ChatManagerTest::testAcknowledgeMessages() { QSignalSpy messageReceivedSpy(ChatManager::instance(), SIGNAL(messageReceived(QString,QString,QDateTime,QString,bool))); QVariantMap properties; properties["Sender"] = "12345"; properties["Recipients"] = (QStringList() << "12345"); QStringList messages; messages << "Hi there" << "How are you" << "Always look on the bright side of life"; Q_FOREACH(const QString &message, messages) { mGenericMockController->PlaceIncomingMessage(message, properties); // the wait shouldn't be needed, but just in case QTest::qWait(50); } TRY_COMPARE(messageReceivedSpy.count(), messages.count()); QStringList messageIds; for (int i = 0; i < messages.count(); ++i) { QString messageId = messageReceivedSpy[i][3].toString(); messageIds << messageId; } QSignalSpy messageReadSpy(mGenericMockController, SIGNAL(MessageRead(QString))); Q_FOREACH(const QString &messageId, messageIds) { ChatManager::instance()->acknowledgeMessage(properties["Recipients"].toStringList(), messageId, "mock/mock/account0"); } TRY_COMPARE(messageReadSpy.count(), messageIds.count()); QStringList receivedIds; for (int i = 0; i < messageReadSpy.count(); ++i) { receivedIds << messageReadSpy[i][0].toString(); } qSort(receivedIds); qSort(messageIds); QCOMPARE(receivedIds, messageIds); } void ChatManagerTest::testChatEntry() { QStringList recipients; recipients << "user@domain.com" << "user2@domain.com"; QSignalSpy chatEntryCreatedSpy(ChatManager::instance(), SIGNAL(chatEntryCreated(QString, QStringList,ChatEntry *))); ChatEntry *entry = ChatManager::instance()->chatEntryForParticipants("mock/mock/account0", recipients, true); QVERIFY(entry == NULL); QTRY_COMPARE(chatEntryCreatedSpy.count(), 1); entry = ChatManager::instance()->chatEntryForParticipants("mock/mock/account0", recipients, false); QVERIFY(entry != NULL); QList arguments = chatEntryCreatedSpy.takeFirst(); QCOMPARE(QString("mock/mock/account0"), arguments.at(0).toString()); QCOMPARE(recipients.toSet(), arguments.at(1).toStringList().toSet()); QCOMPARE(entry, arguments.at(2).value()); } void ChatManagerTest::testSendMessageWithAttachments_data() { QTest::addColumn("recipients"); QTest::addColumn("message"); QTest::addColumn("accountId"); QTest::addColumn("mmsFlag"); QTest::newRow("message via the generic account") << (QStringList() << "recipient1") << QString("Hello world") << QString("mock/mock/account0") << false; QTest::newRow("message via the phone account") << (QStringList() << "1234567") << QString("Hello Phone World") << QString("mock/ofono/account0") << true; } void ChatManagerTest::testSendMessageWithAttachments() { QFETCH(QStringList, recipients); QFETCH(QString, message); QFETCH(QString, accountId); QFETCH(bool, mmsFlag); // just to make it easier, sort the recipients qSort(recipients); MockController *controller = accountId.startsWith("mock/mock") ? mGenericMockController : mPhoneMockController; QSignalSpy controllerMessageSentSpy(controller, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); QVariantList attachmentList; QVariantList attachment; attachment << "id" << "content/type" << "filepath"; attachmentList << QVariant::fromValue(attachment); QVariant attachments = QVariant::fromValue(attachmentList); ChatManager::instance()->sendMessage(accountId, recipients, message, attachments); TRY_COMPARE(controllerMessageSentSpy.count(), 1); QString messageText = controllerMessageSentSpy.first()[0].toString(); QVariantMap messageProperties = controllerMessageSentSpy.first()[2].toMap(); QStringList messageRecipients = messageProperties["Recipients"].toStringList(); qSort(messageRecipients); QCOMPARE(messageText, message); QCOMPARE(messageRecipients, recipients); QCOMPARE(messageProperties.contains("x-canonical-mms"), mmsFlag); QCOMPARE(messageProperties["x-canonical-mms"].toBool(), mmsFlag); } QTEST_MAIN(ChatManagerTest) #include "ChatManagerTest.moc" ./tests/libtelephonyservice/CMakeLists.txt0000644000015600001650000001017112677320771021072 0ustar jenkinsjenkinsset(LIBTELEPHONYSERVICE_DIR ${CMAKE_SOURCE_DIR}/libtelephonyservice) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${LIBTELEPHONYSERVICE_DIR} ${TP_QT5_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/tests/common ${CMAKE_BINARY_DIR}/tests/common ${GSETTINGS_QT_INCLUDE_DIRS} ) add_executable(GreeterContactsTestServerExe GreeterContactsTestServer.cpp) qt5_use_modules(GreeterContactsTestServerExe Core DBus) add_executable(ToneGeneratorMock ToneGeneratorMock.cpp) qt5_use_modules(ToneGeneratorMock Core DBus) add_executable(IndicatorMock IndicatorMock.cpp) qt5_use_modules(IndicatorMock Core DBus) generate_test(GreeterContactsTest USE_DBUS SOURCES GreeterContactsTest.cpp ${LIBTELEPHONYSERVICE_DIR}/greetercontacts.cpp QT5_MODULES Contacts Core DBus Test ENVIRONMENT XDG_SESSION_CLASS=greeter XDG_GREETER_DATA_DIR=${CMAKE_BINARY_DIR}/Testing/Temporary TASKS --task ${CMAKE_CURRENT_BINARY_DIR}/GreeterContactsTestServerExe --task-name server --ignore-return WAIT_FOR org.freedesktop.Accounts) set_target_properties(GreeterContactsTest PROPERTIES COMPILE_DEFINITIONS "AS_BUSNAME=sessionBus;CMAKE_SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\"") add_dependencies(GreeterContactsTest GreeterContactsTestServerExe) generate_test(GreeterContactsThreadTest USE_DBUS SOURCES GreeterContactsThreadTest.cpp ${LIBTELEPHONYSERVICE_DIR}/greetercontacts.cpp QT5_MODULES Contacts Core DBus Test ENVIRONMENT XDG_SESSION_CLASS=greeter XDG_GREETER_DATA_DIR=${CMAKE_BINARY_DIR}/Testing/Temporary TASKS --task ${CMAKE_CURRENT_BINARY_DIR}/GreeterContactsTestServerExe --task-name server --ignore-return WAIT_FOR org.freedesktop.Accounts) set_target_properties(GreeterContactsThreadTest PROPERTIES COMPILE_DEFINITIONS "AS_BUSNAME=sessionBus;CMAKE_SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\"") add_dependencies(GreeterContactsThreadTest GreeterContactsTestServerExe) generate_test(ToneGeneratorTest USE_DBUS SOURCES ToneGeneratorTest.cpp ${LIBTELEPHONYSERVICE_DIR}/tonegenerator.cpp QT5_MODULES Core DBus Test TASKS --task ${CMAKE_CURRENT_BINARY_DIR}/ToneGeneratorMock --task-name tone-gen --ignore-return WAIT_FOR com.Nokia.Telephony.Tones) add_dependencies(ToneGeneratorTest ToneGeneratorMock) generate_test(CallNotificationTest USE_DBUS SOURCES CallNotificationTest.cpp ${LIBTELEPHONYSERVICE_DIR}/callnotification.cpp QT5_MODULES Core DBus Test TASKS --task ${CMAKE_CURRENT_BINARY_DIR}/IndicatorMock --task-name indicator --ignore-return WAIT_FOR com.canonical.TelephonyServiceIndicator) generate_test(ContactUtilsTest SOURCES ContactUtilsTest.cpp QT5_MODULES Contacts Core Test LIBRARIES telephonyservice USE_UI) generate_test(PhoneUtilsTest SOURCES PhoneUtilsTest.cpp LIBRARIES telephonyservice USE_UI) generate_test(ProtocolTest SOURCES ProtocolTest.cpp ${LIBTELEPHONYSERVICE_DIR}/protocol.cpp ENVIRONMENT TELEPHONY_SERVICE_PROTOCOLS_DIR=${CMAKE_CURRENT_SOURCE_DIR}/testProtocols) generate_test(ProtocolManagerTest SOURCES ProtocolManagerTest.cpp ${LIBTELEPHONYSERVICE_DIR}/protocol.cpp ${LIBTELEPHONYSERVICE_DIR}/protocolmanager.cpp QT5_MODULES Core Qml Test ENVIRONMENT TELEPHONY_SERVICE_PROTOCOLS_DIR=${CMAKE_CURRENT_SOURCE_DIR}/testProtocols) generate_telepathy_test(AccountEntryFactoryTest SOURCES AccountEntryFactoryTest.cpp) generate_telepathy_test(AccountEntryTest SOURCES AccountEntryTest.cpp) generate_telepathy_test(CallEntryTest SOURCES CallEntryTest.cpp) generate_telepathy_test(ChatManagerTest SOURCES ChatManagerTest.cpp) generate_telepathy_test(ChatEntryTest SOURCES ChatEntryTest.cpp) generate_telepathy_test(MultimediaAccountEntryTest SOURCES MultimediaAccountEntryTest.cpp) generate_telepathy_test(OfonoAccountEntryTest SOURCES OfonoAccountEntryTest.cpp) generate_telepathy_test(TelepathyHelperSetupTest SOURCES TelepathyHelperSetupTest.cpp) generate_telepathy_test(TelepathyHelperTest SOURCES TelepathyHelperTest.cpp) generate_telepathy_test(USSDManagerTest SOURCES USSDManagerTest.cpp) ./tests/libtelephonyservice/IndicatorMock.cpp0000644000015600001650000000401512677320771021564 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 #define INDICATOR_DBUS_SERVICE_NAME "com.canonical.TelephonyServiceIndicator" #define INDICATOR_DBUS_OBJ_PATH "/com/canonical/TelephonyServiceIndicator" class IndicatorMock : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", INDICATOR_DBUS_SERVICE_NAME) public: Q_SCRIPTABLE void ClearNotifications(); Q_SCRIPTABLE void ClearCallNotification(const QString &targetId, const QString &accountId); Q_SIGNALS: Q_SCRIPTABLE void ClearNotificationsRequested(); Q_SCRIPTABLE void ClearCallNotificationRequested(const QString &targetId, const QString &accountId); }; void IndicatorMock::ClearNotifications() { Q_EMIT ClearNotificationsRequested(); } void IndicatorMock::ClearCallNotification(const QString &targetId, const QString &accountId) { Q_EMIT ClearCallNotificationRequested(targetId, accountId); } int main(int argc, char **argv) { QCoreApplication a(argc, argv); QDBusConnection connection = QDBusConnection::sessionBus(); IndicatorMock toneGen; connection.registerObject(INDICATOR_DBUS_OBJ_PATH, &toneGen, QDBusConnection::ExportScriptableContents); connection.registerService(INDICATOR_DBUS_SERVICE_NAME); return a.exec(); } #include "IndicatorMock.moc" ./tests/libtelephonyservice/GreeterContactsTest.cpp0000644000015600001650000002311612677320771022775 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 #include #include Q_DECLARE_METATYPE(QtContacts::QContact) // for QVariant's benefit QTCONTACTS_USE_NAMESPACE class GreeterContactsWrapper : public GreeterContacts { Q_OBJECT public: GreeterContactsWrapper() : GreeterContacts() {} }; 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(); void testGreeterIsActive(); private: void waitForUpdatedSignal(bool convertedPath = false); void makeGreeterContacts(); void waitForInitialQuery(); QContact makeTestContact(bool convertedPath = false); QVariantMap makeTestMap(); void setActiveEntry(bool currentUser); void setCurrentContact(const QVariantMap &map); void setUseInvalidated(const QString &path, const QString &interface, bool useInvalidated); void setGreeterActive(bool active); QString mUserPath; GreeterContacts *mGreeterContacts; QSignalSpy *mSpy; }; GreeterContactsTest::GreeterContactsTest() : QObject() { mUserPath = "/org/freedesktop/Accounts/User" + QString::number(getuid()); } void GreeterContactsTest::initTestCase() { mGreeterContacts = NULL; mSpy = NULL; qRegisterMetaType(); } void GreeterContactsTest::cleanup() { if (mSpy) { delete mSpy; mSpy = NULL; } if (mGreeterContacts) { delete mGreeterContacts; mGreeterContacts = NULL; } setActiveEntry(false); setCurrentContact(QVariantMap()); setUseInvalidated("/list", "com.canonical.UnityGreeter.List", false); setUseInvalidated(mUserPath, "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(true); setCurrentContact(makeTestMap()); makeGreeterContacts(); setFilter(); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnFilter() { setActiveEntry(true); 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(true); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnEntryInvalidated() { setCurrentContact(makeTestMap()); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setUseInvalidated("/list", "com.canonical.UnityGreeter.List", true); setActiveEntry(true); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnContacts() { setActiveEntry(true); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setCurrentContact(makeTestMap()); waitForUpdatedSignal(); } void GreeterContactsTest::testSignalOnContactsInvalidated() { setActiveEntry(true); makeGreeterContacts(); setFilter(); waitForInitialQuery(); setUseInvalidated(mUserPath, "com.canonical.TelephonyServiceApprover", true); setCurrentContact(makeTestMap()); waitForUpdatedSignal(); } void GreeterContactsTest::testEmitContact() { setActiveEntry(true); makeGreeterContacts(); setFilter(); waitForInitialQuery(); // this next line acts like setCurrentContact() because uid is set to 12345 GreeterContacts::emitContact(makeTestContact()); waitForUpdatedSignal(true); } void GreeterContactsTest::testGreeterIsActive() { makeGreeterContacts(); // check that by default it is false QCOMPARE(mGreeterContacts->greeterActive(), false); QSignalSpy spy(mGreeterContacts, SIGNAL(greeterActiveChanged())); // now set it to true setGreeterActive(true); QTRY_COMPARE(spy.count(), 1); QCOMPARE(mGreeterContacts->greeterActive(), 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(bool currentUser) { QString entry = ""; if (currentUser) entry = getpwuid(getuid())->pw_name; 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", mUserPath, "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", mUserPath, "com.canonical.TelephonyServiceApprover", QDBusConnection::sessionBus()); QSignalSpy spy(&iface, SIGNAL(InitialQueriesDone())); QTRY_COMPARE(spy.count(), 1); } void GreeterContactsTest::makeGreeterContacts() { mGreeterContacts = new GreeterContactsWrapper(); mSpy = new QSignalSpy(mGreeterContacts, SIGNAL(contactUpdated(QtContacts::QContact))); } void GreeterContactsTest::waitForUpdatedSignal(bool convertedPath) { QTRY_COMPARE(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()); } void GreeterContactsTest::setGreeterActive(bool active) { QDBusInterface iface("com.canonical.UnityGreeter", "/", "org.freedesktop.DBus.Properties", QDBusConnection::sessionBus()); QDBusReply reply = iface.call("Set", "com.canonical.UnityGreeter", "IsActive", QVariant::fromValue(QDBusVariant(QVariant(active)))); QVERIFY(reply.isValid()); } QTEST_MAIN(GreeterContactsTest) #include "GreeterContactsTest.moc" ./tests/libtelephonyservice/testProtocols/0000755000015600001650000000000012677320772021217 5ustar jenkinsjenkins./tests/libtelephonyservice/testProtocols/voice.protocol0000644000015600001650000000004512677320771024105 0ustar jenkinsjenkins[Protocol] Name=voice Features=voice ./tests/libtelephonyservice/testProtocols/text.protocol0000644000015600001650000000004312677320771023762 0ustar jenkinsjenkins[Protocol] Name=text Features=text ./tests/libtelephonyservice/testProtocols/bar.protocol0000644000015600001650000000005012677320771023540 0ustar jenkinsjenkins[Protocol] Name=bar Features=text,voice ./tests/libtelephonyservice/testProtocols/foo.protocol0000644000015600001650000000021412677320771023561 0ustar jenkinsjenkins[Protocol] Name=foo Features=text,voice FallbackProtocol=bar BackgroundImage=/tmp/background.png Icon=/tmp/icon.png ServiceName=The Service ./tests/libtelephonyservice/ToneGeneratorTest.cpp0000644000015600001650000000727312677320771022463 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "tonegenerator.h" #define TONEGEN_DBUS_SERVICE_NAME "com.Nokia.Telephony.Tones" #define TONEGEN_DBUS_OBJ_PATH "/com/Nokia/Telephony/Tones" class ToneGeneratorTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void cleanup(); void testSingleTone_data(); void testSingleTone(); void testMultipleTones(); void testWaitingTone(); void testCallEndedTone(); private: QDBusInterface *mToneInterface; QSignalSpy *mStartToneSpy; QSignalSpy *mStopToneSpy; }; void ToneGeneratorTest::initTestCase() { mToneInterface = new QDBusInterface(TONEGEN_DBUS_SERVICE_NAME, TONEGEN_DBUS_OBJ_PATH, TONEGEN_DBUS_SERVICE_NAME, QDBusConnection::sessionBus(), this); mStartToneSpy = new QSignalSpy(mToneInterface, SIGNAL(StartEventToneRequested(uint, int, uint))); mStopToneSpy = new QSignalSpy(mToneInterface,SIGNAL(StopToneRequested())); } void ToneGeneratorTest::cleanupTestCase() { mToneInterface->deleteLater(); mStartToneSpy->deleteLater(); mStopToneSpy->deleteLater(); } void ToneGeneratorTest::cleanup() { mStartToneSpy->clear(); mStopToneSpy->clear(); } void ToneGeneratorTest::testSingleTone_data() { QTest::addColumn("key"); QTest::newRow("0") << (uint)0; QTest::newRow("1") << (uint)1; QTest::newRow("2") << (uint)2; QTest::newRow("3") << (uint)3; QTest::newRow("4") << (uint)4; QTest::newRow("5") << (uint)5; QTest::newRow("6") << (uint)6; QTest::newRow("7") << (uint)7; QTest::newRow("8") << (uint)8; QTest::newRow("9") << (uint)9; QTest::newRow("10") << (uint)10; QTest::newRow("11") << (uint)11; } void ToneGeneratorTest::testSingleTone() { QFETCH(uint, key); ToneGenerator::instance()->playDTMFTone(key); QTRY_COMPARE(mStartToneSpy->count(), 1); QCOMPARE(mStartToneSpy->first()[0].toUInt(), key); QTRY_COMPARE(mStopToneSpy->count(), 1); } void ToneGeneratorTest::testMultipleTones() { int count = 12; for (uint key = 0; key < count; ++key) { ToneGenerator::instance()->playDTMFTone(key); } QTRY_COMPARE(mStartToneSpy->count(), count); QTRY_COMPARE(mStopToneSpy->count(), 1); } void ToneGeneratorTest::testWaitingTone() { ToneGenerator::instance()->playWaitingTone(); QTRY_COMPARE(mStartToneSpy->count(), 1); QCOMPARE(mStartToneSpy->first()[0].toUInt(), WAITING_TONE); ToneGenerator::instance()->stopWaitingTone(); QTRY_COMPARE(mStopToneSpy->count(), 1); } void ToneGeneratorTest::testCallEndedTone() { ToneGenerator::instance()->playCallEndedTone(); QTRY_COMPARE(mStartToneSpy->count(), 1); QCOMPARE(mStartToneSpy->first()[0].toUInt(), CALL_ENDED_TONE); QTRY_COMPARE(mStopToneSpy->count(), 1); } QTEST_MAIN(ToneGeneratorTest) #include "ToneGeneratorTest.moc" ./tests/libtelephonyservice/GreeterContactsThreadTest.cpp0000644000015600001650000000413612677320771024126 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 Q_DECLARE_METATYPE(QtContacts::QContact) // for QVariant's benefit QTCONTACTS_USE_NAMESPACE class GreeterContactsThreadTest : public QObject { Q_OBJECT private Q_SLOTS: void testSingletonAcrossThreads(); }; void GreeterContactsThreadTest::testSingletonAcrossThreads() { // make sure that the ::instance() method works across threads QThread thread1; thread1.start(); QTimer timer1; GreeterContacts *singleton1 = nullptr; timer1.moveToThread(&thread1); connect(&timer1, &QTimer::timeout, [&]() { singleton1 = GreeterContacts::instance(); thread1.quit(); }); timer1.setSingleShot(true); timer1.setInterval(0); QThread thread2; thread2.start(); QTimer timer2; GreeterContacts *singleton2 = nullptr; timer2.moveToThread(&thread2); connect(&timer2, &QTimer::timeout, [&]() { singleton2 = GreeterContacts::instance(); thread2.quit(); }); timer2.setSingleShot(true); timer2.setInterval(0); QMetaObject::invokeMethod(&timer1, "start", Qt::QueuedConnection); QMetaObject::invokeMethod(&timer2, "start", Qt::QueuedConnection); QTRY_VERIFY(thread1.wait()); QTRY_VERIFY(thread2.wait()); QVERIFY(singleton1); QVERIFY(singleton2); QCOMPARE(singleton1, singleton2); } QTEST_MAIN(GreeterContactsThreadTest) #include "GreeterContactsThreadTest.moc" ./tests/libtelephonyservice/USSDManagerTest.cpp0000644000015600001650000002543112677320771021754 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "ofonoaccountentry.h" #include "accountentryfactory.h" #include "telepathyhelper.h" #include "mockcontroller.h" #include "ussdmanager.h" class USSDManagerTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testInitiate(); void testRespond(); void testCancel(); void testActive_data(); void testActive(); void testActiveChanged(); void testState(); void testNotificationReceived(); void testRequestReceived(); void testInitiateUSSDComplete(); void testRespondComplete_data(); void testRespondComplete(); void testBarringComplete(); void testForwardingComplete(); void testWaitingComplete(); void testCallingLinePresentationComplete(); void testConnectedLinePresentationComplete(); void testCallingLineRestrictionComplete(); void testConnectedLineRestrictionComplete(); void testInitiateFailed(); void testAccountReconnect(); private: OfonoAccountEntry *mAccount; Tp::AccountPtr mTpAccount; MockController *mMockController; USSDManager *mManager; }; void USSDManagerTest::initTestCase() { initialize(); } void USSDManagerTest::init() { mTpAccount = addAccount("mock", "ofono", "the account"); QVERIFY(!mTpAccount.isNull()); QTRY_VERIFY(mTpAccount->isReady(Tp::Account::FeatureCore)); mAccount = qobject_cast(AccountEntryFactory::createEntry(mTpAccount, this)); QVERIFY(mAccount); // make sure the connection is available QTRY_VERIFY(!mTpAccount->connection().isNull()); QTRY_COMPARE(mTpAccount->connection()->selfContact()->presence().type(), Tp::ConnectionPresenceTypeAvailable); QTRY_VERIFY(mAccount->connected()); // and create the mock controller mMockController = new MockController("ofono", this); mManager = new USSDManager(mAccount, mAccount); } void USSDManagerTest::cleanup() { doCleanup(); mAccount->deleteLater(); mMockController->deleteLater(); mManager->deleteLater(); } void USSDManagerTest::testInitiate() { QString command("initiatecommand"); QSignalSpy initiateSpy(mMockController, SIGNAL(USSDInitiateCalled(QString))); mManager->initiate(command); QTRY_COMPARE(initiateSpy.count(), 1); QCOMPARE(initiateSpy.first()[0].toString(), command); } void USSDManagerTest::testRespond() { QString reply("somereply"); QSignalSpy respondSpy(mMockController, SIGNAL(USSDRespondCalled(QString))); mManager->respond(reply); QTRY_COMPARE(respondSpy.count(), 1); QCOMPARE(respondSpy.first()[0].toString(), reply); } void USSDManagerTest::testCancel() { QSignalSpy cancelSpy(mMockController, SIGNAL(USSDCancelCalled())); mManager->cancel(); QTRY_COMPARE(cancelSpy.count(), 1); } void USSDManagerTest::testActive_data() { QTest::addColumn("state"); QTest::addColumn("active"); QTest::newRow("idle is inactive") << "idle" << false; QTest::newRow("active is active") << "active" << true; QTest::newRow("anything else is active") << "blabla" << true; } void USSDManagerTest::testActive() { QFETCH(QString, state); QFETCH(bool, active); mMockController->TriggerUSSDStateChanged(state); QTRY_COMPARE(mManager->active(), active); } void USSDManagerTest::testActiveChanged() { QSignalSpy activeSpy(mManager, SIGNAL(activeChanged())); mMockController->TriggerUSSDStateChanged("active"); QTRY_COMPARE(activeSpy.count(), 1); } void USSDManagerTest::testState() { QString state = "foobar"; QSignalSpy stateSpy(mManager, SIGNAL(stateChanged(QString))); mMockController->TriggerUSSDStateChanged(state); QTRY_COMPARE(stateSpy.count(), 1); QCOMPARE(stateSpy.first()[0].toString(), state); QCOMPARE(mManager->state(), state); } void USSDManagerTest::testNotificationReceived() { QString notification("the notification"); QSignalSpy notificationReceivedSpy(mManager, SIGNAL(notificationReceived(QString))); mMockController->TriggerUSSDNotificationReceived(notification); QTRY_COMPARE(notificationReceivedSpy.count(), 1); QCOMPARE(notificationReceivedSpy.first()[0].toString(), notification); } void USSDManagerTest::testRequestReceived() { QString request("the notification"); QSignalSpy requestReceivedSpy(mManager, SIGNAL(requestReceived(QString))); mMockController->TriggerUSSDRequestReceived(request); QTRY_COMPARE(requestReceivedSpy.count(), 1); QCOMPARE(requestReceivedSpy.first()[0].toString(), request); } void USSDManagerTest::testInitiateUSSDComplete() { QString response("some response"); QSignalSpy initiateUSSDCompleteSpy(mManager, SIGNAL(initiateUSSDComplete(QString))); mMockController->TriggerUSSDInitiateUSSDComplete(response); QTRY_COMPARE(initiateUSSDCompleteSpy.count(), 1); QCOMPARE(initiateUSSDCompleteSpy.first()[0].toString(), response); } void USSDManagerTest::testRespondComplete_data() { QTest::addColumn("success"); QTest::addColumn("response"); QTest::newRow("success") << true << "somesuccessvalue"; QTest::newRow("failure") << false << "somefailurevalue"; } void USSDManagerTest::testRespondComplete() { QFETCH(bool, success); QFETCH(QString, response); QSignalSpy respondCompleteSpy(mManager, SIGNAL(respondComplete(bool,QString))); mMockController->TriggerUSSDRespondComplete(success, response); QTRY_COMPARE(respondCompleteSpy.count(), 1); QCOMPARE(respondCompleteSpy.first()[0].toBool(), success); QCOMPARE(respondCompleteSpy.first()[1].toString(), response); } void USSDManagerTest::testBarringComplete() { QString op("theOp"); QString service("theService"); QVariantMap map; map["op"] = op; map["service"] = service; QSignalSpy barringCompleteSpy(mManager, SIGNAL(barringComplete(QString,QString,QVariantMap))); mMockController->TriggerUSSDBarringComplete(op, service, map); QTRY_COMPARE(barringCompleteSpy.count(), 1); QCOMPARE(barringCompleteSpy.first()[0].toString(), op); QCOMPARE(barringCompleteSpy.first()[1].toString(), service); QCOMPARE(barringCompleteSpy.first()[2].toMap(), map); } void USSDManagerTest::testForwardingComplete() { QString op("theOtherOp"); QString service("theOtherService"); QVariantMap map; map["op"] = op; map["service"] = service; map["count"] = 1; QSignalSpy forwardingCompleteSpy(mManager, SIGNAL(forwardingComplete(QString,QString,QVariantMap))); mMockController->TriggerUSSDForwardingComplete(op, service, map); QTRY_COMPARE(forwardingCompleteSpy.count(), 1); QCOMPARE(forwardingCompleteSpy.first()[0].toString(), op); QCOMPARE(forwardingCompleteSpy.first()[1].toString(), service); QCOMPARE(forwardingCompleteSpy.first()[2].toMap(), map); } void USSDManagerTest::testWaitingComplete() { QString op("anotherOp"); QVariantMap map; map["op"] = op; map["one"] = 1; map["two"] = 2; QSignalSpy waitingCompleteSpy(mManager, SIGNAL(waitingComplete(QString,QVariantMap))); mMockController->TriggerUSSDWaitingComplete(op, map); QTRY_COMPARE(waitingCompleteSpy.count(), 1); QCOMPARE(waitingCompleteSpy.first()[0].toString(), op); QCOMPARE(waitingCompleteSpy.first()[1].toMap(), map); } void USSDManagerTest::testCallingLinePresentationComplete() { QString op("clpOp"); QString status("clpStatus"); QSignalSpy clpCompleteSpy(mManager, SIGNAL(callingLinePresentationComplete(QString,QString))); mMockController->TriggerUSSDCallingLinePresentationComplete(op, status); QTRY_COMPARE(clpCompleteSpy.count(), 1); QCOMPARE(clpCompleteSpy.first()[0].toString(), op); QCOMPARE(clpCompleteSpy.first()[1].toString(), status); } void USSDManagerTest::testConnectedLinePresentationComplete() { QString op("clp2Op"); QString status("clp2Status"); QSignalSpy clpCompleteSpy(mManager, SIGNAL(connectedLinePresentationComplete(QString,QString))); mMockController->TriggerUSSDConnectedLinePresentationComplete(op, status); QTRY_COMPARE(clpCompleteSpy.count(), 1); QCOMPARE(clpCompleteSpy.first()[0].toString(), op); QCOMPARE(clpCompleteSpy.first()[1].toString(), status); } void USSDManagerTest::testCallingLineRestrictionComplete() { QString op("clrOp"); QString status("clrStatus"); QSignalSpy clrCompleteSpy(mManager, SIGNAL(callingLineRestrictionComplete(QString,QString))); mMockController->TriggerUSSDCallingLineRestrictionComplete(op, status); QTRY_COMPARE(clrCompleteSpy.count(), 1); QCOMPARE(clrCompleteSpy.first()[0].toString(), op); QCOMPARE(clrCompleteSpy.first()[1].toString(), status); } void USSDManagerTest::testConnectedLineRestrictionComplete() { QString op("clr2Op"); QString status("clr2Status"); QSignalSpy clrCompleteSpy(mManager, SIGNAL(connectedLineRestrictionComplete(QString,QString))); mMockController->TriggerUSSDConnectedLineRestrictionComplete(op, status); QTRY_COMPARE(clrCompleteSpy.count(), 1); QCOMPARE(clrCompleteSpy.first()[0].toString(), op); QCOMPARE(clrCompleteSpy.first()[1].toString(), status); } void USSDManagerTest::testInitiateFailed() { QSignalSpy initiateFailedSpy(mManager, SIGNAL(initiateFailed())); mMockController->TriggerUSSDInitiateFailed(); QTRY_COMPARE(initiateFailedSpy.count(), 1); } void USSDManagerTest::testAccountReconnect() { // make sure that methods and signals are working after an account reconnects Q_EMIT mAccount->connectedChanged(); // and now try one method call QString command("reinitiatecommand"); QSignalSpy initiateSpy(mMockController, SIGNAL(USSDInitiateCalled(QString))); mManager->initiate(command); QTRY_COMPARE(initiateSpy.count(), 1); QCOMPARE(initiateSpy.first()[0].toString(), command); // and check one of the signals QString state("someCorrectState"); QSignalSpy stateChangedSpy(mManager, SIGNAL(stateChanged(QString))); mMockController->TriggerUSSDStateChanged(state); QTRY_COMPARE(stateChangedSpy.count(), 1); QCOMPARE(stateChangedSpy.first()[0].toString(), state); QCOMPARE(mManager->state(), state); } QTEST_MAIN(USSDManagerTest) #include "USSDManagerTest.moc" ./tests/libtelephonyservice/AccountEntryTest.cpp0000644000015600001650000001620712677321002022306 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "accountentry.h" #include "accountentryfactory.h" #include "mockcontroller.h" class AccountEntryTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testAccountId(); void testActive(); void testDisplayName(); void testStatus(); void testStatusMessage(); void testConnected(); void testCompareIds_data(); void testCompareIds(); void testAddressableVCardFields(); private: AccountEntry *mAccount; Tp::AccountPtr mTpAccount; AccountEntry *mNullAccount; MockController *mMockController; }; void AccountEntryTest::initTestCase() { initialize(); // create a null account mNullAccount = AccountEntryFactory::createEntry(Tp::AccountPtr(), this); } void AccountEntryTest::init() { mTpAccount = addAccount("mock", "mock", "the account"); QVERIFY(!mTpAccount.isNull()); mAccount = AccountEntryFactory::createEntry(mTpAccount, this); QVERIFY(mAccount); TRY_VERIFY(mAccount->ready()); // make sure the connection is available TRY_VERIFY(mAccount->connected()); // and make sure the status and status message are the ones we expect TRY_COMPARE(mAccount->status(), QString("available")); // and create the mock controller mMockController = new MockController("mock", this); } void AccountEntryTest::cleanup() { doCleanup(); mAccount->deleteLater(); mMockController->deleteLater(); } void AccountEntryTest::testAccountId() { QCOMPARE(mAccount->accountId(), mTpAccount->uniqueIdentifier()); QVERIFY(mNullAccount->accountId().isNull()); } void AccountEntryTest::testActive() { // the mock account is enabled/connected by default, so make sure it is like that QVERIFY(mAccount->active()); // FIXME: setting the account as offline, triggers an automatic reconnection and the // test fails. In the future we might want to re-enable this and test some other way. QSignalSpy activeChangedSpy(mAccount, SIGNAL(activeChanged())); // now set the account away and see if the active flag changes correctly mMockController->SetOnline(false); TRY_VERIFY(!mAccount->active()); TRY_VERIFY(activeChangedSpy.count() > 0); // now re-enable the account and check that the entry is updated activeChangedSpy.clear(); mMockController->SetOnline(true); TRY_VERIFY(activeChangedSpy.count() > 0); QVERIFY(mAccount->active()); // check that for a null account active is false QVERIFY(!mNullAccount->active()); } void AccountEntryTest::testDisplayName() { QSignalSpy displayNameChangedSpy(mAccount, SIGNAL(displayNameChanged())); // check that the value is correct already QCOMPARE(mAccount->displayName(), mTpAccount->displayName()); // now try to set the display in the telepathy account directly and see that the entry gets updated QString newDisplayName = "some other display name"; mTpAccount->setDisplayName(newDisplayName); TRY_COMPARE(mAccount->displayName(), newDisplayName); QCOMPARE(displayNameChangedSpy.count(), 1); // and try setting the display name in the entry itself displayNameChangedSpy.clear(); newDisplayName = "changing again"; mAccount->setDisplayName(newDisplayName); TRY_COMPARE(mAccount->displayName(), newDisplayName); QCOMPARE(displayNameChangedSpy.count(), 1); QCOMPARE(mTpAccount->displayName(), newDisplayName); // check that for a null account the displayName is null QVERIFY(mNullAccount->displayName().isNull()); } void AccountEntryTest::testStatus() { QSignalSpy statusChangedSpy(mAccount, SIGNAL(statusChanged())); // check that the value is correct already QCOMPARE(mAccount->status(), mTpAccount->connection()->selfContact()->presence().status()); // and now set a new value mMockController->SetPresence("away", "away"); TRY_COMPARE(statusChangedSpy.count(), 1); QCOMPARE(mAccount->status(), QString("away")); // check that for a null account the status is null QVERIFY(mNullAccount->status().isNull()); } void AccountEntryTest::testStatusMessage() { QSignalSpy statusMessageChangedSpy(mAccount, SIGNAL(statusMessageChanged())); // check that the value is correct already TRY_COMPARE(mAccount->statusMessage(), mTpAccount->connection()->selfContact()->presence().statusMessage()); // and now set a new value QString statusMessage("I am online"); mMockController->SetPresence("available", statusMessage); TRY_COMPARE(statusMessageChangedSpy.count(), 1); QCOMPARE(mAccount->statusMessage(), statusMessage); // check that for a null account the displayName is null QVERIFY(mNullAccount->statusMessage().isNull()); } void AccountEntryTest::testConnected() { QSignalSpy connectedChangedSpy(mAccount, SIGNAL(connectedChanged())); // the mock account is enabled/connected by default, so make sure it is like that QVERIFY(mAccount->connected()); // now set the account offline and see if the active flag changes correctly mMockController->SimulateDisconnect(); TRY_VERIFY(connectedChangedSpy.count() > 0); TRY_VERIFY(!mAccount->connected()); // now re-enable the account and check that the entry is updated connectedChangedSpy.clear(); mAccount->account()->reconnect(); // because of the way the mock was implemented, sometimes this can return two connectedChanged() signals. TRY_VERIFY(connectedChangedSpy.count() > 0); TRY_VERIFY(mAccount->connected()); // check that for a null account the displayName is null QVERIFY(!mNullAccount->connected()); } void AccountEntryTest::testCompareIds_data() { QTest::addColumn("first"); QTest::addColumn("second"); QTest::addColumn("expectedResult"); QTest::newRow("identical values") << "1234567" << "1234567" << true; QTest::newRow("case difference") << "TestId" << "testid" << false; QTest::newRow("phone prefix") << "1234567" << "1231234567" << false; } void AccountEntryTest::testCompareIds() { QFETCH(QString, first); QFETCH(QString, second); QFETCH(bool, expectedResult); QCOMPARE(mAccount->compareIds(first, second), expectedResult); } void AccountEntryTest::testAddressableVCardFields() { QVERIFY(!mAccount->addressableVCardFields().isEmpty()); QCOMPARE(mAccount->addressableVCardFields(), mTpAccount->protocolInfo().addressableVCardFields()); } QTEST_MAIN(AccountEntryTest) #include "AccountEntryTest.moc" ./tests/approver/0000755000015600001650000000000012677320771014111 5ustar jenkinsjenkins./tests/approver/ApproverTest.cpp0000644000015600001650000001457012677320771017262 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "telepathytest.h" #include "approvercontroller.h" #include "mockcontroller.h" #include "accountentry.h" #include "accountentryfactory.h" #include "telepathyhelper.h" class ApproverTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testSnapDecisionTimeout(); void testAcceptCall(); void testCarKitOutgoingCall(); void testCarKitIncomingCall(); private: void waitForCallActive(const QString &callerId); MockController *mMockController; Tp::AccountPtr mTpAccount; }; void ApproverTest::initTestCase() { initialize(); QSignalSpy setupReadySpy(TelepathyHelper::instance(), SIGNAL(setupReady())); TRY_COMPARE(setupReadySpy.count(), 1); } void ApproverTest::init() { mTpAccount = addAccount("mock", "mock", "the account"); // and create the mock controller mMockController = new MockController("mock", this); } void ApproverTest::cleanup() { doCleanup(); mMockController->deleteLater(); } void ApproverTest::testSnapDecisionTimeout() { QString callerId("12345"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); QSignalSpy notificationSpy(¬ificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); mMockController->placeCall(properties); TRY_COMPARE(notificationSpy.count(), 1); QVariantMap hints = notificationSpy.first()[6].toMap(); QVERIFY(hints.contains("x-canonical-snap-decisions-timeout")); QCOMPARE(hints["x-canonical-snap-decisions-timeout"].toInt(), -1); mMockController->HangupCall(callerId); } void ApproverTest::testAcceptCall() { QString callerId("7654321"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); QSignalSpy notificationSpy(¬ificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); QString objectPath = mMockController->placeCall(properties); TRY_COMPARE(notificationSpy.count(), 1); // at this point we are already sure the approver has the call, as the notification was placed QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString))); ApproverController::instance()->acceptCall(); TRY_COMPARE(callStateSpy.count(), 1); QCOMPARE(callStateSpy.first()[0].toString(), callerId); QCOMPARE(callStateSpy.first()[1].toString(), objectPath); QCOMPARE(callStateSpy.first()[2].toString(), QString("accepted")); mMockController->HangupCall(callerId); } void ApproverTest::testCarKitOutgoingCall() { // make sure that an outgoing call placed outside of telepathy is handle correctly QString callerId("2345678"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "outgoing"; QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString))); QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); QSignalSpy notificationSpy(¬ificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); QString objectPath = mMockController->placeCall(properties); // wait for a few seconds and check that no notification was displayed QTest::qWait(3000); QCOMPARE(notificationSpy.count(), 0); // check that the call state is not "accepted" TRY_VERIFY(callStateSpy.count() > 0); QCOMPARE(callStateSpy.last()[0].toString(), callerId); QCOMPARE(callStateSpy.last()[1].toString(), objectPath); QCOMPARE(callStateSpy.last()[2].toString(), QString("initialised")); mMockController->HangupCall(callerId); } void ApproverTest::testCarKitIncomingCall() { // make sure that an outgoing call placed outside of telepathy is handle correctly QString callerId("3456789"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QDBusInterface notificationsMock("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); QSignalSpy notificationSpy(¬ificationsMock, SIGNAL(MockNotificationReceived(QString, uint, QString, QString, QString, QStringList, QVariantMap, int))); QString objectPath = mMockController->placeCall(properties); TRY_COMPARE(notificationSpy.count(), 1); // at this point we are already sure the approver has the call, as the notification was placed QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString))); // now set the call state as active to simulate the call being answered on the car kit mMockController->SetCallState(callerId, "active"); // wait for a few seconds while the approver approves the channel and give it to the handler QTest::qWait(3000); QCOMPARE(callStateSpy.count(), 1); QCOMPARE(callStateSpy.first()[0].toString(), callerId); QCOMPARE(callStateSpy.first()[1].toString(), objectPath); // the call state needs to be active. If it is in any other state, it is because the approver wrongly called Accept() on the channel QCOMPARE(callStateSpy.first()[2].toString(), QString("active")); mMockController->HangupCall(callerId); } QTEST_MAIN(ApproverTest) #include "ApproverTest.moc" ./tests/approver/approvercontroller.h0000644000015600001650000000220512677320771020223 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 APPROVERCONTROLLER_H #define APPROVERCONTROLLER_H #include #include class ApproverController : public QObject { Q_OBJECT public: static ApproverController *instance(); public Q_SLOTS: void acceptCall(); void hangUpAndAcceptCall(); private: explicit ApproverController(QObject *parent = 0); QDBusInterface mApproverInterface; }; #endif // ApproverController_H ./tests/approver/CMakeLists.txt0000644000015600001650000000135312677320771016653 0ustar jenkinsjenkinsinclude_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../common ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_BINARY_DIR}/tests/common ${TP_QT5_INCLUDE_DIRS} ${GSETTINGS_QT_INCLUDE_DIRS} ) if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")) generate_telepathy_test(ApproverTest SOURCES ApproverTest.cpp approvercontroller.cpp TASKS --task ${CMAKE_BINARY_DIR}/approver/telephony-service-approver --task-name telephony-service-approver --wait-for com.canonical.TelephonyServiceHandler --ignore-return WAIT_FOR org.freedesktop.Telepathy.Client.TelephonyServiceApprover) endif() ./tests/approver/approvercontroller.cpp0000644000015600001650000000271712677320771020566 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 "approvercontroller.h" #include #include #define APPROVER_SERVICE "com.canonical.Approver" #define APPROVER_OBJECT "/com/canonical/Approver" #define APPROVER_INTERFACE "com.canonical.TelephonyServiceApprover" ApproverController *ApproverController::instance() { static ApproverController *self = new ApproverController(); return self; } ApproverController::ApproverController(QObject *parent) : QObject(parent), mApproverInterface(APPROVER_SERVICE, APPROVER_OBJECT, APPROVER_INTERFACE) { } void ApproverController::acceptCall() { mApproverInterface.call("AcceptCall"); } void ApproverController::hangUpAndAcceptCall() { mApproverInterface.call("HangUpAndAcceptCall"); } ./tests/handler/0000755000015600001650000000000012677321002013654 5ustar jenkinsjenkins./tests/handler/approver.cpp0000644000015600001650000001467012677320771016242 0ustar jenkinsjenkins/** * 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(bool callAcceptOnChannel) { Q_FOREACH (Tp::ChannelDispatchOperationPtr dispatchOperation, mDispatchOps) { QList channels = dispatchOperation->channels(); Q_FOREACH (Tp::ChannelPtr channel, channels) { if (callAcceptOnChannel) { Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (callChannel) { callChannel->accept(); } } if (dispatchOperation->possibleHandlers().contains(TELEPHONY_SERVICE_HANDLER)) { dispatchOperation->handleWith(TELEPHONY_SERVICE_HANDLER); mDispatchOps.removeAll(dispatchOperation); break; } } } } 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(); } ./tests/handler/approver.h0000644000015600001650000000373312677320771015705 0ustar jenkinsjenkins/** * 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(bool callAcceptOnChannel = true); 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 ./tests/handler/handlercontroller.cpp0000644000015600001650000001240012677320771020112 0ustar jenkinsjenkins/** * 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 #include #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) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); connect(&mHandlerInterface, SIGNAL(CallPropertiesChanged(QString, QVariantMap)), SIGNAL(callPropertiesChanged(QString, QVariantMap))); connect(&mHandlerInterface, SIGNAL(CallIndicatorVisibleChanged(bool)), SIGNAL(callIndicatorVisibleChanged(bool))); } QVariantMap HandlerController::getCallProperties(const QString &objectPath) { QVariantMap properties; QDBusReply reply = mHandlerInterface.call("GetCallProperties", objectPath); if (reply.isValid()) { properties = reply.value(); } return properties; } bool HandlerController::callIndicatorVisible() { QDBusInterface handlerPropertiesInterface("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "org.freedesktop.DBus.Properties"); QDBusReply reply = handlerPropertiesInterface.call("GetAll", "com.canonical.TelephonyServiceHandler"); if (!reply.isValid()) { return false; } QVariantMap map = reply.value(); return map["CallIndicatorVisible"].toBool(); } void HandlerController::startChat(const QString &accountId, const QStringList &recipients) { mHandlerInterface.call("StartChat", accountId, recipients); } 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); } bool HandlerController::hasCalls() { QDBusReply reply = mHandlerInterface.call("HasCalls"); return reply.isValid() && reply.value(); } 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); } QString HandlerController::sendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const AttachmentList &attachments, const QVariantMap &properties) { QDBusReply reply = mHandlerInterface.call("SendMessage", accountId, recipients, message, QVariant::fromValue(attachments), properties); if (reply.isValid()) { return reply.value(); } return QString(); } void HandlerController::acknowledgeMessages(const QString &number, const QStringList &messageIds, const QString &accountId) { mHandlerInterface.call("AcknowledgeMessages", number, messageIds, accountId); } void HandlerController::setCallIndicatorVisible(bool visible) { QDBusInterface handlerPropertiesInterface("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "org.freedesktop.DBus.Properties"); handlerPropertiesInterface.call("Set", "com.canonical.TelephonyServiceHandler", "CallIndicatorVisible", QVariant::fromValue(QDBusVariant(visible))); } ./tests/handler/handlercontroller.h0000644000015600001650000000473012677320771017566 0ustar jenkinsjenkins/** * 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 #include #include "dbustypes.h" class HandlerController : public QObject { Q_OBJECT public: static HandlerController *instance(); QVariantMap getCallProperties(const QString &objectPath); bool callIndicatorVisible(); public Q_SLOTS: // call methods void startChat(const QString &accountId, const QStringList &recipients); 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); bool hasCalls(); // conference call methods void createConferenceCall(const QStringList &objectPaths); void mergeCall(const QString &conferenceObjectPath, const QString &callObjectPath); void splitCall(const QString &objectPath); // messaging methods QString sendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const AttachmentList &attachments = AttachmentList(), const QVariantMap &properties = QVariantMap()); void acknowledgeMessages(const QString &number, const QStringList &messageIds, const QString &accountId); // active call indicator void setCallIndicatorVisible(bool visible); Q_SIGNALS: void callPropertiesChanged(const QString &objectPath, const QVariantMap &properties); void callIndicatorVisibleChanged(bool visible); private: explicit HandlerController(QObject *parent = 0); QDBusInterface mHandlerInterface; }; #endif // HANDLERCONTROLLER_H ./tests/handler/HandlerTest.cpp0000644000015600001650000005304012677321002016577 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "telepathytest.h" #include "chatmanager.h" #include "handlercontroller.h" #include "mockcontroller.h" #include "approver.h" #include "accountentry.h" #include "accountentryfactory.h" #include "telepathyhelper.h" class HandlerTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testMakingCalls(); void testHangUpCall(); void testCallHold(); void testCallProperties(); void testConferenceCall(); void testSendMessage(); void testSendMessageWithAttachments(); void testSendMessageOwnNumber(); void testAcknowledgeMessage(); void testAcknowledgeAllMessages(); void testActiveCallIndicator(); void testNotApprovedChannels(); void testMultimediaFallback(); private: void registerApprover(); void unregisterApprover(); void waitForCallActive(const QString &callerId); Approver *mApprover; MockController *mMockController; Tp::AccountPtr mTpAccount; MockController *mMultimediaMockController; Tp::AccountPtr mMultimediaTpAccount; MockController *mOfonoMockController; Tp::AccountPtr mOfonoTpAccount; }; void HandlerTest::initTestCase() { initialize(); QSignalSpy setupReadySpy(TelepathyHelper::instance(), SIGNAL(setupReady())); TRY_COMPARE(setupReadySpy.count(), 1); registerApprover(); } void HandlerTest::init() { mTpAccount = addAccount("mock", "mock", "the account"); // and create the mock controller mMockController = new MockController("mock", this); mOfonoTpAccount = addAccount("mock", "ofono", "the account"); mOfonoMockController = new MockController("ofono", this); mMultimediaTpAccount = addAccount("mock", "multimedia", "the account"); mMultimediaMockController = new MockController("multimedia", this); } void HandlerTest::cleanup() { doCleanup(); mMockController->deleteLater(); mMultimediaMockController->deleteLater(); mOfonoMockController->deleteLater(); } void HandlerTest::testMakingCalls() { QString callerId("1234567"); QSignalSpy callReceivedSpy(mMockController, SIGNAL(CallReceived(QString))); // FIXME: add support for multiple accounts HandlerController::instance()->startCall(callerId, mTpAccount->uniqueIdentifier()); TRY_COMPARE(callReceivedSpy.count(), 1); QCOMPARE(callReceivedSpy.first().first().toString(), callerId); mMockController->HangupCall(callerId); } void HandlerTest::testHangUpCall() { QString callerId("7654321"); QVariantMap properties; properties["Caller"] = callerId; properties["State"] = "incoming"; QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall())); QString objectPath = mMockController->placeCall(properties); QVERIFY(!objectPath.isEmpty()); // wait for the channel to hit the approver TRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); waitForCallActive(callerId); // and finally request the hangup QSignalSpy callEndedSpy(mMockController, SIGNAL(CallEnded(QString))); TRY_VERIFY(HandlerController::instance()->hasCalls()); HandlerController::instance()->hangUpCall(objectPath); TRY_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 = mMockController->placeCall(properties); QVERIFY(!objectPath.isEmpty()); // wait for the channel to hit the approver TRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); waitForCallActive(callerId); QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString))); TRY_VERIFY(HandlerController::instance()->hasCalls()); // set the call on hold HandlerController::instance()->setHold(objectPath, true); TRY_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); TRY_COMPARE(callStateSpy.count(), 1); QCOMPARE(callStateSpy.first()[2].toString(), QString("active")); mMockController->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))); mMockController->placeCall(properties); // wait for the channel to hit the approver TRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); waitForCallActive(callerId); // wait until the call properties are changed TRY_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])); } TRY_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); QTest::qWait(500); } 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 = mMockController->placeCall(properties); // wait for the channel to hit the approver TRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); approverCallSpy.clear(); waitForCallActive(callerId1); // make a second call properties["Caller"] = callerId2; QString call2 = mMockController->placeCall(properties); // wait for the channel to hit the approver TRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); approverCallSpy.clear(); waitForCallActive(callerId2); // now create the conf call QSignalSpy conferenceCreatedSpy(mMockController, SIGNAL(ConferenceCreated(QString))); HandlerController::instance()->createConferenceCall(QStringList() << call1 << call2); TRY_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 = mMockController->placeCall(properties); TRY_COMPARE(approverCallSpy.count(), 1); mApprover->acceptCall(); approverCallSpy.clear(); waitForCallActive(callerId3); // merge that call on the conference QSignalSpy channelMergedSpy(mMockController, SIGNAL(ChannelMerged(QString))); HandlerController::instance()->mergeCall(conferenceObjectPath, call3); TRY_COMPARE(channelMergedSpy.count(), 1); QCOMPARE(channelMergedSpy.first().first().toString(), call3); // now try to split one of the channels QSignalSpy channelSplittedSpy(mMockController, SIGNAL(ChannelSplitted(QString))); HandlerController::instance()->splitCall(call2); TRY_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); // just to make sure it is all done before removing the accounts QTest::qWait(500); } void HandlerTest::testSendMessage() { QString recipient("22222222"); QString message("Hello, world!"); QSignalSpy messageSentSpy(mMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); // FIXME: add support for multiple accounts HandlerController::instance()->sendMessage(mTpAccount->uniqueIdentifier(), QStringList() << recipient, message); TRY_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::testSendMessageWithAttachments() { QString recipient("22222222"); QString message("Hello, world!"); QSignalSpy messageSentSpy(mOfonoMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); QTemporaryFile outputFile("audioXXXXXX.ogg"); outputFile.open(); AttachmentStruct attachment{"id", "audio/ogg", outputFile.fileName()}; HandlerController::instance()->sendMessage(mOfonoTpAccount->uniqueIdentifier(), QStringList() << recipient, message, AttachmentList() << attachment); TRY_COMPARE(messageSentSpy.count(), 1); outputFile.close(); QString sentMessage = messageSentSpy.first()[0].toString(); QVariantMap messageProperties = messageSentSpy.first()[2].value(); QCOMPARE(sentMessage, message); QCOMPARE(messageProperties["Recipients"].value().count(), 1); QCOMPARE(messageProperties["Recipients"].value().first(), recipient); QVariantList messageAttachments = qdbus_cast(messageSentSpy.first()[1]); QVariantMap firstAttachment = qdbus_cast(messageAttachments.first()); QCOMPARE(firstAttachment["content-type"].toString(), QString("audio/ogg")); QCOMPARE(firstAttachment["identifier"].toString(), QString("id")); } void HandlerTest::testSendMessageOwnNumber() { QString recipient("84376666"); QString message("Hello, world!"); QSignalSpy messageSentSpy(mMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); // first send a message to our own number HandlerController::instance()->sendMessage(mTpAccount->uniqueIdentifier(), QStringList() << mTpAccount->connection()->selfContact()->id(), message); TRY_COMPARE(messageSentSpy.count(), 1); QVariantMap messageProperties = messageSentSpy.first()[2].value(); QCOMPARE(messageProperties["Recipients"].toStringList().first(), mTpAccount->connection()->selfContact()->id()); messageSentSpy.clear(); // then send to another number and check if old channels are not reused HandlerController::instance()->sendMessage(mTpAccount->uniqueIdentifier(), QStringList() << recipient, message); TRY_COMPARE(messageSentSpy.count(), 1); messageProperties = messageSentSpy.first()[2].value(); QCOMPARE(messageProperties["Recipients"].toStringList().first(), recipient); } void HandlerTest::testAcknowledgeMessage() { // if we register the observer before this test, other tests fail TelepathyHelper::instance()->registerChannelObserver(); QString recipient("84376666"); QString recipient2("+554184376666"); QString message("Hello, world!"); QSignalSpy messageSentSpy(mMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); // first send a message to a certain number so the handler request one channel HandlerController::instance()->sendMessage(mTpAccount->uniqueIdentifier(), QStringList() << recipient, message); TRY_COMPARE(messageSentSpy.count(), 1); QSignalSpy messageReceivedSpy(ChatManager::instance(), SIGNAL(messageReceived(QString,QString,QDateTime,QString,bool))); // now receive a message from a very similar number so CM creates another // channel and the handler needs to deal with both QVariantMap properties; properties["Sender"] = recipient2; properties["Recipients"] = (QStringList() << recipient2); mMockController->PlaceIncomingMessage(message, properties); TRY_COMPARE(messageReceivedSpy.count(), 1); QString receivedMessageId = messageReceivedSpy.first()[3].toString(); // then acknowledge the message that arrived in the second channel and make sure handler // does the right thing QSignalSpy messageReadSpy(mMockController, SIGNAL(MessageRead(QString))); QTest::qWait(1000); ChatManager::instance()->acknowledgeMessage(properties["Recipients"].toStringList(), receivedMessageId, mTpAccount->uniqueIdentifier()); TRY_COMPARE(messageReadSpy.count(), 1); QCOMPARE(messageReadSpy.first()[0].toString(), receivedMessageId); } void HandlerTest::testAcknowledgeAllMessages() { // FIXME: we assume the observer is already registered from the test above QString recipient("98437666"); QString recipient2("+554198437666"); QString message("Hello, world! %1"); int messageCount = 10; QSignalSpy messageSentSpy(mMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); // first send a message to a certain number so the handler request one channel HandlerController::instance()->sendMessage(mTpAccount->uniqueIdentifier(), QStringList() << recipient, message); TRY_COMPARE(messageSentSpy.count(), 1); QSignalSpy messageReceivedSpy(ChatManager::instance(), SIGNAL(messageReceived(QString,QString,QDateTime,QString,bool))); // now receive some messages from a very similar number so CM creates another // channel and the handler needs to deal with both QVariantMap properties; properties["Sender"] = recipient2; properties["Recipients"] = (QStringList() << recipient2); for (int i = 0; i < messageCount; ++i) { mMockController->PlaceIncomingMessage(message.arg(QString::number(i)), properties); } TRY_COMPARE(messageReceivedSpy.count(), messageCount); // then acknowledge the messages that arrived in the second channel and make sure handler // does the right thing QTest::qWait(1000); QSignalSpy messageReadSpy(mMockController, SIGNAL(MessageRead(QString))); ChatManager::instance()->acknowledgeAllMessages(properties["Recipients"].toStringList(), mTpAccount->uniqueIdentifier()); TRY_COMPARE(messageReadSpy.count(), messageCount); } void HandlerTest::testActiveCallIndicator() { // start by making sure the property is false by default QVERIFY(!HandlerController::instance()->callIndicatorVisible()); QSignalSpy spy(HandlerController::instance(), SIGNAL(callIndicatorVisibleChanged(bool))); // set the property to true HandlerController::instance()->setCallIndicatorVisible(true); TRY_COMPARE(spy.count(), 1); QVERIFY(spy.first().first().toBool()); QVERIFY(HandlerController::instance()->callIndicatorVisible()); // and back to false spy.clear(); HandlerController::instance()->setCallIndicatorVisible(false); TRY_COMPARE(spy.count(), 1); QVERIFY(!spy.first().first().toBool()); QVERIFY(!HandlerController::instance()->callIndicatorVisible()); } void HandlerTest::testNotApprovedChannels() { QVariantMap properties; QString callerId = "123456"; properties["Caller"] = callerId; properties["State"] = "incoming"; QSignalSpy approverCallSpy(mApprover, SIGNAL(newCall())); QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString))); QString objectPath = mMockController->placeCall(properties); QVERIFY(!objectPath.isEmpty()); // wait for the channel to hit the approver TRY_COMPARE(approverCallSpy.count(), 1); // accept the call but do not call callChannel->accept() on the channel mApprover->acceptCall(false); // wait for a few seconds QTest::qWait(3000); // the last state received should be initialised TRY_VERIFY(callStateSpy.count() > 0); QCOMPARE(callStateSpy.last()[0].toString(), callerId); QCOMPARE(callStateSpy.last()[1].toString(), objectPath); QCOMPARE(callStateSpy.last()[2].toString(), QString("initialised")); } void HandlerTest::testMultimediaFallback() { QString recipient("22222222"); QString message("Hello, world!"); mMultimediaMockController->SetContactPresence(recipient, Tp::ConnectionPresenceTypeAvailable, "available", ""); // We have to make sure the handler already has the new state QTest::qWait(1000); QSignalSpy messageSentOfonoSpy(mOfonoMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); QSignalSpy messageSentMultimediaSpy(mMultimediaMockController, SIGNAL(MessageSent(QString,QVariantList,QVariantMap))); QString accountId = HandlerController::instance()->sendMessage(mOfonoTpAccount->uniqueIdentifier(), QStringList() << recipient, message); QCOMPARE(accountId, mMultimediaTpAccount->uniqueIdentifier()); TRY_COMPARE(messageSentMultimediaSpy.count(), 1); QCOMPARE(messageSentOfonoSpy.count(), 0); QString sentMessage = messageSentMultimediaSpy.first().first().toString(); QVariantMap messageProperties = messageSentMultimediaSpy.first().last().value(); QCOMPARE(sentMessage, message); QCOMPARE(messageProperties["Recipients"].value().count(), 1); QCOMPARE(messageProperties["Recipients"].value().first(), recipient); messageSentMultimediaSpy.clear(); messageSentOfonoSpy.clear(); mMultimediaMockController->SetContactPresence(recipient, Tp::ConnectionPresenceTypeUnknown, "offline", ""); // We have to make sure the handler already has the new state QTest::qWait(1000); HandlerController::instance()->sendMessage(mOfonoTpAccount->uniqueIdentifier(), QStringList() << recipient, message); TRY_COMPARE(messageSentOfonoSpy.count(), 1); QCOMPARE(messageSentMultimediaSpy.count(), 0); sentMessage = messageSentOfonoSpy.first().first().toString(); messageProperties = messageSentOfonoSpy.first().last().value(); QCOMPARE(sentMessage, message); QCOMPARE(messageProperties["Recipients"].value().count(), 1); QCOMPARE(messageProperties["Recipients"].value().first(), recipient); } void HandlerTest::registerApprover() { // register the approver mApprover = new Approver(); QVERIFY(TelepathyHelper::instance()->registerClient(mApprover, "TelephonyTestApprover")); // Tp-qt does not set registered status to approvers TRY_VERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(TELEPHONY_SERVICE_APPROVER)); } void HandlerTest::unregisterApprover() { QVERIFY(TelepathyHelper::instance()->unregisterClient(mApprover)); mApprover->deleteLater(); mApprover = NULL; TRY_VERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(TELEPHONY_SERVICE_APPROVER)); } void HandlerTest::waitForCallActive(const QString &callerId) { QSignalSpy callStateSpy(mMockController, SIGNAL(CallStateChanged(QString,QString,QString))); QString state; QString objectPath; QString caller; int tries = 0; while ((state != "active" || caller != callerId) && tries < 5) { TRY_COMPARE(callStateSpy.count(), 1); caller = callStateSpy.first()[0].toString(); objectPath = callStateSpy.first()[1].toString(); state = callStateSpy.first()[2].toString(); callStateSpy.clear(); tries++; qDebug() << "Waiting for call active, try " << tries << " failed."; } QCOMPARE(caller, callerId); QCOMPARE(state, QString("active")); QVERIFY(!objectPath.isEmpty()); } QTEST_MAIN(HandlerTest) #include "HandlerTest.moc" ./tests/handler/CMakeLists.txt0000644000015600001650000000055312677320771016433 0ustar jenkinsjenkinsinclude_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../common ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_BINARY_DIR}/tests/common ${TP_QT5_INCLUDE_DIRS} ${GSETTINGS_QT_INCLUDE_DIRS} ) generate_telepathy_test(HandlerTest SOURCES HandlerTest.cpp handlercontroller.cpp approver.cpp) ./tests/common/0000755000015600001650000000000012677320772013544 5ustar jenkinsjenkins./tests/common/mockcontroller.h0000644000015600001650000000242512677320771016754 0ustar jenkinsjenkins/** * 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 "MockConnectionInterface.h" class MockController : public ComCanonicalMockConnectionInterface { Q_OBJECT public: explicit MockController(const QString &protocol, QObject *parent = 0); public Q_SLOTS: // We only reimplement the methods that need sync replies QString placeCall(const QVariantMap &properties); QString serial(); private: QString mProtocol; QString mMockObject; }; #endif // MOCKCONTROLLER_H ./tests/common/mock/0000755000015600001650000000000012677321002014460 5ustar jenkinsjenkins./tests/common/mock/connection.h0000644000015600001650000001514412677321002016775 0ustar jenkinsjenkins/** * 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" #include "emergencymodeiface.h" #include "ussdiface.h" #include "voicemailiface.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 QVariantMap& request, 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); uint setPresenceFail(const QString& status, const QString& statusMessage, Tp::DBusError *error); void setContactPresence(const QString &id, int presenceType, const QString &status = QString(), const QString &statusMessage = QString()); void connect(Tp::DBusError *error); void setOnline(bool online); void simulateAuthFailure(); void simulateDisconnect(); Tp::BaseConnectionRequestsInterfacePtr requestsIface; Tp::BaseConnectionSimplePresenceInterfacePtr simplePresenceIface; Tp::BaseConnectionContactsInterfacePtr contactsIface; uint newHandle(const QString &identifier); QMap callChannels(); // phone custom interfaces BaseConnectionEmergencyModeInterfacePtr emergencyModeIface; BaseConnectionVoicemailInterfacePtr voicemailIface; BaseConnectionUSSDInterfacePtr supplementaryServicesIface; uint ensureHandle(const QString &id); Tp::BaseChannelPtr createTextChannel(uint targetHandleType, uint targetHandle, const QVariantMap &hints, Tp::DBusError *error); Tp::BaseChannelPtr createCallChannel(uint targetHandleType, uint targetHandle, const QVariantMap &hints, Tp::DBusError *error); ~MockConnection(); QString placeCall(const QVariantMap &properties); QStringList emergencyNumbers(Tp::DBusError *error); void setEmergencyNumbers(const QStringList &emergencyNumbers); void setCountryCode(const QString &countryCode); bool voicemailIndicator(Tp::DBusError *error); void setVoicemailIndicator(bool visible); QString voicemailNumber(Tp::DBusError *error); void setVoicemailNumber(const QString &number); uint voicemailCount(Tp::DBusError *error); void setVoicemailCount(int count); void USSDInitiate(const QString &command, Tp::DBusError *error); void USSDRespond(const QString &reply, Tp::DBusError *error); void USSDCancel(Tp::DBusError *error); QString serial(); // FIXME: there is a problem in telepathy-qt that connection object paths and services are not properly unregistered // and thus if we gain the same memory address (and thus the same pointer) every time we reconnect, there might be some problems QString uniqueName() const; Q_SIGNALS: void messageRead(const QString &messageId); void messageSent(const QString &message, const QVariantList &attachments, 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); // USSD notifications void ussdInitiateCalled(const QString &command); void ussdRespondCalled(const QString &reply); void ussdCancelCalled(); 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 changeChatState(const QStringList &participants, const QString &userId, int 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); MockTextChannel *textChannelForRecipients(const QStringList &recipients); QMap mHandles; Tp::SimpleStatusSpecMap mStatuses; QList mTextChannels; QMap mCallChannels; QMap mInitialCallStatus; QStringList mModems; Tp::SimplePresence mSelfPresence; Tp::SimpleContactPresences mPresences; MockConnectionDBus *mDBus; QStringList mIncomingCalls; MockConferenceCallChannel *mConferenceCall; QStringList mEmergencyNumbers; QString mCountryCode; int mVoicemailCount; bool mVoicemailIndicator; QString mVoicemailNumber; }; #endif ./tests/common/mock/ussdiface.cpp0000644000015600001650000002477412677320771017164 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 "ussdiface.h" // Conn.I.USSD BaseConnectionUSSDInterface::Adaptee::Adaptee(BaseConnectionUSSDInterface *interface) : QObject(interface), mInterface(interface) { } struct TP_QT_NO_EXPORT BaseConnectionUSSDInterface::Private { Private(BaseConnectionUSSDInterface *parent) : adaptee(new BaseConnectionUSSDInterface::Adaptee(parent)) { } QString state; QString serial; InitiateCallback initiateCB; RespondCallback respondCB; CancelCallback cancelCB; BaseConnectionUSSDInterface::Adaptee *adaptee; }; BaseConnectionUSSDInterface::Adaptee::~Adaptee() { } void BaseConnectionUSSDInterface::Adaptee::initiate(const QString &command, const ConnectionInterfaceUSSDAdaptor::InitiateContextPtr &context) { if (!mInterface->mPriv->initiateCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; mInterface->mPriv->initiateCB(command, &error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(); } void BaseConnectionUSSDInterface::Adaptee::respond(const QString &reply, const ConnectionInterfaceUSSDAdaptor::RespondContextPtr &context) { if (!mInterface->mPriv->respondCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; mInterface->mPriv->respondCB(reply, &error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(); } void BaseConnectionUSSDInterface::Adaptee::cancel(const ConnectionInterfaceUSSDAdaptor::CancelContextPtr &context) { if (!mInterface->mPriv->cancelCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; mInterface->mPriv->cancelCB(&error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(); } BaseConnectionUSSDInterface::BaseConnectionUSSDInterface() : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_USSD), mPriv(new Private(this)) { } BaseConnectionUSSDInterface::~BaseConnectionUSSDInterface() { delete mPriv; } void BaseConnectionUSSDInterface::setInitiateCallback(const InitiateCallback &cb) { mPriv->initiateCB = cb; } void BaseConnectionUSSDInterface::setRespondCallback(const RespondCallback &cb) { mPriv->respondCB = cb; } void BaseConnectionUSSDInterface::setCancelCallback(const CancelCallback &cb) { mPriv->cancelCB = cb; } QString BaseConnectionUSSDInterface::state() const { return mPriv->state; } void BaseConnectionUSSDInterface::setSerial(const QString &serial) const { mPriv->serial = serial; } QString BaseConnectionUSSDInterface::serial() const { return mPriv->serial; } void BaseConnectionUSSDInterface::StateChanged(const QString &state) { mPriv->state = state; Q_EMIT mPriv->adaptee->stateChanged(state); } void BaseConnectionUSSDInterface::InitiateUSSDComplete(const QString &ussdResp) { Q_EMIT mPriv->adaptee->initiateUSSDComplete(ussdResp); } void BaseConnectionUSSDInterface::RespondComplete(bool success, const QString &ussdResp) { Q_EMIT mPriv->adaptee->respondComplete(success, ussdResp); } void BaseConnectionUSSDInterface::BarringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap) { Q_EMIT mPriv->adaptee->barringComplete(ssOp, cbService, cbMap); } void BaseConnectionUSSDInterface::ForwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap) { Q_EMIT mPriv->adaptee->forwardingComplete(ssOp, cfService, cfMap); } void BaseConnectionUSSDInterface::WaitingComplete(const QString &ssOp, const QVariantMap &cwMap) { Q_EMIT mPriv->adaptee->waitingComplete(ssOp, cwMap); } void BaseConnectionUSSDInterface::CallingLinePresentationComplete(const QString &ssOp, const QString &status) { Q_EMIT mPriv->adaptee->callingLinePresentationComplete(ssOp, status); } void BaseConnectionUSSDInterface::ConnectedLinePresentationComplete(const QString &ssOp, const QString &status) { Q_EMIT mPriv->adaptee->connectedLinePresentationComplete(ssOp, status); } void BaseConnectionUSSDInterface::CallingLineRestrictionComplete(const QString &ssOp, const QString &status) { Q_EMIT mPriv->adaptee->callingLineRestrictionComplete(ssOp, status); } void BaseConnectionUSSDInterface::ConnectedLineRestrictionComplete(const QString &ssOp, const QString &status) { Q_EMIT mPriv->adaptee->connectedLineRestrictionComplete(ssOp, status); } void BaseConnectionUSSDInterface::InitiateFailed() { Q_EMIT mPriv->adaptee->initiateFailed(); } void BaseConnectionUSSDInterface::NotificationReceived(const QString &message) { Q_EMIT mPriv->adaptee->notificationReceived(message); } void BaseConnectionUSSDInterface::RequestReceived(const QString &message) { Q_EMIT mPriv->adaptee->requestReceived(message); } QVariantMap BaseConnectionUSSDInterface::immutableProperties() const { QVariantMap map; return map; } void BaseConnectionUSSDInterface::createAdaptor() { (void) new ConnectionInterfaceUSSDAdaptor(dbusObject()->dbusConnection(), mPriv->adaptee, dbusObject()); } ConnectionInterfaceUSSDAdaptor::ConnectionInterfaceUSSDAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent) : Tp::AbstractAdaptor(bus, adaptee, parent) { connect(adaptee, SIGNAL(notificationReceived(const QString &)), SIGNAL(NotificationReceived(const QString &))); connect(adaptee, SIGNAL(requestReceived(const QString &)), SIGNAL(RequestReceived(const QString &))); connect(adaptee, SIGNAL(initiateUSSDComplete(const QString &)), SIGNAL(InitiateUSSDComplete(const QString &))); connect(adaptee, SIGNAL(barringComplete(const QString &, const QString &, const QVariantMap &)), SIGNAL(BarringComplete(const QString &, const QString &, const QVariantMap &))); connect(adaptee, SIGNAL(forwardingComplete(const QString &, const QString &, const QVariantMap &)), SIGNAL(ForwardingComplete(const QString &, const QString &, const QVariantMap &))); connect(adaptee, SIGNAL(waitingComplete(const QString &, const QVariantMap &)), SIGNAL(WaitingComplete(const QString &, const QVariantMap &))); connect(adaptee, SIGNAL(callingLinePresentationComplete(const QString &, const QString &)), SIGNAL(CallingLinePresentationComplete(const QString &, const QString &))); connect(adaptee, SIGNAL(connectedLinePresentationComplete(const QString &, const QString &)), SIGNAL(ConnectedLinePresentationComplete(const QString &, const QString &))); connect(adaptee, SIGNAL(callingLineRestrictionComplete(const QString &, const QString &)), SIGNAL(CallingLineRestrictionComplete(const QString &, const QString &))); connect(adaptee, SIGNAL(connectedLineRestrictionComplete(const QString &, const QString &)), SIGNAL(ConnectedLineRestrictionComplete(const QString &, const QString &))); connect(adaptee, SIGNAL(initiateFailed()), SIGNAL(InitiateFailed())); connect(adaptee, SIGNAL(stateChanged(const QString&)), SIGNAL(StateChanged(const QString&))); connect(adaptee, SIGNAL(respondComplete(bool, const QString &)), SIGNAL(RespondComplete(bool, const QString &))); } ConnectionInterfaceUSSDAdaptor::~ConnectionInterfaceUSSDAdaptor() { } void ConnectionInterfaceUSSDAdaptor::Initiate(const QString &command, const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("initiate(const QString &,ConnectionInterfaceUSSDAdaptor::InitiateContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return; } InitiateContextPtr ctx = InitiateContextPtr( new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "initiate", Q_ARG(QString, command), Q_ARG(ConnectionInterfaceUSSDAdaptor::InitiateContextPtr, ctx)); return; } void ConnectionInterfaceUSSDAdaptor::Respond(const QString &reply, const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("respond(QConnectionInterfaceUSSDAdaptor::RespondContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return; } RespondContextPtr ctx = RespondContextPtr( new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "respond", Q_ARG(QString, reply), Q_ARG(ConnectionInterfaceUSSDAdaptor::RespondContextPtr, ctx)); return; } void ConnectionInterfaceUSSDAdaptor::Cancel(const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("cancel(ConnectionInterfaceUSSDAdaptor::CancelContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return; } CancelContextPtr ctx = CancelContextPtr( new Tp::MethodInvocationContext< >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "cancel", Q_ARG(ConnectionInterfaceUSSDAdaptor::CancelContextPtr, ctx)); return; } QString ConnectionInterfaceUSSDAdaptor::Serial() const { return qvariant_cast< QString >(adaptee()->property("serial")); } QString ConnectionInterfaceUSSDAdaptor::State() const { return qvariant_cast< QString >(adaptee()->property("state")); } ./tests/common/mock/main.cpp0000644000015600001650000000344612677320771016133 0ustar jenkinsjenkins/** * 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); // create a standard protocol Tp::BaseProtocolPtr proto = Tp::BaseProtocol::create( QDBusConnection::sessionBus(), QLatin1String("mock")); // create a phone protocol Tp::BaseProtocolPtr phoneProto = Tp::BaseProtocol::create( QDBusConnection::sessionBus(), QLatin1String("ofono")); // create a multimedia protocol Tp::BaseProtocolPtr multimediaProto = Tp::BaseProtocol::create( QDBusConnection::sessionBus(), QLatin1String("multimedia")); Tp::BaseConnectionManagerPtr cm = Tp::BaseConnectionManager::create( QDBusConnection::sessionBus(), QLatin1String("mock")); cm->addProtocol(multimediaProto); cm->addProtocol(phoneProto); cm->addProtocol(proto); cm->registerObject(); return a.exec(); } ./tests/common/mock/callchannel.h0000644000015600001650000000510312677320771017110 0ustar jenkinsjenkins/** * 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 ./tests/common/mock/emergencymodeiface.h0000644000015600001650000001106312677320771020461 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 OFONOEMERGENCYMODEIFACE_H #define OFONOEMERGENCYMODEIFACE_H // telepathy-qt #include #include #include #include #include class BaseConnectionEmergencyModeInterface; typedef Tp::SharedPtr BaseConnectionEmergencyModeInterfacePtr; #define TP_QT_IFACE_CONNECTION_EMERGENCYMODE "com.canonical.Telephony.EmergencyMode" class TP_QT_EXPORT BaseConnectionEmergencyModeInterface : public Tp::AbstractConnectionInterface { Q_OBJECT Q_DISABLE_COPY(BaseConnectionEmergencyModeInterface) public: static BaseConnectionEmergencyModeInterfacePtr create() { return BaseConnectionEmergencyModeInterfacePtr(new BaseConnectionEmergencyModeInterface()); } template static Tp::SharedPtr create() { return Tp::SharedPtr( new BaseConnectionEmergencyModeInterfaceSubclass()); } QVariantMap immutableProperties() const; virtual ~BaseConnectionEmergencyModeInterface(); typedef Tp::Callback1 EmergencyNumbersCallback; void setEmergencyNumbersCallback(const EmergencyNumbersCallback &cb); void setFakeEmergencyNumber(const QString &fakeEmergencyNumber); public Q_SLOTS: void setEmergencyNumbers(const QStringList &numbers); void setCountryCode(const QString &countryCode); protected: BaseConnectionEmergencyModeInterface(); private: void createAdaptor(); class Adaptee; friend class Adaptee; struct Private; friend struct Private; Private *mPriv; }; class TP_QT_EXPORT ConnectionInterfaceEmergencyModeAdaptor : public Tp::AbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CONNECTION_EMERGENCYMODE) Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: ConnectionInterfaceEmergencyModeAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent); virtual ~ConnectionInterfaceEmergencyModeAdaptor(); typedef Tp::MethodInvocationContextPtr< QStringList > EmergencyNumbersContextPtr; typedef Tp::MethodInvocationContextPtr< QString > CountryCodeContextPtr; public Q_SLOTS: // METHODS QStringList EmergencyNumbers(const QDBusMessage& dbusMessage); QString CountryCode(const QDBusMessage& dbusMessage); Q_SIGNALS: // SIGNALS void EmergencyNumbersChanged(const QStringList &numbers); void CountryCodeChanged(const QString &countryCode); }; class TP_QT_NO_EXPORT BaseConnectionEmergencyModeInterface::Adaptee : public QObject { Q_OBJECT public: Adaptee(BaseConnectionEmergencyModeInterface *interface); ~Adaptee(); private Q_SLOTS: void emergencyNumbers(const ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr &context); void countryCode(const ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr &context); Q_SIGNALS: void emergencyNumbersChanged(const QStringList &numbers); void countryCodeChanged(const QString &countryCode); public: BaseConnectionEmergencyModeInterface *mInterface; }; #endif ./tests/common/mock/conferencecallchannel.h0000644000015600001650000000557012677320771021150 0ustar jenkinsjenkins/** * 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 ./tests/common/mock/callchannel.cpp0000644000015600001650000002071412677320771017450 0ustar jenkinsjenkins/** * 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, Tp::HandleTypeContact, targetHandle); 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("accepted"); QTimer *timer = new QTimer(this); timer->setSingleShot(true); timer->setInterval(100); connect(timer, &QTimer::timeout, [this, timer]() { setCallState("active"); timer->deleteLater(); }); timer->start(); } 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; } setCallState("initialising"); 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); setCallState("initialised"); 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() { } 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 == "accepted") { mCallChannel->setCallState(Tp::CallStateAccepted, 0, reason, stateDetails); } 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"; } else if (state == "initialising") { reason.reason = Tp::CallStateChangeReasonProgressMade; mCallChannel->setCallState(Tp::CallStateInitialising, 0, reason, stateDetails); } else if (state == "initialised") { reason.reason = Tp::CallStateChangeReasonProgressMade; mCallChannel->setCallState(Tp::CallStateInitialised, 0, reason, stateDetails); } mState = state; Q_EMIT callStateChanged(this, state); } ./tests/common/mock/emergencymodeiface.cpp0000644000015600001650000001340012677320771021011 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 "emergencymodeiface.h" BaseConnectionEmergencyModeInterface::Adaptee::Adaptee(BaseConnectionEmergencyModeInterface *interface) : QObject(interface), mInterface(interface) { } struct TP_QT_NO_EXPORT BaseConnectionEmergencyModeInterface::Private { Private(BaseConnectionEmergencyModeInterface *parent) : adaptee(new BaseConnectionEmergencyModeInterface::Adaptee(parent)) { } EmergencyNumbersCallback emergencyNumbersCB; BaseConnectionEmergencyModeInterface::Adaptee *adaptee; QString fakeEmergencyNumber; QString countryCode; }; BaseConnectionEmergencyModeInterface::Adaptee::~Adaptee() { } void BaseConnectionEmergencyModeInterface::Adaptee::emergencyNumbers(const ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr &context) { if (!mInterface->mPriv->emergencyNumbersCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; QStringList numbers = mInterface->mPriv->emergencyNumbersCB(&error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } if (mInterface->mPriv->fakeEmergencyNumber.isEmpty()) { context->setFinished(numbers); } else { context->setFinished(QStringList() << numbers << mInterface->mPriv->fakeEmergencyNumber); } } void BaseConnectionEmergencyModeInterface::Adaptee::countryCode(const ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr &context) { context->setFinished(mInterface->mPriv->countryCode); } BaseConnectionEmergencyModeInterface::BaseConnectionEmergencyModeInterface() : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_EMERGENCYMODE), mPriv(new Private(this)) { } BaseConnectionEmergencyModeInterface::~BaseConnectionEmergencyModeInterface() { delete mPriv; } void BaseConnectionEmergencyModeInterface::setEmergencyNumbersCallback(const EmergencyNumbersCallback &cb) { mPriv->emergencyNumbersCB = cb; } void BaseConnectionEmergencyModeInterface::setEmergencyNumbers(const QStringList &numbers) { QStringList finalEmergencyList(numbers); if (!mPriv->fakeEmergencyNumber.isEmpty()) { finalEmergencyList << mPriv->fakeEmergencyNumber; } Q_EMIT mPriv->adaptee->emergencyNumbersChanged(finalEmergencyList); } void BaseConnectionEmergencyModeInterface::setCountryCode(const QString &countryCode) { mPriv->countryCode = countryCode; Q_EMIT mPriv->adaptee->countryCodeChanged(mPriv->countryCode); } void BaseConnectionEmergencyModeInterface::setFakeEmergencyNumber(const QString &fakeEmergencyNumber) { mPriv->fakeEmergencyNumber = fakeEmergencyNumber; } QVariantMap BaseConnectionEmergencyModeInterface::immutableProperties() const { QVariantMap map; return map; } void BaseConnectionEmergencyModeInterface::createAdaptor() { (void) new ConnectionInterfaceEmergencyModeAdaptor(dbusObject()->dbusConnection(), mPriv->adaptee, dbusObject()); } ConnectionInterfaceEmergencyModeAdaptor::ConnectionInterfaceEmergencyModeAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent) : Tp::AbstractAdaptor(bus, adaptee, parent) { connect(adaptee, SIGNAL(emergencyNumbersChanged(QStringList)), SIGNAL(EmergencyNumbersChanged(QStringList))); connect(adaptee, SIGNAL(countryCodeChanged(QString)), SIGNAL(CountryCodeChanged(QString))); } ConnectionInterfaceEmergencyModeAdaptor::~ConnectionInterfaceEmergencyModeAdaptor() { } QStringList ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbers(const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("emergencyNumbers(ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return QStringList(); } EmergencyNumbersContextPtr ctx = EmergencyNumbersContextPtr( new Tp::MethodInvocationContext< QStringList >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "emergencyNumbers", Q_ARG(ConnectionInterfaceEmergencyModeAdaptor::EmergencyNumbersContextPtr, ctx)); return QStringList(); } QString ConnectionInterfaceEmergencyModeAdaptor::CountryCode(const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("countryCode(ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return QString(); } CountryCodeContextPtr ctx = CountryCodeContextPtr( new Tp::MethodInvocationContext< QString >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "countryCode", Q_ARG(ConnectionInterfaceEmergencyModeAdaptor::CountryCodeContextPtr, ctx)); return QString(); } ./tests/common/mock/conferencecallchannel.cpp0000644000015600001650000002365212677320771021504 0ustar jenkinsjenkins/** * 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, Tp::HandleTypeNone, 0); 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); } ./tests/common/mock/dbustypes.h0000644000015600001650000000227512677320771016675 0ustar jenkinsjenkins/** * 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 ./tests/common/mock/protocol.cpp0000644000015600001650000000375112677320771017047 0ustar jenkinsjenkins/** * 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::ProtocolParameterList parameters; Tp::ProtocolParameter parameter("modem-objpath", "s", 0); parameters << parameter; setParameters(parameters); addressingIface = Tp::BaseProtocolAddressingInterface::create(); if (name == "ofono") { addressingIface->setAddressableVCardFields(QStringList() << "tel"); } else { addressingIface->setAddressableVCardFields(QStringList() << "x-mock-im" << "x-sip"); } plugInterface(addressingIface); } Tp::BaseConnectionPtr Protocol::createConnection(const QVariantMap ¶meters, Tp::DBusError *error) { Q_UNUSED(error); return Tp::BaseConnection::create("mock", name().toLatin1(), parameters); } ./tests/common/mock/speakeriface.cpp0000644000015600001650000000770512677320771017633 0ustar jenkinsjenkins/** * 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")); } ./tests/common/mock/mockconnectiondbus.cpp0000644000015600001650000002144412677321002021060 0ustar jenkinsjenkins/* * 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(messageRead(QString)), SIGNAL(MessageRead(QString))); connect(mConnection, SIGNAL(messageSent(QString,QVariantList,QVariantMap)), SIGNAL(MessageSent(QString,QVariantList,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))); connect(mConnection, SIGNAL(ussdInitiateCalled(QString)), SIGNAL(USSDInitiateCalled(QString))); connect(mConnection, SIGNAL(ussdRespondCalled(QString)), SIGNAL(USSDRespondCalled(QString))); connect(mConnection, SIGNAL(ussdCancelCalled()), SIGNAL(USSDCancelCalled())); connect(mConnection, SIGNAL(disconnected()), SIGNAL(Disconnected())); connect(mConnection, SIGNAL(destroyed()), SIGNAL(Destroyed())); qDBusRegisterMetaType >(); mObjectPath = "/com/canonical/MockConnection/" + mConnection->protocolName(); connectToBus(); } MockConnectionDBus::~MockConnectionDBus() { QDBusConnection::sessionBus().unregisterObject(mObjectPath, QDBusConnection::UnregisterTree); } 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(mObjectPath, this); } void MockConnectionDBus::PlaceIncomingMessage(const QString &message, const QVariantMap &properties) { qDebug() << __PRETTY_FUNCTION__ << message << properties; mConnection->placeIncomingMessage(message, properties); } void MockConnectionDBus::ChangeChatState(const QStringList &participants, const QString &userId, int state) { mConnection->changeChatState(participants, userId, state); } QString MockConnectionDBus::PlaceCall(const QVariantMap &properties) { qDebug() << __PRETTY_FUNCTION__ << properties; return mConnection->placeCall(properties); } void MockConnectionDBus::HangupCall(const QString &callerId) { qDebug() << __PRETTY_FUNCTION__ << callerId; mConnection->hangupCall(callerId); } void MockConnectionDBus::SetCallState(const QString &phoneNumber, const QString &state) { qDebug() << __PRETTY_FUNCTION__ << phoneNumber << state; mConnection->setCallState(phoneNumber, state); } void MockConnectionDBus::SetOnline(bool online) { qDebug() << __PRETTY_FUNCTION__ << online; mConnection->setOnline(online); } void MockConnectionDBus::SetPresence(const QString &status, const QString &statusMessage) { qDebug() << __PRETTY_FUNCTION__ << status << statusMessage; Tp::DBusError error; mConnection->setPresence(status, statusMessage, &error); } void MockConnectionDBus::SetContactPresence(const QString &id, int presenceType, const QString &status, const QString &statusMessage) { qDebug() << __PRETTY_FUNCTION__ << id << presenceType << status << statusMessage; mConnection->setContactPresence(id, presenceType, status, statusMessage); } void MockConnectionDBus::SimulateAuthFailure() { mConnection->simulateAuthFailure(); } void MockConnectionDBus::SimulateDisconnect() { mConnection->simulateDisconnect(); } void MockConnectionDBus::SetVoicemailIndicator(bool active) { qDebug() << __PRETTY_FUNCTION__ << active; mConnection->setVoicemailIndicator(active); } void MockConnectionDBus::SetVoicemailNumber(const QString &number) { qDebug() << __PRETTY_FUNCTION__ << number; mConnection->setVoicemailNumber(number); } void MockConnectionDBus::SetVoicemailCount(int count) { qDebug() << __PRETTY_FUNCTION__ << count; mConnection->setVoicemailCount(count); } void MockConnectionDBus::SetEmergencyNumbers(const QStringList &numbers) { qDebug() << __PRETTY_FUNCTION__ << numbers; mConnection->setEmergencyNumbers(numbers); } void MockConnectionDBus::SetCountryCode(const QString &countryCode) { qDebug() << __PRETTY_FUNCTION__ << countryCode; mConnection->setCountryCode(countryCode); } QString MockConnectionDBus::Serial() { qDebug() << __PRETTY_FUNCTION__ << mConnection->serial(); return mConnection->serial(); } void MockConnectionDBus::TriggerUSSDNotificationReceived(const QString &message) { qDebug() << __PRETTY_FUNCTION__ << message; mConnection->supplementaryServicesIface->NotificationReceived(message); } void MockConnectionDBus::TriggerUSSDRequestReceived(const QString &message) { qDebug() << __PRETTY_FUNCTION__ << message; mConnection->supplementaryServicesIface->RequestReceived(message); } void MockConnectionDBus::TriggerUSSDInitiateUSSDComplete(const QString &ussdResp) { qDebug() << __PRETTY_FUNCTION__ << ussdResp; mConnection->supplementaryServicesIface->InitiateUSSDComplete(ussdResp); } void MockConnectionDBus::TriggerUSSDRespondComplete(bool success, const QString &ussdResp) { qDebug() << __PRETTY_FUNCTION__ << ussdResp; mConnection->supplementaryServicesIface->RespondComplete(success, ussdResp); } void MockConnectionDBus::TriggerUSSDBarringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap) { qDebug() << __PRETTY_FUNCTION__ << ssOp << cbService << cbMap; mConnection->supplementaryServicesIface->BarringComplete(ssOp, cbService, cbMap); } void MockConnectionDBus::TriggerUSSDForwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap) { qDebug() << __PRETTY_FUNCTION__ << ssOp << cfService << cfMap; mConnection->supplementaryServicesIface->ForwardingComplete(ssOp, cfService, cfMap); } void MockConnectionDBus::TriggerUSSDWaitingComplete(const QString &ssOp, const QVariantMap &cwMap) { qDebug() << __PRETTY_FUNCTION__ << ssOp << cwMap; mConnection->supplementaryServicesIface->WaitingComplete(ssOp, cwMap); } void MockConnectionDBus::TriggerUSSDCallingLinePresentationComplete(const QString &ssOp, const QString &status) { qDebug() << __PRETTY_FUNCTION__ << ssOp << status; mConnection->supplementaryServicesIface->CallingLinePresentationComplete(ssOp, status); } void MockConnectionDBus::TriggerUSSDConnectedLinePresentationComplete(const QString &ssOp, const QString &status) { qDebug() << __PRETTY_FUNCTION__ << ssOp << status; mConnection->supplementaryServicesIface->ConnectedLinePresentationComplete(ssOp, status); } void MockConnectionDBus::TriggerUSSDCallingLineRestrictionComplete(const QString &ssOp, const QString &status) { qDebug() << __PRETTY_FUNCTION__ << ssOp << status; mConnection->supplementaryServicesIface->CallingLineRestrictionComplete(ssOp, status); } void MockConnectionDBus::TriggerUSSDConnectedLineRestrictionComplete(const QString &ssOp, const QString &status) { qDebug() << __PRETTY_FUNCTION__ << ssOp << status; mConnection->supplementaryServicesIface->ConnectedLineRestrictionComplete(ssOp, status); } void MockConnectionDBus::TriggerUSSDInitiateFailed() { qDebug() << __PRETTY_FUNCTION__; mConnection->supplementaryServicesIface->InitiateFailed(); } void MockConnectionDBus::TriggerUSSDStateChanged(const QString &state) { qDebug() << __PRETTY_FUNCTION__ << state; mConnection->supplementaryServicesIface->StateChanged(state); } ./tests/common/mock/ussdiface.h0000644000015600001650000002226712677320771016624 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 OFONOUSSDIFACE_H #define OFONOUSSDIFACE_H // telepathy-qt #include #include #include #include #include class BaseConnectionUSSDInterface; typedef Tp::SharedPtr BaseConnectionUSSDInterfacePtr; #define TP_QT_IFACE_CONNECTION_USSD "com.canonical.Telephony.USSD" class TP_QT_EXPORT BaseConnectionUSSDInterface : public Tp::AbstractConnectionInterface { Q_OBJECT Q_DISABLE_COPY(BaseConnectionUSSDInterface) public: static BaseConnectionUSSDInterfacePtr create() { return BaseConnectionUSSDInterfacePtr(new BaseConnectionUSSDInterface()); } template static Tp::SharedPtr create() { return Tp::SharedPtr( new BaseConnectionUSSDInterfaceSubclass()); } QVariantMap immutableProperties() const; virtual ~BaseConnectionUSSDInterface(); typedef Tp::Callback2 InitiateCallback; void setInitiateCallback(const InitiateCallback &cb); typedef Tp::Callback2 RespondCallback; void setRespondCallback(const RespondCallback &cb); typedef Tp::Callback1 CancelCallback; void setCancelCallback(const CancelCallback &cb); QString state() const; QString serial() const; public Q_SLOTS: 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(); void StateChanged(const QString &state); void setSerial(const QString& serial) const; protected: BaseConnectionUSSDInterface(); private: void createAdaptor(); class Adaptee; friend class Adaptee; struct Private; friend struct Private; Private *mPriv; }; class TP_QT_EXPORT ConnectionInterfaceUSSDAdaptor : public Tp::AbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CONNECTION_USSD) Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") Q_PROPERTY(QString State READ State) Q_PROPERTY(QString Serial READ Serial) public: ConnectionInterfaceUSSDAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent); virtual ~ConnectionInterfaceUSSDAdaptor(); typedef Tp::MethodInvocationContextPtr< > InitiateContextPtr; typedef Tp::MethodInvocationContextPtr< > RespondContextPtr; typedef Tp::MethodInvocationContextPtr< > CancelContextPtr; public Q_SLOTS: // METHODS void Initiate(const QString &command, const QDBusMessage& dbusMessage); void Respond(const QString &reply, const QDBusMessage& dbusMessage); void Cancel(const QDBusMessage& dbusMessage); QString State() const; QString Serial() const; Q_SIGNALS: // SIGNALS 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(); void StateChanged(const QString &state); }; class TP_QT_NO_EXPORT BaseConnectionUSSDInterface::Adaptee : public QObject { Q_OBJECT Q_PROPERTY(QString state READ state) Q_PROPERTY(QString serial READ serial) public: Adaptee(BaseConnectionUSSDInterface *interface); ~Adaptee(); QString state() const { return mInterface->state(); } QString serial() const { return mInterface->serial(); } private Q_SLOTS: void initiate(const QString &command, const ConnectionInterfaceUSSDAdaptor::InitiateContextPtr &context); void respond(const QString &reply, const ConnectionInterfaceUSSDAdaptor::RespondContextPtr &context); void cancel(const ConnectionInterfaceUSSDAdaptor::CancelContextPtr &context); Q_SIGNALS: void notificationReceived(const QString &message); void requestReceived(const QString &message); void initiateUSSDComplete(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(); void respondComplete(bool success, const QString &response); void stateChanged(const QString &state); public: BaseConnectionUSSDInterface *mInterface; }; #endif ./tests/common/mock/mockconnectiondbus.h0000644000015600001650000000770212677321002020526 0ustar jenkinsjenkins/** * 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); ~MockConnectionDBus(); bool connectToBus(); void PlaceIncomingMessage(const QString &message, const QVariantMap &properties); void ChangeChatState(const QStringList &participants, const QString &userId, int state); QString PlaceCall(const QVariantMap &properties); void HangupCall(const QString &callerId); void SetCallState(const QString &phoneNumber, const QString &state); void SetOnline(bool online); void SetPresence(const QString &status, const QString &statusMessage); void SetContactPresence(const QString &id, int presenceType, const QString &status, const QString &statusMessage); void SimulateAuthFailure(); void SimulateDisconnect(); // voicemail stuff void SetVoicemailIndicator(bool active); void SetVoicemailNumber(const QString &number); void SetVoicemailCount(int count); // emergency numbers stuff void SetEmergencyNumbers(const QStringList &numbers); void SetCountryCode(const QString &countryCode); // USSD stuff QString Serial(); void TriggerUSSDNotificationReceived(const QString &message); void TriggerUSSDRequestReceived(const QString &message); void TriggerUSSDInitiateUSSDComplete(const QString &ussdResp); void TriggerUSSDRespondComplete(bool success, const QString &ussdResp); void TriggerUSSDBarringComplete(const QString &ssOp, const QString &cbService, const QVariantMap &cbMap); void TriggerUSSDForwardingComplete(const QString &ssOp, const QString &cfService, const QVariantMap &cfMap); void TriggerUSSDWaitingComplete(const QString &ssOp, const QVariantMap &cwMap); void TriggerUSSDCallingLinePresentationComplete(const QString &ssOp, const QString &status); void TriggerUSSDConnectedLinePresentationComplete(const QString &ssOp, const QString &status); void TriggerUSSDCallingLineRestrictionComplete(const QString &ssOp, const QString &status); void TriggerUSSDConnectedLineRestrictionComplete(const QString &ssOp, const QString &status); void TriggerUSSDInitiateFailed(); void TriggerUSSDStateChanged(const QString &state); Q_SIGNALS: // signals that will be relayed into the bus void MessageRead(const QString &messageId); void MessageSent(const QString &message, const QVariantList &attachments, 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); // USSD stuff void USSDInitiateCalled(const QString &command); void USSDRespondCalled(const QString &reply); void USSDCancelCalled(); void Disconnected(); void Destroyed(); private: MockConnectionAdaptor *mAdaptor; MockConnection *mConnection; QString mObjectPath; }; #endif // MOCKCONNECTIONDBUS_H ./tests/common/mock/MockConnection.xml0000644000015600001650000002630212677321002020116 0ustar jenkinsjenkins An interface to the fake connection manager ./tests/common/mock/connection.cpp0000644000015600001650000006612712677321002017337 0ustar jenkinsjenkins/** * 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), mConferenceCall(0), mVoicemailIndicator(false), mVoicemailCount(0) { setSelfHandle(newHandle("11112222")); 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"); text.allowedProperties.append(TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialInviteeHandles")); // 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::setPresenceFail)); simplePresenceIface->setMaximumStatusMessageLength(255); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(simplePresenceIface)); // Set Presence Tp::SimpleStatusSpec presenceOnline; presenceOnline.type = Tp::ConnectionPresenceTypeAvailable; presenceOnline.maySetOnSelf = true; presenceOnline.canHaveMessage = true; Tp::SimpleStatusSpec presenceOffline; presenceOffline.type = Tp::ConnectionPresenceTypeOffline; presenceOffline.maySetOnSelf = true; presenceOffline.canHaveMessage = true; Tp::SimpleStatusSpec presenceAway; presenceAway.type = Tp::ConnectionPresenceTypeAway; presenceAway.maySetOnSelf = true; presenceAway.canHaveMessage = true; mStatuses.insert(QLatin1String("available"), presenceOnline); mStatuses.insert(QLatin1String("offline"), presenceOffline); mStatuses.insert(QLatin1String("away"), presenceAway); mStatuses.insert(QLatin1String("simlocked"), presenceAway); mStatuses.insert(QLatin1String("flightmode"), presenceOffline); mStatuses.insert(QLatin1String("nosim"), presenceOffline); mStatuses.insert(QLatin1String("nomodem"), presenceOffline); mStatuses.insert(QLatin1String("registered"), presenceOnline); mStatuses.insert(QLatin1String("roaming"), presenceOnline); mStatuses.insert(QLatin1String("unregistered"), presenceAway); mStatuses.insert(QLatin1String("denied"), presenceAway); mStatuses.insert(QLatin1String("unknown"), presenceAway); mStatuses.insert(QLatin1String("searching"), presenceAway); simplePresenceIface->setStatuses(mStatuses); mSelfPresence.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)); // init custom emergency mode interface (not provided by telepathy emergencyModeIface = BaseConnectionEmergencyModeInterface::create(); emergencyModeIface->setEmergencyNumbersCallback(Tp::memFun(this,&MockConnection::emergencyNumbers)); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(emergencyModeIface)); mEmergencyNumbers << "123" << "456" << "789"; emergencyModeIface->setEmergencyNumbers(mEmergencyNumbers); emergencyModeIface->setCountryCode("US"); // init custom voicemail interface (not provided by telepathy) voicemailIface = BaseConnectionVoicemailInterface::create(); voicemailIface->setVoicemailCountCallback(Tp::memFun(this,&MockConnection::voicemailCount)); voicemailIface->setVoicemailIndicatorCallback(Tp::memFun(this,&MockConnection::voicemailIndicator)); voicemailIface->setVoicemailNumberCallback(Tp::memFun(this,&MockConnection::voicemailNumber)); voicemailIface->setVoicemailNumber(mVoicemailNumber); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(voicemailIface)); voicemailIface->setVoicemailCount(mVoicemailCount); voicemailIface->setVoicemailIndicator(mVoicemailIndicator); mVoicemailNumber = "*555"; supplementaryServicesIface = BaseConnectionUSSDInterface::create(); supplementaryServicesIface->setInitiateCallback(Tp::memFun(this,&MockConnection::USSDInitiate)); supplementaryServicesIface->setRespondCallback(Tp::memFun(this,&MockConnection::USSDRespond)); supplementaryServicesIface->setCancelCallback(Tp::memFun(this,&MockConnection::USSDCancel)); static int serial = 0; serial++; supplementaryServicesIface->setSerial(QString("accountserial%1").arg(QString::number(serial))); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(supplementaryServicesIface)); mDBus = new MockConnectionDBus(this); setOnline(true); } MockConnection::~MockConnection() { } 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 } MockTextChannel *MockConnection::textChannelForRecipients(const QStringList &recipients) { Q_FOREACH(MockTextChannel *channel, mTextChannels) { QStringList channelRecipients = channel->recipients(); if (channelRecipients.length() != recipients.length()) { continue; } bool ok = true; Q_FOREACH(const QString &recipient, recipients) { if (!channelRecipients.contains(recipient)) { ok = false; break; } } if (ok) { return channel; } } return 0; } uint MockConnection::setPresence(const QString& status, const QString& statusMessage, Tp::DBusError *error) { qDebug() << "setPresence" << status << statusMessage; Tp::SimpleContactPresences presences; if (!mStatuses.contains(status) || !mStatuses[status].maySetOnSelf) { error->set(TP_QT_ERROR_INVALID_ARGUMENT, "Status not supported or cannot be set"); return selfHandle(); } Tp::SimpleStatusSpec spec = mStatuses[status]; mSelfPresence.status = status; mSelfPresence.type = spec.type; mSelfPresence.statusMessage = spec.canHaveMessage ? statusMessage : ""; presences[selfHandle()] = mSelfPresence; simplePresenceIface->setPresences(presences); return selfHandle(); } uint MockConnection::setPresenceFail(const QString &status, const QString &statusMessage, Tp::DBusError *error) { error->set(TP_QT_ERROR_NOT_AVAILABLE, "Can't change online status: Operation not supported"); 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)) { if (handle == selfHandle()) { attributes[TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE+"/presence"] = QVariant::fromValue(mSelfPresence); } else if (mPresences.contains(handle)) { attributes[TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE+"/presence"] = QVariant::fromValue(mPresences[handle]); } } 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); } void MockConnection::simulateDisconnect() { setStatus(Tp::ConnectionStatusDisconnected, Tp::ConnectionStatusReasonRequested); } void MockConnection::simulateAuthFailure() { setStatus(Tp::ConnectionStatusDisconnected, Tp::ConnectionStatusReasonAuthenticationFailed); } uint MockConnection::newHandle(const QString &identifier) { static int handleCount = 0; mHandles[++handleCount] = identifier; return handleCount; } 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, const QVariantMap &hints, Tp::DBusError *error) { Q_UNUSED(targetHandleType); Q_UNUSED(error); if (hints.contains(TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialInviteeHandles")) && targetHandleType == Tp::HandleTypeNone && targetHandle == 0) { } QStringList recipients; bool flash; if (hints.contains(TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialInviteeHandles"))) { recipients << inspectHandles(Tp::HandleTypeContact, qdbus_cast(hints[TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialInviteeHandles")]), error); } else { recipients << mHandles.value(targetHandle); } if (hints.contains(TP_QT_IFACE_CHANNEL_INTERFACE_SMS + QLatin1String(".Flash"))) { flash = hints[TP_QT_IFACE_CHANNEL_INTERFACE_SMS + QLatin1String(".Flash")].toBool(); } // FIXME: test flash messages MockTextChannel *channel = new MockTextChannel(this, recipients, targetHandle); QObject::connect(channel, SIGNAL(messageRead(QString)), SLOT(onMessageRead(QString))); QObject::connect(channel, SIGNAL(destroyed()), SLOT(onTextChannelClosed())); QObject::connect(channel, SIGNAL(messageSent(QString,QVariantList,QVariantMap)), SIGNAL(messageSent(QString,QVariantList,QVariantMap))); qDebug() << channel; mTextChannels << channel; return channel->baseChannel(); } void MockConnection::onMessageRead(const QString &id) { // FIXME: check what else to do Q_EMIT messageRead(id); } 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 QVariantMap &request, Tp::DBusError *error) { const QString channelType = request.value(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType")).toString(); uint targetHandleType = request.value(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType")).toUInt(); uint targetHandle = request.value(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle")).toUInt(); 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, request, error); } else if (channelType == TP_QT_IFACE_CHANNEL_TYPE_CALL) { return createCallChannel(targetHandleType, targetHandle, request, 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) { QString sender = info["Sender"].toString(); QStringList recipients = info["Recipients"].toStringList(); MockTextChannel *channel = textChannelForRecipients(recipients); if (!channel) { // request the channel Tp::DBusError error; QVariantMap request; bool yours; uint handle = ensureHandle(sender); request[TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType")] = TP_QT_IFACE_CHANNEL_TYPE_TEXT; request[TP_QT_IFACE_CHANNEL + QLatin1String(".InitiatorHandle")] = handle; request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType")] = Tp::HandleTypeContact; request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle")] = handle; ensureChannel(request, yours, false, &error); if(error.isValid()) { qWarning() << "Error creating channel for incoming message" << error.name() << error.message(); return; } channel = textChannelForRecipients(recipients); if (!channel) { return; } } channel->messageReceived(message, info); } void MockConnection::onTextChannelClosed() { MockTextChannel *channel = static_cast(sender()); if (channel) { qDebug() << "text channel closed for recipients " << channel->recipients(); mTextChannels.removeAll(channel); } } 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(); } QStringList MockConnection::emergencyNumbers(Tp::DBusError *error) { return mEmergencyNumbers; } void MockConnection::setEmergencyNumbers(const QStringList &emergencyNumbers) { mEmergencyNumbers = emergencyNumbers; emergencyModeIface->setEmergencyNumbers(emergencyNumbers); } void MockConnection::setCountryCode(const QString &countryCode) { mCountryCode = countryCode; emergencyModeIface->setCountryCode(countryCode); } bool MockConnection::voicemailIndicator(Tp::DBusError *error) { return mVoicemailIndicator; } void MockConnection::setVoicemailIndicator(bool visible) { mVoicemailIndicator = visible; voicemailIface->setVoicemailIndicator(visible); } QString MockConnection::voicemailNumber(Tp::DBusError *error) { return mVoicemailNumber; } void MockConnection::setVoicemailNumber(const QString &number) { mVoicemailNumber = number; voicemailIface->setVoicemailNumber(mVoicemailNumber); } uint MockConnection::voicemailCount(Tp::DBusError *error) { return mVoicemailCount; } void MockConnection::setVoicemailCount(int count) { mVoicemailCount = count; voicemailIface->setVoicemailCount(mVoicemailCount); } void MockConnection::USSDInitiate(const QString &command, Tp::DBusError *error) { // just emit a signal saying we received the command Q_EMIT ussdInitiateCalled(command); } void MockConnection::USSDRespond(const QString &reply, Tp::DBusError *error) { // just emit a signal saying we received the reply Q_EMIT ussdRespondCalled(reply); } void MockConnection::USSDCancel(Tp::DBusError *error) { // just emit a signal saying the operation was cancelled Q_EMIT ussdCancelCalled(); } QString MockConnection::serial() { return supplementaryServicesIface->serial(); } QString MockConnection::uniqueName() const { static int count = 0; return QString("connection%1%2").arg((quintptr) this, 0, 16).arg(count++, 0, 16); } 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); } void MockConnection::changeChatState(const QStringList &participants, const QString &userId, int state) { MockTextChannel *channel = textChannelForRecipients(participants); if (!channel) { return; } channel->changeChatState(userId, state); } void MockConnection::setContactPresence(const QString &id, int presenceType, const QString &status, const QString &statusMessage) { Tp::SimpleContactPresences presences; Tp::SimplePresence presence; presence.status = status; presence.statusMessage = statusMessage; presence.type = (Tp::ConnectionPresenceType)presenceType; uint handle = ensureHandle(id); presences[handle] = presence; mPresences[handle] = presence; simplePresenceIface->setPresences(presences); } ./tests/common/mock/speakeriface.h0000644000015600001650000000754712677320771017304 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 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 ./tests/common/mock/textchannel.h0000644000015600001650000000506512677320771017170 0ustar jenkinsjenkins/** * 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, QStringList recipients, 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); void addMembers(QStringList recipients); QStringList recipients() const; Tp::UIntList members(); void onAddMembers(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error); void onRemoveMembers(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error); public Q_SLOTS: void placeDeliveryReport(const QString &messageId, const QString &status); void changeChatState(const QString &userId, int state); Q_SIGNALS: void messageRead(const QString &id); void messageSent(const QString &message, const QVariantList &attachments, const QVariantMap &info); private: ~MockTextChannel(); Tp::BaseChannelPtr mBaseChannel; QStringList mRecipients; MockConnection *mConnection; uint mTargetHandle; Tp::BaseChannelMessagesInterfacePtr mMessagesIface; Tp::BaseChannelGroupInterfacePtr mGroupIface; Tp::BaseChannelChatStateInterfacePtr mChatStateIface; Tp::BaseChannelTextTypePtr mTextChannel; uint mMessageCounter; Tp::UIntList mMembers; }; #endif // MOCKTEXTCHANNEL_H ./tests/common/mock/protocol.h0000644000015600001650000000225512677320771016512 0ustar jenkinsjenkins/** * 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); Tp::BaseProtocolAddressingInterfacePtr addressingIface; private: Tp::BaseConnectionPtr createConnection(const QVariantMap ¶meters, Tp::DBusError *error); }; #endif ./tests/common/mock/CMakeLists.txt0000644000015600001650000000150712677320771017237 0ustar jenkinsjenkinsinclude_directories( ${TP_QT5_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libtelephonyservice ) 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 emergencymodeiface.cpp ussdiface.cpp voicemailiface.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}) ./tests/common/mock/voicemailiface.h0000644000015600001650000001241212677320771017605 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 OFONOVOICEMAILIFACE_H #define OFONOVOICEMAILIFACE_H // telepathy-qt #include #include #include #include #include class BaseConnectionVoicemailInterface; typedef Tp::SharedPtr BaseConnectionVoicemailInterfacePtr; #define TP_QT_IFACE_CONNECTION_VOICEMAIL "com.canonical.Telephony.Voicemail" class TP_QT_EXPORT BaseConnectionVoicemailInterface : public Tp::AbstractConnectionInterface { Q_OBJECT Q_DISABLE_COPY(BaseConnectionVoicemailInterface) public: static BaseConnectionVoicemailInterfacePtr create() { return BaseConnectionVoicemailInterfacePtr(new BaseConnectionVoicemailInterface()); } template static Tp::SharedPtr create() { return Tp::SharedPtr( new BaseConnectionVoicemailInterfaceSubclass()); } QVariantMap immutableProperties() const; virtual ~BaseConnectionVoicemailInterface(); typedef Tp::Callback1 VoicemailCountCallback; void setVoicemailCountCallback(const VoicemailCountCallback &cb); typedef Tp::Callback1 VoicemailIndicatorCallback; void setVoicemailIndicatorCallback(const VoicemailIndicatorCallback &cb); typedef Tp::Callback1 VoicemailNumberCallback; void setVoicemailNumberCallback(const VoicemailNumberCallback &cb); public Q_SLOTS: void setVoicemailCount(int count); void setVoicemailIndicator(bool active); void setVoicemailNumber(const QString &voicemailNumber); protected: BaseConnectionVoicemailInterface(); private: void createAdaptor(); class Adaptee; friend class Adaptee; struct Private; friend struct Private; Private *mPriv; }; class TP_QT_EXPORT ConnectionInterfaceVoicemailAdaptor : public Tp::AbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", TP_QT_IFACE_CONNECTION_VOICEMAIL) Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: ConnectionInterfaceVoicemailAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent); virtual ~ConnectionInterfaceVoicemailAdaptor(); typedef Tp::MethodInvocationContextPtr< bool > VoicemailIndicatorContextPtr; typedef Tp::MethodInvocationContextPtr< QString > VoicemailNumberContextPtr; typedef Tp::MethodInvocationContextPtr< uint > VoicemailCountContextPtr; public Q_SLOTS: // METHODS bool VoicemailIndicator(const QDBusMessage& dbusMessage); QString VoicemailNumber(const QDBusMessage& dbusMessage); uint VoicemailCount(const QDBusMessage& dbusMessage); Q_SIGNALS: // SIGNALS void VoicemailCountChanged(uint count); void VoicemailIndicatorChanged(bool active); void VoicemailNumberChanged(const QString &voicemailNumber); }; class TP_QT_NO_EXPORT BaseConnectionVoicemailInterface::Adaptee : public QObject { Q_OBJECT public: Adaptee(BaseConnectionVoicemailInterface *interface); ~Adaptee(); private Q_SLOTS: void voicemailIndicator(const ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr &context); void voicemailNumber(const ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr &context); void voicemailCount(const ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr &context); Q_SIGNALS: void voicemailCountChanged(uint count); void voicemailIndicatorChanged(bool active); void voicemailNumberChanged(const QString &voicemailNumber); public: BaseConnectionVoicemailInterface *mInterface; }; #endif ./tests/common/mock/voicemailiface.cpp0000644000015600001650000001640212677320771020143 0ustar jenkinsjenkins/** * Copyright (C) 2013-2015 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 "voicemailiface.h" // Conn.I.Voicemail BaseConnectionVoicemailInterface::Adaptee::Adaptee(BaseConnectionVoicemailInterface *interface) : QObject(interface), mInterface(interface) { } struct TP_QT_NO_EXPORT BaseConnectionVoicemailInterface::Private { Private(BaseConnectionVoicemailInterface *parent) : adaptee(new BaseConnectionVoicemailInterface::Adaptee(parent)) { } VoicemailCountCallback voicemailCountCB; VoicemailNumberCallback voicemailNumberCB; VoicemailIndicatorCallback voicemailIndicatorCB; BaseConnectionVoicemailInterface::Adaptee *adaptee; }; BaseConnectionVoicemailInterface::Adaptee::~Adaptee() { } void BaseConnectionVoicemailInterface::Adaptee::voicemailIndicator(const ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr &context) { if (!mInterface->mPriv->voicemailIndicatorCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; bool active = mInterface->mPriv->voicemailIndicatorCB(&error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(active); } void BaseConnectionVoicemailInterface::Adaptee::voicemailNumber(const ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr &context) { if (!mInterface->mPriv->voicemailNumberCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; QString number = mInterface->mPriv->voicemailNumberCB(&error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(number); } void BaseConnectionVoicemailInterface::Adaptee::voicemailCount(const ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr &context) { if (!mInterface->mPriv->voicemailCountCB.isValid()) { context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")); return; } Tp::DBusError error; uint count = mInterface->mPriv->voicemailCountCB(&error); if (error.isValid()) { context->setFinishedWithError(error.name(), error.message()); return; } context->setFinished(count); } BaseConnectionVoicemailInterface::BaseConnectionVoicemailInterface() : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_VOICEMAIL), mPriv(new Private(this)) { } BaseConnectionVoicemailInterface::~BaseConnectionVoicemailInterface() { delete mPriv; } void BaseConnectionVoicemailInterface::setVoicemailIndicatorCallback(const VoicemailIndicatorCallback &cb) { mPriv->voicemailIndicatorCB = cb; } void BaseConnectionVoicemailInterface::setVoicemailNumberCallback(const VoicemailNumberCallback &cb) { mPriv->voicemailNumberCB = cb; } void BaseConnectionVoicemailInterface::setVoicemailCountCallback(const VoicemailCountCallback &cb) { mPriv->voicemailCountCB = cb; } void BaseConnectionVoicemailInterface::setVoicemailCount(int count) { Q_EMIT mPriv->adaptee->voicemailCountChanged(uint(count)); } void BaseConnectionVoicemailInterface::setVoicemailNumber(const QString &voicemailNumber) { Q_EMIT mPriv->adaptee->voicemailNumberChanged(voicemailNumber); } void BaseConnectionVoicemailInterface::setVoicemailIndicator(bool active) { Q_EMIT mPriv->adaptee->voicemailIndicatorChanged(active); } QVariantMap BaseConnectionVoicemailInterface::immutableProperties() const { QVariantMap map; return map; } void BaseConnectionVoicemailInterface::createAdaptor() { (void) new ConnectionInterfaceVoicemailAdaptor(dbusObject()->dbusConnection(), mPriv->adaptee, dbusObject()); } ConnectionInterfaceVoicemailAdaptor::ConnectionInterfaceVoicemailAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent) : Tp::AbstractAdaptor(bus, adaptee, parent) { connect(adaptee, SIGNAL(voicemailCountChanged(uint)), SIGNAL(VoicemailCountChanged(uint))); connect(adaptee, SIGNAL(voicemailIndicatorChanged(bool)), SIGNAL(VoicemailIndicatorChanged(bool))); connect(adaptee, SIGNAL(voicemailNumberChanged(QString)), SIGNAL(VoicemailNumberChanged(QString))); } ConnectionInterfaceVoicemailAdaptor::~ConnectionInterfaceVoicemailAdaptor() { } bool ConnectionInterfaceVoicemailAdaptor::VoicemailIndicator(const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("voicemailIndicator(ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return bool(); } VoicemailIndicatorContextPtr ctx = VoicemailIndicatorContextPtr( new Tp::MethodInvocationContext< bool >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "voicemailIndicator", Q_ARG(ConnectionInterfaceVoicemailAdaptor::VoicemailIndicatorContextPtr, ctx)); return bool(); } QString ConnectionInterfaceVoicemailAdaptor::VoicemailNumber(const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("voicemailNumber(ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return QString(); } VoicemailNumberContextPtr ctx = VoicemailNumberContextPtr( new Tp::MethodInvocationContext< QString >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "voicemailNumber", Q_ARG(ConnectionInterfaceVoicemailAdaptor::VoicemailNumberContextPtr, ctx)); return QString(); } uint ConnectionInterfaceVoicemailAdaptor::VoicemailCount(const QDBusMessage& dbusMessage) { if (!adaptee()->metaObject()->indexOfMethod("voicemailCount(ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); return uint(); } VoicemailCountContextPtr ctx = VoicemailCountContextPtr( new Tp::MethodInvocationContext< uint >(dbusConnection(), dbusMessage)); QMetaObject::invokeMethod(adaptee(), "voicemailCount", Q_ARG(ConnectionInterfaceVoicemailAdaptor::VoicemailCountContextPtr, ctx)); return uint(); } ./tests/common/mock/textchannel.cpp0000644000015600001650000002626712677320771017532 0ustar jenkinsjenkins/** * 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, QStringList recipients, uint targetHandle, QObject *parent): QObject(parent), mConnection(conn), mRecipients(recipients), mTargetHandle(targetHandle), mMessageCounter(1) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); Tp::HandleType type = recipients.count() > 1 ? Tp::HandleTypeNone : Tp::HandleTypeContact; Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_TEXT, type, targetHandle); mBaseChannel = baseChannel; 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)); mChatStateIface = Tp::BaseChannelChatStateInterface::create(); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mChatStateIface)); // group stuff mGroupIface = Tp::BaseChannelGroupInterface::create(Tp::ChannelGroupFlagCanAdd, conn->selfHandle()); mGroupIface->setAddMembersCallback(Tp::memFun(this,&MockTextChannel::onAddMembers)); mGroupIface->setRemoveMembersCallback(Tp::memFun(this,&MockTextChannel::onRemoveMembers)); baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mGroupIface)); addMembers(recipients); 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); 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; QVariantMap properties; QMap::const_iterator it = header.constBegin(); while (it != header.constEnd()) { properties[it.key()] = it.value().variant().toString(); it++; } properties["SentTime"] = QDateTime::currentDateTime().toString(Qt::ISODate); properties["Recipients"] = mRecipients; properties["Id"] = id; QVariantList attachments; Tp::MessagePartList messageList = message; messageList.pop_front(); Q_FOREACH(const Tp::MessagePart& messagePart, messageList) { QVariantMap attachment; if (messagePart.contains("content-type") && messagePart["content-type"].variant().toString().startsWith("text/")) { messageText = messagePart["content"].variant().toString(); continue; } QMap::const_iterator it = messagePart.constBegin(); while (it != messagePart.constEnd()) { attachment[it.key()] = it.value().variant().toString(); it++; } attachments << attachment; } Q_EMIT messageSent(messageText, attachments, properties); QTimer *deliveryReportTimer = new QTimer(this); deliveryReportTimer->setSingleShot(true); deliveryReportTimer->setInterval(100); connect(deliveryReportTimer, &QTimer::timeout, [id, deliveryReportTimer, this] { this->placeDeliveryReport(id, "sent"); deliveryReportTimer->deleteLater(); }); deliveryReportTimer->start(); 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); // FIXME: fix it header["message-sender-id"] = QDBusVariant(mRecipients.first()); 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(mRecipients.first()); 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); } void MockTextChannel::addMembers(QStringList recipients) { Tp::UIntList handles; Q_FOREACH(const QString &recipient, recipients) { uint handle = mConnection->ensureHandle(recipient); handles << handle; if (!mRecipients.contains(recipient)) { mRecipients << recipient; } if (!mMembers.contains(handle)) { mMembers << handle; } } mGroupIface->addMembers(handles, recipients); } QStringList MockTextChannel::recipients() const { return mRecipients; } Tp::UIntList MockTextChannel::members() { return mMembers; } void MockTextChannel::onAddMembers(const Tp::UIntList &handles, const QString &message, Tp::DBusError *error) { addMembers(mConnection->inspectHandles(Tp::HandleTypeContact, handles, error)); } void MockTextChannel::onRemoveMembers(const Tp::UIntList &handles, const QString &message, Tp::DBusError *error) { Q_FOREACH(uint handle, handles) { Q_FOREACH(const QString &recipient, mConnection->inspectHandles(Tp::HandleTypeContact, Tp::UIntList() << handle, error)) { mRecipients.removeAll(recipient); } mMembers.removeAll(handle); } mGroupIface->removeMembers(handles); } void MockTextChannel::changeChatState(const QString &userId, int state) { Q_EMIT mChatStateIface->chatStateChanged(mConnection->ensureHandle(userId), state); } ./tests/common/mockcontroller.cpp0000644000015600001650000000323412677320771017306 0ustar jenkinsjenkins/** * 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 static const QString mockService("com.canonical.MockConnection"); static const QString mockObject("/com/canonical/MockConnection/%1"); MockController::MockController(const QString &protocol, QObject *parent) : ComCanonicalMockConnectionInterface(mockService, mockObject.arg(protocol), QDBusConnection::sessionBus(), parent), mProtocol(protocol), mMockObject(mockObject.arg(protocol)) { } QString MockController::placeCall(const QVariantMap &properties) { QDBusPendingReply reply = PlaceCall(properties); reply.waitForFinished(); if (!reply.isValid()) { return QString::null; } return reply.value(); } QString MockController::serial() { QDBusPendingReply reply = Serial(); reply.waitForFinished(); if (!reply.isValid()) { return QString::null; } return reply.value(); } ./tests/common/protocols/0000755000015600001650000000000012677320772015570 5ustar jenkinsjenkins./tests/common/protocols/multimedia.protocol0000644000015600001650000000010012677320771021473 0ustar jenkinsjenkins[Protocol] Name=multimedia Features=text FallbackProtocol=ofono ./tests/common/protocols/mock.protocol0000644000015600001650000000007312677320771020303 0ustar jenkinsjenkins[Protocol] Name=mock Features=text,voice FallbackProtocol= ./tests/common/protocols/ofono.protocol0000644000015600001650000000007412677320771020473 0ustar jenkinsjenkins[Protocol] Name=ofono Features=text,voice FallbackProtocol= ./tests/common/NotificationsMock.cpp0000644000015600001650000000611012677320771017670 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 #define NOTIFICATIONS_DBUS_SERVICE_NAME "org.freedesktop.Notifications" #define NOTIFICATIONS_DBUS_OBJ_PATH "/org/freedesktop/Notifications" class NotificationsMock : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", NOTIFICATIONS_DBUS_SERVICE_NAME) public: Q_SCRIPTABLE uint Notify(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout); Q_SCRIPTABLE void CloseNotification(uint id); Q_SCRIPTABLE QString GetServerInformation(QString& vendor, QString& version, QString& spec_version); // Mock specific method Q_SCRIPTABLE void MockInvokeAction(uint id, QString action_key); Q_SIGNALS: Q_SCRIPTABLE void NotificationClosed(uint id, uint reason); Q_SCRIPTABLE void ActionInvoked(uint id, QString action_key); // Mock specific signal Q_SCRIPTABLE void MockNotificationReceived(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout); }; uint NotificationsMock::Notify(QString app_name, uint replaces_id, QString app_icon, QString summary, QString body, QStringList actions, QVariantMap hints, int expire_timeout) { Q_EMIT MockNotificationReceived(app_name, replaces_id, app_icon, summary, body, actions, hints, expire_timeout); static uint id = 1; return (replaces_id != 0 ? replaces_id : id++); } void NotificationsMock::MockInvokeAction(uint id, QString action_key) { Q_EMIT ActionInvoked(id, action_key); Q_EMIT NotificationClosed(id, 2); // 2 is dismissed by user } void NotificationsMock::CloseNotification(uint id) { Q_EMIT NotificationClosed(id, 3); // 3 is closed by a CloseNotification() call } QString NotificationsMock::GetServerInformation(QString &vendor, QString &version, QString &spec_version) { return QString(); } int main(int argc, char **argv) { QCoreApplication a(argc, argv); QDBusConnection connection = QDBusConnection::sessionBus(); NotificationsMock notifications; connection.registerObject(NOTIFICATIONS_DBUS_OBJ_PATH, ¬ifications, QDBusConnection::ExportScriptableContents); connection.registerService(NOTIFICATIONS_DBUS_SERVICE_NAME); return a.exec(); } #include "NotificationsMock.moc" ./tests/common/telepathytest.cpp0000644000015600001650000001101512677320771017144 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "telepathyhelper.h" #include "accountentry.h" TelepathyTest::TelepathyTest() : mPhoneSettings("com.ubuntu.phone") { } void TelepathyTest::initialize() { Tp::registerTypes(); // create an account manager instance to help testing Tp::Features accountFeatures; accountFeatures << Tp::Account::FeatureCore << Tp::Account::FeatureProtocolInfo; Tp::Features contactFeatures; contactFeatures << Tp::Contact::FeatureAlias << Tp::Contact::FeatureAvatarData << Tp::Contact::FeatureAvatarToken << Tp::Contact::FeatureCapabilities << Tp::Contact::FeatureSimplePresence; Tp::Features connectionFeatures; connectionFeatures << 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(), accountFeatures), Tp::ConnectionFactory::create(QDBusConnection::sessionBus(), connectionFeatures), channelFactory, Tp::ContactFactory::create(contactFeatures)); mReady = false; connect(mAccountManager->becomeReady(Tp::AccountManager::FeatureCore), &Tp::PendingOperation::finished, [=]{ Q_FOREACH(const Tp::AccountPtr &account, mAccountManager->allAccounts()) { Tp::PendingOperation *op = account->remove(); WAIT_FOR(op->isFinished()); } mReady = true; }); TRY_VERIFY(mReady); } void TelepathyTest::doCleanup() { // remove all accounts on every test to prevent garbage to go from one test to another Q_FOREACH(const Tp::AccountPtr &account, mAccounts) { QVERIFY(removeAccount(account)); } QVERIFY(mAccounts.isEmpty()); } Tp::AccountPtr TelepathyTest::addAccount(const QString &manager, const QString &protocol, const QString &displayName, const QVariantMap ¶meters) { bool finished = false; Tp::AccountPtr account; connect(mAccountManager->createAccount(manager, protocol, displayName, parameters), &Tp::PendingOperation::finished, [&](Tp::PendingOperation *op) { Tp::PendingAccount *pa = qobject_cast(op); if (op->isError() || !pa) { qCritical() << "Failed to create account:" << op->errorName() << op->errorMessage(); finished = true; return; } account = pa->account(); // on the real device this is done by the telepathy-ofono plugin account->setEnabled(true); account->setConnectsAutomatically(true); finished = true; }); WAIT_FOR(finished); WAIT_FOR(!account->connection().isNull()); WAIT_FOR(account->connectionStatus() == Tp::ConnectionStatusConnected); WAIT_FOR(account->connection()->selfContact()->presence().type() == Tp::ConnectionPresenceTypeAvailable); mAccounts << account; return account; } bool TelepathyTest::removeAccount(const Tp::AccountPtr &account) { bool success = false; bool finished = false; connect(account->remove(), &Tp::PendingOperation::finished, [&](Tp::PendingOperation *op) { success = !op->isError(); finished = true; }); WAIT_FOR(finished); if (success) { mAccounts.removeAll(account); } return success; } QList TelepathyTest::accounts() const { return mAccounts; } void TelepathyTest::cleanup() { doCleanup(); } ./tests/common/dbus-session.conf.in0000644000015600001650000000321612677320771017437 0ustar jenkinsjenkins session unix:tmpdir=/tmp @CMAKE_CURRENT_BINARY_DIR@/dbus-services 60000 1000000000 1000000000 1000000000 120000 240000 100000 10000 100000 10000 50000 50000 50000 300000 ./tests/common/telepathytest.h0000644000015600001650000000361012677320771016613 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 . */ #ifndef TELEPATHYTEST_H #define TELEPATHYTEST_H #include #include #include #include #include #define DEFAULT_TIMEOUT 15000 #define TRY_VERIFY(x) QTRY_VERIFY_WITH_TIMEOUT((x), DEFAULT_TIMEOUT) #define TRY_COMPARE(x, y) QTRY_COMPARE_WITH_TIMEOUT((x), (y), DEFAULT_TIMEOUT) #define WAIT_FOR(x) while (!(x)) { qDebug() << "Waiting for:" << #x ; QTest::qWait(100); } class TelepathyTest : public QObject { Q_OBJECT public: TelepathyTest(); protected: void initialize(); void doCleanup(); // helper slots void onAccountManagerReady(Tp::PendingOperation *op); Tp::AccountPtr addAccount(const QString &manager, const QString &protocol, const QString &displayName, const QVariantMap ¶meters = QVariantMap()); bool removeAccount(const Tp::AccountPtr &account); QList accounts() const; private Q_SLOTS: void cleanup(); protected: QGSettings mPhoneSettings; private: Tp::AccountManagerPtr mAccountManager; bool mReady; QList mAccounts; }; #endif //TELEPATHYTEST_H ./tests/common/CMakeLists.txt0000644000015600001650000000156012677320771016305 0ustar jenkinsjenkinsinclude_directories(${TP_QT5_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_CURRENT_BINARY_DIR} ${GSETTINGS_QT_INCLUDE_DIRS}) configure_file(dbus-session.conf.in ${CMAKE_CURRENT_BINARY_DIR}/dbus-session.conf) add_executable(NotificationsMock NotificationsMock.cpp) qt5_use_modules(NotificationsMock Core DBus) qt5_add_dbus_interface(mockcontroller_SRCS mock/MockConnection.xml MockConnectionInterface) add_library(mockcontroller STATIC mockcontroller.cpp mockcontroller.h ${mockcontroller_SRCS}) qt5_use_modules(mockcontroller Core DBus) add_library(telepathytest STATIC telepathytest.cpp telepathytest.h) qt5_use_modules(telepathytest Core DBus) target_link_libraries(telepathytest telephonyservice ${TP_QT5_LIBRARIES} ${GSETTINGS_QT_LDFLAGS}) add_subdirectory(mock) add_subdirectory(dbus-services) ./tests/common/dbus-services/0000755000015600001650000000000012677320771016321 5ustar jenkinsjenkins./tests/common/dbus-services/CMakeLists.txt0000644000015600001650000000074112677320771021063 0ustar jenkinsjenkins# copy the services we want to use set(DBUS_SERVICES_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/dbus-1/services) file(COPY ${DBUS_SERVICES_DIR}/org.freedesktop.Telepathy.MissionControl5.service DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY ${DBUS_SERVICES_DIR}/org.freedesktop.Telepathy.AccountManager.service DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY ${DBUS_SERVICES_DIR}/ca.desrt.dconf.service DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) ./tests/CMakeLists.txt0000644000015600001650000000031312677320771015010 0ustar jenkinsjenkinsinclude (GenerateTest) add_subdirectory(common) add_subdirectory(approver) add_subdirectory(handler) add_subdirectory(indicator) add_subdirectory(libtelephonyservice) add_subdirectory(Ubuntu.Telephony) ./tests/Ubuntu.Telephony/0000755000015600001650000000000012677320772015504 5ustar jenkinsjenkins./tests/Ubuntu.Telephony/tst_PhoneNumberInput.qml0000644000015600001650000000476312677320771022364 0ustar jenkinsjenkins/* * Copyright (C) 2014 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.PhoneNumber 0.1 import "tst_PhoneNumberData.js" as TestData TestCase { id: phoneNumberInputTest name: "PhoneNumberInputTest" function init() { TestData.reset_item(phoneInput) } function test_updateOnlyWhenFocused() { phoneInput.updateOnlyWhenFocused = false compare(phoneInput.updateOnlyWhenFocused, false) } function test_formatPhone_data() { return TestData.formatPhone_data() } function test_formatPhone(data) { phoneInput.insert(0, data.input) tryCompare(phoneInput, "text", data.expectedOutput) tryCompare(phoneInput, "cursorPosition", data.expectedCursorPosition) } function test_modifyPhone_data() { return TestData.modifyPhone_data() } function test_modifyPhone(data) { phoneInput.text = data.input tryCompare(phoneInput, "text", data.formatedInput) phoneInput.cursorPosition = data.moveCursor tryCompare(phoneInput, "cursorPosition", data.moveCursor) switch (data.action) { case "remove": phoneInput.remove(data.moveCursor, data.moveCursor-1) break; case "insert": phoneInput.insert(data.moveCursor, data.text) } tryCompare(phoneInput, "text", data.newFormatedInput) tryCompare(phoneInput, "cursorPosition", data.expectedCursorPosition) } function test_update_autoFormater() { phoneInput.autoFormat = false phoneInput.text = "7572923" compare(phoneInput.text, "7572923") phoneInput.autoFormat = true compare(phoneInput.text, "757-2923") } PhoneNumberInput { id: phoneInput focus: true autoFormat: true defaultRegion: "US" } } ./tests/Ubuntu.Telephony/PresenceRequestTest.cpp0000644000015600001650000000725212677320771022172 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathytest.h" #include "presencerequest.h" #include "telepathyhelper.h" #include "mockcontroller.h" #include "accountentryfactory.h" Q_DECLARE_METATYPE(AccountEntry*) class PresenceRequestTest : public TelepathyTest { Q_OBJECT private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void testContactPresenceChange_data(); void testContactPresenceChange(); private: Tp::AccountPtr mTpAccount; AccountEntry *mAccount; MockController *mMockController; }; void PresenceRequestTest::initTestCase() { qRegisterMetaType(); initialize(); TelepathyHelper::instance()->registerChannelObserver(); } void PresenceRequestTest::init() { QSignalSpy accountSpy(TelepathyHelper::instance(), SIGNAL(accountAdded(AccountEntry*))); mTpAccount = addAccount("mock", "mock", "the account"); QVERIFY(!mTpAccount.isNull()); TRY_COMPARE(accountSpy.count(), 1); mAccount = qobject_cast(accountSpy.first().first().value()); QVERIFY(mAccount); TRY_VERIFY(mAccount->ready()); TRY_COMPARE(mAccount->status(), QString("available")); // and create the mock controller mMockController = new MockController("mock", this); } void PresenceRequestTest::cleanup() { doCleanup(); mMockController->deleteLater(); mAccount->deleteLater(); } void PresenceRequestTest::testContactPresenceChange_data() { QTest::addColumn("id"); QTest::addColumn("presenceType"); QTest::addColumn("status"); QTest::addColumn("statusMessage"); QTest::newRow("contact 1 online") << "contact1@test.com" << (int)Tp::ConnectionPresenceTypeAvailable << "online" << "message 1"; QTest::newRow("contact 1 offline") << "contact1@test.com" << (int)Tp::ConnectionPresenceTypeOffline << "offline" << ""; QTest::newRow("contact 2 online") << "contact2@test.com" << (int)Tp::ConnectionPresenceTypeAvailable << "online" << "message 2"; QTest::newRow("contact 2 offline") << "contact2@test.com" << (int)Tp::ConnectionPresenceTypeOffline << "offline" << ""; } void PresenceRequestTest::testContactPresenceChange() { QFETCH(QString, id); QFETCH(int, presenceType); QFETCH(QString, status); QFETCH(QString, statusMessage); PresenceRequest presenceRequest; QSignalSpy presenceRequestSpy(&presenceRequest, SIGNAL(typeChanged())); presenceRequest.setAccountId(mAccount->accountId()); presenceRequest.setIdentifier(id); presenceRequest.componentComplete(); mMockController->SetContactPresence(id, presenceType, status, statusMessage); TRY_COMPARE(presenceRequestSpy.count(), 1); TRY_COMPARE(presenceRequest.identifier(), id); TRY_COMPARE(presenceRequest.type(), (uint)presenceType); TRY_COMPARE(presenceRequest.status(), status); TRY_COMPARE(presenceRequest.statusMessage(), statusMessage); } QTEST_MAIN(PresenceRequestTest) #include "PresenceRequestTest.moc" ./tests/Ubuntu.Telephony/tst_PhoneNumberPhoneUtils.qml0000644000015600001650000000706112677320771023351 0ustar jenkinsjenkins/* * Copyright (C) 2014 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.2 import QtTest 1.0 import Ubuntu.Telephony.PhoneNumber 0.1 as PhoneNumber TestCase { id: phoneNumberPhoneUtils name: "phoneNumberPhoneUtils" function test_formatPhone_data() { var data = []; data.push({input: "6681800", expectedOutput: "668-1800"}) // Local number data.push({input: "7327572923", expectedOutput: "(732) 757-2923"}) // Country number data.push({input: "+558187042155", expectedOutput: "+55 81 8704-2155"}) // International number data.push({input: "55555555555", expectedOutput: "55555555555"}) // Invalid number data.push({input: "*144", expectedOutput: "*144"}) // Special number data.push({input: "#123#", expectedOutput: "#123#"}) // Operators command return data } function test_formatPhone(data) { var formatted = PhoneNumber.PhoneUtils.format(data.input, "US") compare(formatted, data.expectedOutput) } function test_locale() { var localeName = Qt.locale().name compare(PhoneNumber.PhoneUtils.defaultRegion, localeName.substr(localeName.length - 2, 2)) } function test_matchPhone_data() { var data = []; data.push({text: "my 1rst phone number 617-688-0034, ..", expectedMatches: ["617-688-0034"]}) // Local number data.push({text: "my 1rst phone number 650 253 0000, ..", expectedMatches: ["650 253 0000"]}) // Local number data.push({text: "my phnle number 7327572923, please call me", expectedMatches: ["7327572923"]}) // Country number data.push({text: "my international number +558187042155, please call me", expectedMatches: ["+558187042155"]}) // International number data.push({text: "this is an invalid number 55555555555, yes yes it is", expectedMatches: []}) // Invalid number data.push({text: "could you call me between 15h30-16h yes?", expectedMatches: []}) // Invalid number data.push({text: "could you call me between at extension *144 yes?", expectedMatches: []}) // Special number data.push({text: "my operator number: #123#, yes", expectedMatches: []}) // Operators command return data } function compareMatches(matches1, matches2) { compare(matches1.length, matches2.length) for (var i = 0; i < matches1.length; ++i) { compare(matches1[i], matches2[i]) } } function test_matchPhone(data) { var actualMatches = PhoneNumber.PhoneUtils.matchInText(data.text, "US") compareMatches(actualMatches, data.expectedMatches) } } ./tests/Ubuntu.Telephony/tst_PhoneNumberData.js0000644000015600001650000000710212677320771021747 0ustar jenkinsjenkins/* * Copyright (C) 2014 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 . */ function reset_item(item) { item.defaultRegion = "US" item.autoFormat = true item.text = "" item.cursorPosition = 0 item.updateOnlyWhenFocused = false } function formatPhone_data() { var data = []; data.push({input: "7572923", expectedOutput: "757-2923", expectedCursorPosition: 8}) // Local number data.push({input: "7327572923", expectedOutput: "(732) 757-2923", expectedCursorPosition: 14}) // Country number data.push({input: "+558187042155", expectedOutput: "+55 81 8704-2155", expectedCursorPosition: 16}) // International number data.push({input: "55555555555", expectedOutput: "55555555555", expectedCursorPosition: 11}) // Ivalid number data.push({input: "123#", expectedOutput: "123#", expectedCursorPosition: 4}) // Special number data.push({input: "#123#", expectedOutput: "#123#", expectedCursorPosition: 5}) data.push({input: "*144", expectedOutput: "*144", expectedCursorPosition: 4}) data.push({input: "123#456", expectedOutput: "123#456", expectedCursorPosition: 7}) data.push({input: "123,456", expectedOutput: "123,456", expectedCursorPosition: 7}) data.push({input: "123,;456;", expectedOutput: "123,;456;", expectedCursorPosition: 9}) data.push({input: "1+2;3,4*5#6;", expectedOutput: "1+2;3,4*5#6;", expectedCursorPosition: 12}) return data } function modifyPhone_data() { var data = []; // Input a number data.push({input: "555", formatedInput: "555", moveCursor: 3, action: "insert", text: "5", newFormatedInput: "555-5", expectedCursorPosition: 5}) // change a number and keep the format data.push({input: "7327572923", formatedInput: "(732) 757-2923", moveCursor: 4, action: "remove", text: "", newFormatedInput: "(737) 572-923", expectedCursorPosition: 3}) // fix a number wrong formatted data.push({input: "01234567890", formatedInput: "01234567890", moveCursor: 10, action: "remove", text: "", newFormatedInput: "(012) 345-6780", expectedCursorPosition: 13}) data.push({input: "75772923", formatedInput: "(757) 729-23", moveCursor: 7, action: "remove", text: "", newFormatedInput: "757-2923", expectedCursorPosition: 3}) data.push({input: "08199086488", formatedInput: "08199086488", moveCursor: 3, action: "remove", text: "", newFormatedInput: "(089) 908-6488", expectedCursorPosition: 3}) // special numbers data.push({input: "123", formatedInput: "1 23", moveCursor: 4, action: "insert", text: "#", newFormatedInput: "123#", expectedCursorPosition: 4}) data.push({input: "144", formatedInput: "1 44", moveCursor: 0, action: "insert", text: "*", newFormatedInput: "*144", expectedCursorPosition: 1}) return data } ./tests/Ubuntu.Telephony/CMakeLists.txt0000644000015600001650000000220712677320771020244 0ustar jenkinsjenkinsinclude_directories( ${CMAKE_CURRENT_BINARY_DIR} ${TP_QT5_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/Ubuntu/Telephony ${CMAKE_SOURCE_DIR}/libtelephonyservice ${CMAKE_SOURCE_DIR}/tests/common ${CMAKE_BINARY_DIR}/tests/common ${GSETTINGS_QT_INCLUDE_DIRS} ) set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/Ubuntu/Telephony) generate_test(ContactWatcherTest USE_UI SOURCES ContactWatcherTest.cpp LIBRARIES telephonyservice-qml QT5_MODULES Contacts Core DBus Qml Test) generate_test(context_properties QML_TEST tst_contextProperties.qml) generate_test(phonenumber_field QML_TEST tst_PhoneNumberField.qml) generate_test(phonenumber_input QML_TEST tst_PhoneNumberInput.qml) generate_test(phonenumber_utils QML_TEST tst_PhoneNumberPhoneUtils.qml) generate_telepathy_test(PresenceRequestTest SOURCES PresenceRequestTest.cpp LIBRARIES ${TP_QT5_LIBRARIES} telephonyservice mockcontroller telepathytest telephonyservice-qml) # make the files visible on qtcreator file(GLOB QML_TESTS *.qml *.js) add_custom_target(telephonyservice_QMLTESTS ALL SOURCES ${QML_TESTS}) ./tests/Ubuntu.Telephony/tst_contextProperties.qml0000644000015600001650000000223512677320771022653 0ustar jenkinsjenkins/* * 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"); } } ./tests/Ubuntu.Telephony/tst_PhoneNumberField.qml0000644000015600001650000000476312677320771022310 0ustar jenkinsjenkins/* * Copyright (C) 2014 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.PhoneNumber 0.1 import "tst_PhoneNumberData.js" as TestData TestCase { id: phoneNumberFieldTest name: "PhoneNumberFieldTest" function init() { TestData.reset_item(phoneField) } function test_updateOnlyWhenFocused() { phoneField.updateOnlyWhenFocused = false compare(phoneField.updateOnlyWhenFocused, false) } function test_formatPhone_data() { return TestData.formatPhone_data() } function test_formatPhone(data) { phoneField.insert(0, data.input) tryCompare(phoneField, "text", data.expectedOutput) tryCompare(phoneField, "cursorPosition", data.expectedCursorPosition) } function test_modifyPhone_data() { return TestData.modifyPhone_data() } function test_modifyPhone(data) { phoneField.text = data.input tryCompare(phoneField, "text", data.formatedInput) phoneField.cursorPosition = data.moveCursor tryCompare(phoneField, "cursorPosition", data.moveCursor) switch (data.action) { case "remove": phoneField.remove(data.moveCursor, data.moveCursor-1) break; case "insert": phoneField.insert(data.moveCursor, data.text) } tryCompare(phoneField, "text", data.newFormatedInput) tryCompare(phoneField, "cursorPosition", data.expectedCursorPosition) } function test_update_autoFormater() { phoneField.autoFormat = false phoneField.text = "7572923" compare(phoneField.text, "7572923") phoneField.autoFormat = true compare(phoneField.text, "757-2923") } PhoneNumberField { id: phoneField focus: true autoFormat: true defaultRegion: "US" } } ./tests/Ubuntu.Telephony/ContactWatcherTest.cpp0000644000015600001650000005344612677320771021774 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 #include QTCONTACTS_USE_NAMESPACE class ContactWatcherTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testIdentifier(); void testMatchExistingContact(); void testMatchNewContact(); void testMatchContactChanged(); void testClearAfterContactChanged(); void testContactRemoval(); void testClearPhoneNumber(); void testInteractiveProperty_data(); void testInteractiveProperty(); void testLateSearch(); void testAddressableFields(); void testExtendedFieldMatch(); void testSimilarPhoneNumbers(); 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::testIdentifier() { QString identifier("123456"); ContactWatcher watcher; QSignalSpy spy(&watcher, SIGNAL(identifierChanged())); watcher.setIdentifier(identifier); QCOMPARE(spy.count(), 1); QCOMPARE(watcher.identifier(), identifier); } void ContactWatcherTest::testMatchExistingContact() { QString identifier("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << identifier, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; watcher.componentComplete(); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // set the phone number and wait for the match to happen watcher.setIdentifier(identifier); // 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(detailPropertiesSpy.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.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail().contexts()); QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail().subTypes()); QCOMPARE(watcher.isUnknown(), false); clearManager(); } void ContactWatcherTest::testMatchNewContact() { QString identifier("1234567"); ContactWatcher watcher; watcher.componentComplete(); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); watcher.setIdentifier(identifier); // 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() << identifier.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(detailPropertiesSpy.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.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail().contexts()); QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail().subTypes()); QCOMPARE(watcher.isUnknown(), false); clearManager(); } void ContactWatcherTest::testMatchContactChanged() { QString identifier("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.componentComplete(); watcher.setIdentifier(identifier); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged())); QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged())); QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // now modify the contact´s phone number so that it matches QContactPhoneNumber number = contact.detail(); number.setNumber(identifier); 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(detailPropertiesSpy.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.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail().contexts()); QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), 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 identifier("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << identifier, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; watcher.componentComplete(); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); // set the phone number and wait for the match to happen watcher.setIdentifier(identifier); // 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 detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); 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(detailPropertiesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly cleared QVERIFY(watcher.contactId().isEmpty()); QVERIFY(watcher.alias().isEmpty()); QVERIFY(watcher.avatar().isEmpty()); QVERIFY(watcher.detailProperties().isEmpty()); QVERIFY(watcher.isUnknown()); 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 identifier("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << identifier, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; watcher.componentComplete(); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); // set the phone number and wait for the match to happen watcher.setIdentifier(identifier); // 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 detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); 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(detailPropertiesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly cleared QVERIFY(watcher.contactId().isEmpty()); QVERIFY(watcher.alias().isEmpty()); QVERIFY(watcher.avatar().isEmpty()); QVERIFY(watcher.detailProperties().isEmpty()); QVERIFY(watcher.isUnknown()); 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 identifier("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << identifier, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcher; watcher.componentComplete(); QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); // set the phone number and wait for the match to happen watcher.setIdentifier(identifier); // 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 detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // now clear the phone number watcher.setIdentifier(""); QCOMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(detailPropertiesSpy.count(), 1); QCOMPARE(unknownSpy.count(), 1); // and verify that the values are properly cleared QVERIFY(watcher.contactId().isEmpty()); QVERIFY(watcher.alias().isEmpty()); QVERIFY(watcher.avatar().isEmpty()); QVERIFY(watcher.detailProperties().isEmpty()); QVERIFY(watcher.isUnknown()); clearManager(); } void ContactWatcherTest::testInteractiveProperty_data() { QTest::addColumn("identifier"); QTest::addColumn("signalCount"); QTest::addColumn("interactive"); QTest::newRow("valid phone number") << "98765432" << 1 << true; QTest::newRow("ofono private phone number") << OFONO_PRIVATE_NUMBER << 0 << false; QTest::newRow("ofono unknown number") << OFONO_UNKNOWN_NUMBER << 0 << false; QTest::newRow("empty phone number") << "" << 0 << false; } void ContactWatcherTest::testInteractiveProperty() { QFETCH(QString, identifier); QFETCH(int, signalCount); QFETCH(bool, interactive); ContactWatcher watcher; watcher.componentComplete(); QSignalSpy spy(&watcher, SIGNAL(interactiveChanged())); watcher.setIdentifier(identifier); // the initial interactive value is false it will not change in case of invalid phones QTRY_COMPARE(spy.count(), signalCount); QCOMPARE(watcher.interactive(), interactive); } void ContactWatcherTest::testLateSearch() { QString identifier("12345"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << identifier, 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 detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged())); QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged())); // set the phone number and wait for the match to happen watcher.setIdentifier(identifier); // component not complete yet QTRY_COMPARE(contactIdSpy.count(), 0); QCOMPARE(aliasSpy.count(), 0); QCOMPARE(avatarSpy.count(), 0); QCOMPARE(detailPropertiesSpy.count(), 0); QCOMPARE(unknownSpy.count(), 0); // mark as complete watcher.componentComplete(); // signal will be fired now QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(aliasSpy.count(), 1); QCOMPARE(avatarSpy.count(), 1); QCOMPARE(detailPropertiesSpy.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.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail().contexts()); QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail().subTypes()); QCOMPARE(watcher.isUnknown(), false); clearManager(); } void ContactWatcherTest::testAddressableFields() { ContactWatcher watcher; // check that addressable fields contains "tel" by default QCOMPARE(watcher.addressableFields().count(), 1); QCOMPARE(watcher.addressableFields()[0], QString("tel")); QSignalSpy addressableFieldsSpy(&watcher, SIGNAL(addressableFieldsChanged())); QStringList addressableFields; addressableFields << "x-jabber" << "tel" << "x-sip"; watcher.setAddressableFields(addressableFields); QCOMPARE(addressableFieldsSpy.count(), 1); QCOMPARE(watcher.addressableFields(), addressableFields); // set the addressable fields to an empty value and make sure it falls back to "tel" watcher.setAddressableFields(QStringList()); QCOMPARE(watcher.addressableFields().count(), 1); QCOMPARE(watcher.addressableFields()[0], QString("tel")); } void ContactWatcherTest::testExtendedFieldMatch() { QString field("x-jabber"); QString identifier("foo.bar@someserver.jabber"); QContact contact = createContact("FirstName", "LastName", "file://some_file", QStringList() << "12345", QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); // now add the extended info to the contact QContactExtendedDetail detail; detail.setName(field); detail.setData(identifier); contact.appendDetail(detail); mManager->saveContact(&contact); // now create the watcher and check that it matches this field ContactWatcher watcher; QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged())); watcher.setIdentifier(identifier); watcher.setAddressableFields(QStringList() << field); watcher.componentComplete(); QTRY_COMPARE(contactIdSpy.count(), 1); QCOMPARE(watcher.contactId(), contact.id().toString()); } void ContactWatcherTest::testSimilarPhoneNumbers() { QString contactIdentifierA("+352 661 123456"); QString contactIdentifierB("+352 691 123456"); QContact contactA = createContact("FirstName", "LastName", "file://some_file", QStringList() << contactIdentifierA, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); QContact contactB = createContact("FirstName", "LastName", "file://some_file", QStringList() << contactIdentifierB, QList() << 0 << 1 << 2, QList() << 3 << 4 << 5); ContactWatcher watcherA; QSignalSpy contactIdSpyA(&watcherA, SIGNAL(contactIdChanged())); // try to match contact A watcherA.setIdentifier(contactIdentifierA); // mark as complete watcherA.componentComplete(); // signal will be fired now QTRY_COMPARE(contactIdSpyA.count(), 1); QCOMPARE(watcherA.contactId(), contactA.id().toString()); ContactWatcher watcherB; QSignalSpy contactIdSpyB(&watcherB, SIGNAL(contactIdChanged())); // mark as complete watcherB.componentComplete(); // try to match contact B watcherB.setIdentifier(contactIdentifierB); // signal will be fired now QTRY_COMPARE(contactIdSpyB.count(), 1); QCOMPARE(watcherB.contactId(), contactB.id().toString()); } 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" ./README0000644000015600001650000000007612677320771011774 0ustar jenkinsjenkinsThis is the repository for developing the phone application ./po/0000755000015600001650000000000012677320772011530 5ustar jenkinsjenkins./po/pl.po0000644000015600001650000001566112677320771012513 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-10-13 12:06+0000\n" "Last-Translator: Bartosz Kosiorek \n" "Language-Team: Polish \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: pl\n" #: indicator/messagingmenu.cpp:299 #, 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:398 #, 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" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Wykonanych połączeń: %1" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Odebranych połączeń: %1" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Otrzymanych wiadomości: %1" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Wysłanych wiadomości: %1" #: approver/approver.cpp:518 msgid "Accept" msgstr "Akceptuj" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Oddzwoń" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Numer rozmówcy jest niedostępny" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Połączenie z %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Połączenie z numerem prywatnym" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Połączenie z nieznanym numerem" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Anuluj" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Wyłącz tryb samolotowy oraz spróbuj ponownie poprzez aplikację do wysyłania " "wiadomości." #: approver/approver.cpp:540 msgid "Decline" msgstr "Odrzuć" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Zakończ i odbierz" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Wstrzymaj i odbierz" #: indicator/messagingmenu.cpp:241 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:244 msgid "I'll be 20 minutes late." msgstr "Spóźnię się 20 minut." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Jestem zajęty w tym momencie. Zadzwonię później." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Niestety nie mogę teraz odebrać. Oddzwonię później." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Pędzę z całych sił. Jestem już w drodze." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Spóźnię się. Jestem w drodze." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Odrzucenie + wiadomość" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Wiadomość od %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Dziś nie wykonano połączeń" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Dziś nie odebrano połączeń" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Dziś nie otrzymano wiadomości" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Dziś nie wysyłano wiadomości" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Rozmowy telefoniczne" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Proszę zadzwoń do mnie później." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Proszę wybrać kartę SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Numer zastrzeżony" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Numer zastrzeżony" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Odpowiedz" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Zapisz" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Wyślij" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Przykro mi, nadal nie mogę rozmawiać. Oddzwonię później." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Połączenia telefoniczne trwały dziś %1 minut." #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Obsługa telefonu" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Zatwierdzanie obsługi telefonu" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Wskaźnik obsługi telefonu" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Wiadomość nie może być wysłana." #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Spróbuj jeszcze raz z aplikacji wiadomości." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Numer nieznany" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Nieznany" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Nieznany numer" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Odblokuj kartę SIM i spróbuj ponownie z aplikacji wysyłania wiadomości." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Pokaż wiadomość" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Poczta głosowa" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Wiadomości głosowe" ./po/bs.po0000644000015600001650000001520412677320771012475 0ustar jenkinsjenkins# Bosnian translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-04-12 20:05+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Bosnian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 propušten poziv" msgstr[1] "%1 propuštena poziva" msgstr[2] "%1 propuštenih poziva" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 poruka govorne pošte" msgstr[1] "%1 poruke govorne pošte" msgstr[2] "%1 poruka govorne pošte" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 poziva napravljenih danas" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 poziva primljenih danas" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 tekstualnih poruka primljenih danas" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 tekstualnih poruka poslanih danas" #: approver/approver.cpp:518 msgid "Accept" msgstr "" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Poziv nazad" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Birani broj nije dostupan" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Zovem iz %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Zvanje sa privatnog broja" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Zvanje sa nepoznatog broja" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Otkaži" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Deaktiviraj režim letenja i pokušaj ponovo iz aplikacije za poruke." #: approver/approver.cpp:540 msgid "Decline" msgstr "Odbij" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Završetak + Odgovor" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Zadrži + Odgovori" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Propustio sam tvoj poziv - možeš li me nazvati sada?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Kasniću 20 minuta." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Zauzet sam trenutno. Zvaću te kasnije." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Zauzet sam trenutno. Zvaću te kasnije." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Kasnim, na putu sam sada." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Kasnim. Na putu sam." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Poruka & odbijanje" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Nema napravljenih poziva danas" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Nema primljenih poziva danas" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Nema primljenih poruka danas" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Nema poslanih poruka danas" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Molim te nazovi me kasnije." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Molim, odaberi SIM karticu:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Privatni Broj" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Izvini, još uvijek sam zauzet. Zvaću te kasnije." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Potrošene %1 minute na pozive danas" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonski Servis" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefonski servis odobravatelj" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefonski servis pokazatelj" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Poruka ne može biti poslana" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Pokušaj ponovo iz aplikacije za poruke." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Nepoznat broj" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Nepoznat pozivalac" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Otključaj svoju sim karticu i pokušaj ponovo iz aplikacije za poruke." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Vidi poruku" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Govorna pošta poruke" ./po/pa.po0000644000015600001650000002073112677320771012472 0ustar jenkinsjenkins# Punjabi translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-15 05:43+0000\n" "Last-Translator: Gursharnjit_Singh \n" "Language-Team: Punjabi \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 ਮਿਸ ਕਾਲ" msgstr[1] "%1 ਮਿਸ ਕਾਲਾਂ" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 ਵੋਆਇਸਮੇਲ ਸੁਨੇਹਾ" msgstr[1] "%1 ਵੋਆਇਸਮੇਲ ਸੁਨੇਹੇ" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 ਅੱਜ ਕੀਤੀਆਂ ਕਾਲਾਂ" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 ਅੱਜ ਮਿਲੀਆਂ ਕਾਲਾਂ" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 ਅੱਜ ਮਿਲੇ ਟੈਕਸਟ ਸੁਨੇਹੇ" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 ਅੱਜ ਭੇਜੇ ਗਏ ਟੈਕਸਟ ਸੁਨੇਹੇ" #: approver/approver.cpp:518 msgid "Accept" msgstr "ਮਨਜ਼ੂਰ" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "ਮੁੜ ਕਾਲ ਕਰੋ" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "ਕਾਲਰ ਨੰਬਰ ਮੌਜੂਦ ਨਹੀਂ" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1 ਤੋਂ ਕਾਲ ਕਰ ਰਿਹਾ" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "ਨਿੱਜੀ ਨੰਬਰ ਤੋਂ ਕਾਲ ਕਰ ਰਿਹਾ" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "ਅਣਪਛਾਤੇ ਨੰਬਰ ਤੋਂ ਕਾਲ ਕਰ ਰਿਹਾ" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "ਰੱਦ" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "ਹਵਾਈ ਮੋਡ ਬੰਦ ਕਰੋ ਅਤੇ ਮੈਸੇਜ਼ਿੰਗ ਐਪਲੀਕੇਸ਼ਨ ਤੋਂ ਮੁੜ ਕੋਸ਼ਿਸ ਕਰੋ।" #: approver/approver.cpp:540 msgid "Decline" msgstr "ਇਨਕਾਰ" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "ਅੰਤ + ਜਵਾਬ" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "ਰੱਖੋ + ਜਵਾਬ" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "ਮੈਂ ਤੁਹਾਡੀ ਕਾਲ ਤੋਂ ਖੁੰਝ ਗਿਆ - ਕੀ ਤੁਸੀਂ ਮੈਨੂੰ ਹੁਣ ਕਾਲ ਕਰ ਸਕਦੇ ਹੋ?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "ਮੈਨੂੰ 20 ਮਿੰਟਾਂ ਦੀ ਦੇਰੀ ਹੋਵੇਗੀ।" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "ਇਸ ਵੇਲੇ ਮੈਂ ਰੁਝਿਆ ਹਾਂ। ਮੈਂ ਬਾਅਦ ਵਿੱਚ ਕਾਲ ਕਰਾਂਗਾ।" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "ਮੈਂ ਇਸ ਵੇਲੇ ਰੁਝਿਆ ਹਾਂ। ਮੈਂ ਤੁਹਾਨੂੰ ਬਾਅਦ ਵਿੱਚ ਕਾਲ ਕਰਾਂਗਾ।" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "ਮੈਨੂੰ ਦੇਰੀ ਹੋ ਰਹੀ ਹੈ, ਮੈਂ ਹਾਲੇ ਰਾਹ ਵਿੱਚ ਹਾਂ।" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "ਮੈਨੂੰ ਦੇਰੀ ਹੋ ਰਹੀ ਹੈ, ਮੈਂ ਰਾਹ ਵਿੱਚ ਹਾਂ।" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "ਸੁਨੇਹਾ ਅਤੇ ਇਨਕਾਰ" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "%1 ਤੋਂ ਸੁਨੇਹਾ" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "ਅੱਜ ਕੋਈ ਕਾਲ ਨਹੀਂ ਕੀਤੀ" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "ਅੱਜ ਕੋਈ ਕਾਲ ਨਹੀਂ ਮਿਲੀ" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "ਅੱਜ ਕੋਈ ਟੈਕਸਟ ਸੁਨੇਹਾ ਨਹੀਂ ਮਿਲਿਆ" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "ਅੱਜ ਕੋਈ ਟੈਕਸਟ ਸੁਨੇਹਾ ਨਹੀਂ ਭੇਜਿਆ" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "ਠੀਕ" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "ਫ਼ੋਨ ਕਾਲਾਂ" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "ਕਿਰਪਾ ਕਰਕੇ ਮੈਨੂੰ ਬਾਅਦ ਵਿੱਚ ਕਾਲ ਕਰੋ।" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "ਕਿਰਪਾ ਕਰਕੇ, ਸਿਮ ਕਾਰਡ ਚੁਣੋ:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "ਨਿੱਜੀ ਨੰਬਰ" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "ਨਿੱਜੀ ਨੰਬਰ" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "ਜਵਾਬ" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "ਸਿਮ %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "ਸੰਭਾਲ੍ਹੋ" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "ਭੇਜੋ" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "ਮੁਆਫ਼ੀ, ਮੈਂ ਹਾਲੇ ਵੀ ਰੁਝਿਆ ਹਾਂ। ਮੈਂ ਤੁਹਾਨੂੰ ਬਾਅਦ ਵਿੱਚ ਕਾਲ ਕਰਾਂਗਾ।" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "ਅੱਜ %1 ਮਿੰਟ ਕਾਲਾਂ ਵਿੱਚ ਬਿਤਾਏ" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "ਟੈਲੀਫ਼ੋਨੀ ਸੇਵਾ" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "ਟੈਲੀਫ਼ੋਨੀ ਸੇਵਾ ਪ੍ਰਵਾਨਗੀ" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "ਟੈਲੀਫ਼ੋਨੀ ਸੇਵਾ ਸੂਚਕ" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "ਸੁਨੇਹਾ ਭੇਜਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "ਮੈਸੇਜ਼ਿੰਗ ਐਪਲੀਕੇਸ਼ਨ ਤੋਂ ਮੁੜ ਕੋਸ਼ਿਸ ਕਰੋ।" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "ਅਣਪਛਾਤਾ ਨੰਬਰ" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "ਅਣਪਛਾਤਾ ਕਾਲਰ" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "ਅਣਜਾਣ ਨੰਬਰ" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "ਆਪਣੇ ਸਿਮ ਕਾਰਡ ਦਾ ਲਾੱਕ ਖੋਲ੍ਹੋ ਅਤੇ ਮੈਸੇਜ਼ਿੰਗ ਸੇਵਾ ਤੋਂ ਮੁੜ ਕੋਸ਼ਿਸ ਕਰੋ।" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "ਸੁਨੇਹਾ ਵਿਖਾਓ" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "ਵੋਆਇਸਮੇਲ" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "ਵੋਆਇਸਮੇਲ ਸੁਨੇਹੇ" ./po/az.po0000644000015600001650000001366512677320771012514 0ustar jenkinsjenkins# Azerbaijani translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-08-31 07:59+0000\n" "Last-Translator: Nicat Məmmədov \n" "Language-Team: Azerbaijani \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 cavabsız zәng" msgstr[1] "%1 cavabsız zәng" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 sәsli mesaj" msgstr[1] "%1 sәsli mesaj" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Bu gün %1 zәng qәbul edildi" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Bu gün %1 mәtn mesajı qәbul edildi" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Bu gün %1 mәtn mesajı göndәrildi" #: approver/approver.cpp:518 msgid "Accept" msgstr "Qәbul" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Bilinmәyәn nömrәdәn zәng olunur" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "İmtina" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "Rədd" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20 dәqiqә gecikәcәm." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "İndi mәşğulam. Sәnә sonra zәng edәcәm." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Bu gün heç bir zәng edilmәyib" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Bu gün heç bir zәng qәbul edilmәdi" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Bu gün heç bir mәtn mesajı qәbul edilmәdi" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Bu gün heç bir mәtn mesajı göndәrilmәyib" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Oldu" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Cavabla" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Saxla" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Bağışla, hәlә dә mәşğulam. Sәnә sonra zәng edәcәm." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Bilinmәyәn Nömrә" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Bilinmәyәn nömrә" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Mesaja bax" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Sәsli mesajlar" ./po/gl.po0000644000015600001650000001523112677320771012473 0ustar jenkinsjenkins# Galician translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-06-16 10:02+0000\n" "Last-Translator: Marcos Lans \n" "Language-Team: Galician \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 chamada perdida" msgstr[1] "%1 chamadas perdidas" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 correo de voz" msgstr[1] "%1 correos de voz" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Hoxe fixo %1 chamada(s)" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Hoxe recibiu %1 chamadas" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Hoxe recibiu %1 mensaxes" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Hoxe enviou %1 mensaxes" #: approver/approver.cpp:518 msgid "Accept" msgstr "Aceptar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Chamar de volta" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "O número do comunicante non está dispoñíbel" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Chamada de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Chamada desde un número privado" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Chamada desde un número descoñecido" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancelar" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Desactive o modo avión e probe desde o aplicativo de mensaxería." #: approver/approver.cpp:540 msgid "Decline" msgstr "Rexeitar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Rematar + Responder" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Manter + Contestar" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Perdín a súa chamada, pode chamarme agora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Chegarei 20 minutos tarde." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Estou ocupado neste intre. Chamarei máis tarde." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Neste intre estou ocupado. Chamarei máis tarde." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Chego tarde, estou en camiño." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Chego tarde. Estou en camiño." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Rexeitar cunha mensaxe" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mensaxe de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Hoxe non fixo chamadas" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Hoxe non recibiu chamadas" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Hoxe non recibiu mensaxes de texto" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Hoxe non enviou mensaxes de texto" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Aceptar" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Chamadas telefónicas" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Por favor, chámeme máis tarde." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Escolla unha tarxeta SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Número privado" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Número privado" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Responder" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Gardar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Enviar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Síntoo, estou ocupado. Chamarei máis tarde." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Hoxe ten %1 minutos de chamadas" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servizo de telefonía" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprobador do sevizo telefónico" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador do servizo de telefonía" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Non foi posíbel enviar a mensaxe" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Volva probar desde o aplicativo de mensaxería." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Número descoñecido" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Comunicante descoñecido" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Número descoñecido" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Desbloquee a SIM e volva probar dede o aplicativo de mensaxería." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ver mensaxe" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Correo de voz" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Correos de voz" ./po/nl.po0000644000015600001650000001526712677320771012513 0ustar jenkinsjenkins# Dutch translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-05-03 10:09+0000\n" "Last-Translator: Matthijs Nicolai \n" "Language-Team: Dutch \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 gemiste oproep" msgstr[1] "%1 gemiste oproepen" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 voicemailbericht" msgstr[1] "%1 voicemailberichten" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 keer zelf gebeld vandaag" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 oproepen ontvangen vandaag" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 sms-berichten ontvangen vandaag" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 sms-berichten verstuurd vandaag" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accepteren" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Terugbellen" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Nummer inkomend gesprek niet beschikbaar" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Oproep van %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Oproep van privénummer" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Oproep van onbekend nummer" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Annuleren" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Deactiveer de vliegtuigstand en probeer het a.u.b. opnieuw met de " "berichtenapp." #: approver/approver.cpp:540 msgid "Decline" msgstr "Weigeren" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Beëindigden + beantwoorden" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "In de wacht + beantwoorden" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Ik heb uw oproep gemist - kunt u me nu bellen?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Ik kom 20 minuten later." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Ik ben momenteel bezig. Ik bel later terug." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Ik ben momenteel bezig. Ik bel later terug." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Ik ben laat. Ik ben onderweg." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Ik ben laat. Ik ben onderweg." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Bericht & weigeren" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Bericht van %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Niet zelf gebeld vandaag" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Geen oproepen ontvangen vandaag" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Geen sms-berichten ontvangen vandaag" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Geen sms-berichten verstuurd vandaag" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefoongesprekken" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Bel me a.u.b. later terug." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Selecteer a.u.b. een simkaart:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Privénummer" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Privénummer" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Beantwoorden" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "Sim %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "Sms" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Opslaan" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Versturen" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Sorry, ik ben nog steeds bezig. Ik bel later terug." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 minuten getelefoneerd vandaag" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefoondienst" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefoondienstgoedkeuring" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefoondienstindicator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Het bericht kon niet verstuurd worden" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Probeer het a.u.b. opnieuw met de berichtenapp." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Onbekend nummer" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Onbekende beller" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Onbekend nummer" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Deblokkeer uw simkaart en probeer het a.u.b. opnieuw met de berichtenapp." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Bericht weergeven" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Voicemail" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Voicemailberichten" ./po/ca.po0000644000015600001650000001541312677320771012456 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-27 07:40+0000\n" "Last-Translator: David Planella \n" "Language-Team: Catalan \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: ca\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 trucada perduda" msgstr[1] "%1 trucades perdudes" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 missatge de veu" msgstr[1] "%1 missatge de veu" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 trucades fetes avui" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 trucades rebudes avui" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 missatges de text rebuts avui" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 missatges de text enviats avui" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accepta" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Truca" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "El número de la trucada entrant no està disponible" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "S'està trucant des de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "S'està trucant des d'un número privat" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "S'està trucant des d'un número desconegut" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancel·la" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Desactiveu el mode d'avió i torneu-ho a intentar des de l'aplicació de " "missatgeria." #: approver/approver.cpp:540 msgid "Decline" msgstr "Rebutja" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Finalitza i contesta" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Retenció i resposta" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "No he pogut contestar - em pots trucar ara?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Arribaré 20 minuts tard." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Ara mateix tinc feina. Trucaré més tard." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Ara mateix estic enfeina. Trucaré més tard." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Vaig venint, però arribaré tard." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Arribo tard. Ja estic venint." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Envia un missatge i declina" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Missatge d'en/na %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Avui no heu fet cap trucada" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Avui no heu rebut cap trucada" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Avui no heu rebut cap missatge de text" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Avui no heu enviat cap missatge de text" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "D'acord" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Trucades de telèfon" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Truca'm més tard." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Seleccioneu una targeta SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Númeor privat" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Número privat" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Resposta" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Desa" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Envia" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Tinc feina, et trucaré més tard" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Heu estat %1 minuts en trucades avui" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servei de telefonia" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprovador del servei de telefonia" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador del servei de telefonia" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "No s'ha pogut enviar el missatge" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Torneu-ho a intentar per a l'aplicació de missatgeria." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Número desconegut" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Número entrant desconegut" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Número desconegut" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Desbloqueu la targeta SIM i torneu-ho a provar des de l'aplicació de " "missatgeria." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Mostra el missatge" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Bústia de veu" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Missatges de veu" ./po/ia.po0000644000015600001650000001543012677320771012463 0ustar jenkinsjenkins# Interlingua translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-05-17 11:09+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Interlingua \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 appello perdite" msgstr[1] "%1 appellos perdite" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 message de posta vocal" msgstr[1] "%1 messages de posta vocal" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 appellos facite hodie" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 appellos recipite hodie" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 messages de texto recipite hodie" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 messages de texto expedite hodie" #: approver/approver.cpp:518 msgid "Accept" msgstr "Acceptar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Appellar retro" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Le numero del appellante non es disponibile" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Appello de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Appello per un numero private" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Appello per un numero incognite" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Deler" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Disactivar le modo volo et reprobar ex le application de messages." #: approver/approver.cpp:540 msgid "Decline" msgstr "Declinar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Finir + responder" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Suspender + responder" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Io ha perdite tu appello - pote tu appellar me ora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Io essera 20 minutas in retardo." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Io es occupate al momento. Io appellara plus tarde." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Io es occupate al momento. Io appellara te plus tarde." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Io es fluente in retardo, sur mi cammino ora." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Io es fluente in retardo. Io es sur mi cammino." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Message & declination" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Message ex %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Necun appellos facite hodie" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Necun appellos recipite hodie" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Necun messages de texto recipite hodie" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Necun messages de texto expedite hodie" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Appellos telephonic" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Per favor appella me retro plus tarde." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Per favor, selige un carta SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Numero private" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Numero private" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Responder" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Salvar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Mandar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Displacente, io es ancora occupate. Io appellara te plus tarde." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Pagate %1 minutas in appellos hodie" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servicio de telephonia" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Approbator del servicio de telephonia" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicator del servicio de telephonia" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Le message non pote esser expedite" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Reprobar per le application de messages." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Numero incognite" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Appellator incognite" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Numero incognite" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Disbloca tu carta SIM e reproba ex le application de messages." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Vider le message" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Message vocal" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Messages vocal" ./po/zh_TW.po0000644000015600001650000001470312677320771013127 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-03 13:17+0000\n" "Last-Translator: Cheng-Chia Tseng \n" "Language-Team: Chinese (Traditional) \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: \n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 通未接來電" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 通語音留言" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "今日打出 %1 個電話" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "今日收到 %1 個電話" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "今日收到 %1 封文字訊息" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "今日發出 %1 封文字訊息" #: approver/approver.cpp:518 msgid "Accept" msgstr "接聽" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "回撥" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "無法查看來電號碼" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1 來電" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "私人號碼來電" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "來電號碼不明" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "取消" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "請關閉飛安模式,並回到訊息程式中再試一次。" #: approver/approver.cpp:540 msgid "Decline" msgstr "拒接" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "結束 + 接聽" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Hold + 接聽" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "剛才沒聽到電話,可以現在打給我嗎?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "二十分鐘後到。" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "我現在很忙,稍後再撥給你。" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "現在正忙,晚點打給你。" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "我快遲到了,現在正在路上。" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "正在來了,遲些才到。" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "傳訊息並拒接" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "來自 %1 的訊息" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "今日沒有打出電話" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "今日沒有收到電話" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "今日沒有收到文字訊息" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "今日沒有發出文字訊息" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "確定" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "來電" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "請待會再打給我。" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "請選擇一張 SIM 卡:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "私人號碼" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "私人號碼" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "回覆" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "儲存" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "傳送" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "抱歉,我還在忙。待會打給你。" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "今日打出的電話共用了 %1 分鐘" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "電話服務" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "電話操作服務核可員" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "電話服務指示器" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "訊息無法傳送" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "請在訊息程式中再試一次。" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "號碼不明" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "來電者不明" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "號碼不明" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "請解鎖您的 SIM 卡,並回到訊息程式中再試一次。" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "檢視訊息" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "語音留言" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "語音留言訊息" ./po/ca@valencia.po0000644000015600001650000001540412677320771014261 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-22 15:22+0000\n" "Last-Translator: David Planella \n" "Language-Team: Catalan \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: ca\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 cridada perduda" msgstr[1] "%1 cridades perdudes" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 missatge de veu" msgstr[1] "%1 missatge de veu" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 cridades fetes hui" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 cridades rebudes hui" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 missatges de text rebuts hui" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 missatges de text enviats hui" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accepta" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Crida" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "El número de la cridada entrant no està disponible" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "S'està cridant des de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "S'està cridant des d'un número privat" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "S'està cridant des d'un número desconegut" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancel·la" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Desactiveu el mode d'avió i torneu-ho a intentar des de l'aplicació de " "missatgeria." #: approver/approver.cpp:540 msgid "Decline" msgstr "Rebutja" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Finalitza i contesta" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Retenció i resposta" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "No he pogut contestar - em pots cridar ara?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Arribaré 20 minuts tard." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Ara mateix tinc faena. Cridaré més tard." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Ara mateix estic enfeina. Cridaré més tard." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Vaig venint, però arribaré tard." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Arribo tard. Ja estic venint." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Envia un missatge i declina" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Missatge d'en/na %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Hui no heu fet cap cridada" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Hui no heu rebut cap cridada" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Hui no heu rebut cap missatge de text" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Hui no heu enviat cap missatge de text" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "D'acord" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Cridades de telèfon" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Crida'm més tard." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Seleccioneu una targeta SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Númeor privat" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Número privat" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Resposta" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Guarda" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Envia" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Tinc faena, et cridaré més tard" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Heu estat %1 minuts en cridades hui" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servei de telefonia" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprovador del servei de telefonia" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador del servei de telefonia" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "No s'ha pogut enviar el missatge" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Torneu-ho a intentar per a l'aplicació de missatgeria." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Número desconegut" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Número entrant desconegut" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Número desconegut" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Desbloqueu la targeta SIM i torneu-ho a provar des de l'aplicació de " "missatgeria." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Mostra el missatge" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Bústia de veu" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Missatges de veu" ./po/nb.po0000644000015600001650000001504512677320771012473 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-18 21:29+0000\n" "Last-Translator: Åka Sikrom \n" "Language-Team: Norwegian Bokmal \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: nb\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 ubesvart anrop" msgstr[1] "%1 ubesvarte anrop" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 talemelding" msgstr[1] "%1 talemeldinger" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Ringt ut %1 ganger i dag" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Mottatt %1 anrop i dag" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Mottatt %1 tekstmeldinger i dag" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Sendt %1 tekstmeldinger i dag" #: approver/approver.cpp:518 msgid "Accept" msgstr "Godta" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Ring tilbake" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Anropsnummer er ikke tilgjengelig" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Ringer fra %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Ringer fra skjult nummer" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Ringer fra ukjent nummer" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Avbryt" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Slå av flymodus og prøv igjen fra meldingsprogrammet." #: approver/approver.cpp:540 msgid "Decline" msgstr "Avslå" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Avslutt + svar" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Hold + Svar" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Jeg gikk glipp av anropet ditt. Kan du ringe meg nå?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Jeg blir 20 minutter forsinket." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Jeg er opptatt for øyeblikket. Ringer deg senere." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Jeg er opptatt akkurat nå. Ringer deg senere." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Jeg blir forsinket. Er på vei nå." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Jeg blir noe forsinket. Er på vei." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Send melding og avvis" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Melding fra %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Ingen utgående anrop i dag" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Ingen mottatte anrop i dag" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Ingen mottatte tekstmeldinger i dag" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Ingen sendte tekstmeldinger i dag" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonsamtaler" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Ring meg heller senere." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Velg et SIM-kort:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Skjult nummer" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Skjult nummer" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Svar" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Lagre" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Send" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Beklager, men jeg er fortsatt opptatt. Ringer deg senere." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Vært i anrop i %1 minutter i dag" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefontjeneste" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefontjeneste-godkjenning" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefontjeneste-indikator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Meldinga ble ikke sendt" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Prøv på nytt fra meldingsprogrammet" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Ukjent nummer" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Ukjent anropsperson" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Ukjent nummer" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Lås opp SIM-kortet og prøv på nytt fra meldingsprogrammet" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Vis melding" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Mobilsvar" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Talemeldinger" ./po/cs.po0000644000015600001650000001557512677320771012511 0ustar jenkinsjenkins# Czech translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-05-11 16:39+0000\n" "Last-Translator: Vojtěch Daněk \n" "Language-Team: Czech \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>=2 && n<=4) ? 1 : 2;\n" "X-Launchpad-Export-Date: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: cs\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 zmeškaný hovor" msgstr[1] "%1 zmeškané hovory" msgstr[2] "%1 zmeškaných hovorů" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 hlasová zpráva" msgstr[1] "%1 hlasové zprávy" msgstr[2] "%1 hlasových zpráv" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 dnešních hovorů" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 dnes přijatých hovorů" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 dnes přijatých textových zpráv" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 dnes odeslaných textových zpráv" #: approver/approver.cpp:518 msgid "Accept" msgstr "Vzít" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Zavolat zpět" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Číslo volajícího není dostupné" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Volání z %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Volání ze soukromého čísla" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Volání z neznámého čísla" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Zrušit" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Deaktivujte režim letadla a zkuste zprávu odeslat znovu." #: approver/approver.cpp:540 msgid "Decline" msgstr "Odmítnout" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Ukončit + Odpověď" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Podržet + Odpověď" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Zmeškal jsem Tvůj hovor. Můžeš mi zavolat nyní?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Budu mít 20 minut zpoždění." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Momentálně jsem zaneprázdněný. Zavolám později." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Momentálně jsem zaneprázdněný. Zavolám Ti později." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Mám zpoždění, jsem na cestě." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Mám zpoždění. Už jsem na cestě." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Zpráva & odmítnout" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Zpráva od %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Dnes nebyly uskutečněny žádné hovory" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Dnes nebyly přijaty žádné hovory" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Dnes nebyly přijaty žádné textové zprávy" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Dnes nebyly odeslány žádné textové zprávy" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonní hovory" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Prosím, zavolete mi později." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Prosím, vložte SIM kartu:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Soukromé číslo" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Soukromé číslo" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Odpověď" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Uložit" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Odeslat" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Omlouvám se, stále jsem zaneprázdněn. Zavolám Vám později." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Dnes jste telefonoval %1 minut." #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonní servis" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Potvrzení telefonního servisu" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indikátor telefonního servisu" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Zpráva nemohla být odeslána" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Zkuste znovu z aplikace zpráv." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Neznámé číslo" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Neznámý volající" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Neznámé číslo" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Odemkněte svou sim kartu a zkuste zprávu odeslat znovu z aplikace zpráv." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Zobrazit zprávu" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Hlasová zpráva" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Hlasové zprávy" ./po/fa.po0000644000015600001650000001656312677320771012470 0ustar jenkinsjenkins# Persian translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-11-27 00:47+0000\n" "Last-Translator: Danial Behzadi \n" "Language-Team: Persian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 تماس بی‌پاسخ" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 پیام پست صوتی" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "امروز %1 تماس گرفته شد" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "امروز %1 تماس دریافت شد" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "امروز %1 پیام متنی دریافت شد" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "امروز %1 پیام متنی فرستاده شد" #: approver/approver.cpp:518 msgid "Accept" msgstr "پذیرش" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "زنگ زدن" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "شماره‌ی تماس‌گیرنده موجود نیست" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "در حال تماس از %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "در حال تماس از شماره‌ی خصوصی" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "درحال تماس از شماره‌ی نامشخص" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "لغو" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "حالت پرواز را خاموش کرده و دوباره از برنامه ی پیام‌رسان تلاش کنید." #: approver/approver.cpp:540 msgid "Decline" msgstr "رد" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "پایان + پاسخ" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "نگه داشتن + پاسخ" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "تماستون رو از دست دادم. می‌شه الآن با من تماس بگیرید؟" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "۲۰ دقیقه تأخیر خواهم داشت." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "الآن گرفتارم. بعداً زنگ می‌زنم" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "الآن سرم شلوعه. بعداً باهاتون تماس می‌گیرم." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "تأخیر دارم، توی راهم." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "دیر می‌رسم. تو راهم." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "پیام دادن و رد کردن" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "پیام از %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "امروز تماسی گرفته نشد" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "امروز تماسی دریافت نشد" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "امروز پیام متنی‌ای دریافت نشد" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "امروز پیام متنی‌ای فرستاده نشد" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "باشه" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "تماس‌های تلفنی" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "لطفاً بعداً باهام تماس بگیر." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "لطفاً سیم‌کارتی را برگزینید:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "شماره‌ی خصوصی" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "شماره‌ی خصوصی" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "پاسخ" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "سیم‌کارت %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "پیامک" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "ذخیره" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "فرستادن" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "ببخشید، هنوز دگیرم. بعداً باهاتون تماس می‌گیرم." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "امروز %1 دقیقه صرف تماس شد" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "خدمات تلفن" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "تأییدکننده‌ی خدمات تلفن" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "نشانگر خدمات تلفن" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "پیام نتوانست فرستاده شود" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "دوباره از برنامه ی پیام‌رسان تلاش کنید." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "شماره‌ی ناشناس" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "تماس‌گیرنده‌ی ناشناس" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "شماره‌ی ناشناس" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "قفل سیم‌کارتتان را باز کرده و دوباره از برنامه ی پیام‌رسان تلاش کنید." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "دیدن پیام" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "پست صوتی" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "پیام‌های پست صوتی" ./po/pt.po0000644000015600001650000001532012677320771012513 0ustar jenkinsjenkins# Portuguese translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-10-26 10:12+0000\n" "Last-Translator: Ivo Xavier \n" "Language-Team: Portuguese \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 chamada perdida" msgstr[1] "%1 chamadas perdidas" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mensagem de voicemail" msgstr[1] "%1 mensagens de voicemail" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 chamadas feitas hoje" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 chamadas recebidas hoje" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 mensagens de texto recebidas hoje" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 mensagens de texto enviadas hoje" #: approver/approver.cpp:518 msgid "Accept" msgstr "Aceitar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Ligar de volta" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Número desconhecido" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "A chamar de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "A chamar de um número privado" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "A chamar de um número desconhecido" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancelar" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Desative o modo avião e tente novamente através da app mensagens." #: approver/approver.cpp:540 msgid "Decline" msgstr "Recusar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Fim + Resposta" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Segurar + Responder" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Não atendi a sua chamada - pode ligar agora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Estou 20 minutos atrasado." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Estou ocupado neste momento. Ligo de volta mais tarde." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "De momento estou ocupado. Telefono mais tarde." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Estou atrasado, já estou a ir." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Estou atrasado. Vou a caminho." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Mensagem e declinar" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mensagem de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Sem chamadas feitas hoje" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Sem chamadas recebidas hoje" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Sem mensagens de texto recebidas hoje" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Sem mensagens de texto enviadas hoje" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Chamadas telefónicas" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Por favor, telefone mais tarde." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Por favor, selecione um cartão SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Número privado" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Número privado" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Responder" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Guardar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Enviar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Desculpe, ainda estou ocupado. Telefono mais tarde." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Falou %1 minutos em chamadas hoje" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Serviço telefónico" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprovador de serviço telefónico" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador de serviço telefónico" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "A mensagem não foi enviada" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Tente novamente através da app mensagens." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Número desconhecido" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Chamador desconhecido" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Número desconhecido" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Desbloqueie o seu cartão SIM e tente novamente através da app mensagens." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ver mensagem" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Voicemail" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Mensagens voicemail" ./po/en_GB.po0000644000015600001650000001503312677320771013043 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-08-01 16:48+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom) \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: \n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 missed call" msgstr[1] "%1 missed calls" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 voicemail message" msgstr[1] "%1 voicemail messages" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 calls made today" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 calls received today" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 text messages received today" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 text messages sent today" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accept" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Call back" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Caller number is not available" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Calling from %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Calling from private number" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Calling from unknown number" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancel" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Deactivate flight mode and try again from the messaging application." #: approver/approver.cpp:540 msgid "Decline" msgstr "Decline" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "End + Answer" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Hold + Answer" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "I missed your call - can you call me now?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "I'll be 20 minutes late." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "I'm busy at the moment. I'll call later." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "I'm busy at the moment. I'll call you later." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "I'm running late, on my way now." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "I'm running late. I'm on my way." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Message & decline" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Message from %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "No calls made today" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "No calls received today" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "No text messages received today" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "No text messages sent today" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Phone Calls" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Please call me back later." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Please, select a SIM card:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Private Number" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Private number" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Reply" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Save" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Send" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Sorry, I'm still busy. I'll call you later." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Spent %1 minutes in calls today" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telephony Service" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telephony Service Approver" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telephony Service Indicator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "The message could not be sent" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Try again from the messaging application." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Unknown Number" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Unknown caller" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Unknown number" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Unlock your SIM card and try again from the messaging application." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "View message" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Voicemail" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Voicemail messages" ./po/telephony-service.pot0000644000015600001650000001206612677320771015725 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\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:256 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:308 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:426 msgid "Accept" msgstr "" #: indicator/messagingmenu.cpp:199 msgid "Call back" msgstr "" #: approver/approver.cpp:392 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:389 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:385 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:387 msgid "Calling from unknown number" msgstr "" #: indicator/ussdindicator.cpp:104 msgid "Cancel" msgstr "" #: indicator/textchannelobserver.cpp:207 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:448 msgid "Decline" msgstr "" #: approver/approver.cpp:439 msgid "End + Answer" msgstr "" #: approver/approver.cpp:425 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:204 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:207 msgid "I'll be 20 minutes late." msgstr "" #: approver/approver.cpp:79 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:206 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: approver/approver.cpp:80 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:205 msgid "I'm running late. I'm on my way." msgstr "" #: approver/approver.cpp:456 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:393 indicator/textchannelobserver.cpp:440 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/ussdindicator.cpp:79 indicator/textchannelobserver.cpp:270 msgid "Ok" msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: approver/approver.cpp:81 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:539 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:136 msgid "Private Number" msgstr "" #: indicator/messagingmenu.cpp:259 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:82 msgid "Reply" msgstr "" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:276 msgid "Save" msgstr "" #: indicator/messagingmenu.cpp:151 indicator/messagingmenu.cpp:214 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:208 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:55 indicator/messagingmenu.cpp:59 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:50 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:215 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:210 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:138 msgid "Unknown Number" msgstr "" #: approver/approver.cpp:59 msgid "Unknown caller" msgstr "" #: indicator/messagingmenu.cpp:263 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:205 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:227 indicator/textchannelobserver.cpp:411 msgid "View message" msgstr "" #: indicator/messagingmenu.cpp:313 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:305 msgid "Voicemail messages" msgstr "" ./po/pt_BR.po0000644000015600001650000001543412677320771013104 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-28 13:48+0000\n" "Last-Translator: Deyvison Rocha \n" "Language-Team: Brazilian Portuguese \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: pt_BR\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 chamada perdida" msgstr[1] "%1 chamadas perdidas" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mensagem de voz" msgstr[1] "%1 mensagens de voz" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 chamadas realizadas hoje" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 chamadas recebidas hoje" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 mensagens de texto recebidas hoje" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 mensagens enviadas hoje" #: approver/approver.cpp:518 msgid "Accept" msgstr "Aceitar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Ligar de volta" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Número não disponível" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Chamando de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Chamando de um número privado" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Chamando de um número desconhecido" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancelar" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Desative o modo de voo e tente novamente a partir do aplicativo de mensagens." #: approver/approver.cpp:540 msgid "Decline" msgstr "Rejeitar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Responder e finalizar" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Segurar + Responder" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Eu perdi sua ligação - você pode me ligar agora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Vou chegar 20 minutos atrasado." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Eu estou ocupado no momento. Vou ligar mais tarde." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Estou ocupado no momento. Te ligo mais tarde." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Estou atrasado, a caminho agora." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Eu estou atrasado. Eu estou a caminho." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Mensagem & Recusar" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mensagem de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Nenhuma chamada realizada hoje" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Nenhuma chamada recebida hoje" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Nenhuma mensagem de texto recebida hoje" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Nenhuma mensagem de texto enviada hoje" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Chamadas telefônicas" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Por favor, me ligue de volta mais tarde." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Por favor, selecione um cartão SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Número privado" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Número privado" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Responder" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Salvar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Enviar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Desculpe, ainda estou ocupado. Te ligo mais tarde." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 minutos gastos em chamadas hoje" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Serviço de telefonia" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprovador do serviço de telefonia" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador do serviço de telefonia" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Não foi possível enviar a mensagem" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Tente novamente a partir do aplicativo de mensagens." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Número desconhecido" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Contato desconhecido" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Número desconhecido" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Desbloquear o cartão SIM e tentar novamente a partir do aplicativo de " "mensagens." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ver mensagem" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Correio de voz" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Mensagens do correio de voz" ./po/ta.po0000644000015600001650000001244012677320771012474 0ustar jenkinsjenkins# Tamil translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-11-29 01:45+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Tamil \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:518 msgid "Accept" msgstr "" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "" ./po/sk.po0000644000015600001650000001541512677320771012512 0ustar jenkinsjenkins# Slovak translation for telephony-service # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2016-03-14 09:55+0000\n" "Last-Translator: P_E_T_O \n" "Language-Team: Slovak \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) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" "X-Launchpad-Export-Date: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: sk\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 zmeškaných hovorov" msgstr[1] "%1 zmeškaný hovor" msgstr[2] "%1 zmeškané hovory" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 hlasových správ" msgstr[1] "%1 hlasová správa" msgstr[2] "%1 hlasové správy" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Počet dnešných hovorov: %1" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Počet dnešných prijatých hovorov: %1" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Počet dnešných prijatých správ: %1" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Počet dnešných odoslaných správ: %1" #: approver/approver.cpp:518 msgid "Accept" msgstr "Prijať" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Zavolať naspäť" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Volané číslo je nedostupné" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Volané z %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Volané zo súkromného čísla" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Volané z neznámeho čísla" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Zrušiť" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Deaktivujte režim Lietadlo a skúste to znova z aplikácie Správy." #: approver/approver.cpp:540 msgid "Decline" msgstr "Odmietnuť" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Ukončiť + Odpovedať" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Podržať + Odpovedať" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Zmeškal som Váš hovor - môžete mi zavolať?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Budem meškať 20 minút." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Som zaneprázdnený. Zavolám neskôr." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Som zaneprázdnený. Zavolám neskôr." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Budem meškať, som na ceste." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Budem meškať. Som na ceste." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Odmietnuť so správou" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Správa od %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Dnes žiadne hovory" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Dnes žiadne prijaté hovory" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Dnes žiadna prijatá správa" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Dnes žiadna odoslaná správa" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Hovory" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Prosím, zavolajte neskôr." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Prosím, vyberte SIM kartu:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Súkromné číslo" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Súkromné číslo" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Odpoveď" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Uložiť" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Poslať" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Prepáčte, som stále zaneprázdnený. Zavolám neskôr." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Dnes strávených minút v hovore: %1" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefónna služba" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Schvaľovateľ telefónnej služby" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indikátor telefónnej služby" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Správa nemohla byť odoslaná" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Skúste to znova z aplikácie Správy." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Neznáme číslo" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Neznámy volajúci" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Neznáme číslo" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Odomknite SIM kartu a skúste to znova z aplikácie Správy." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Zobraziť správu" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Hlasová schránka" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Správy hlasovej schránky" ./po/oc.po0000644000015600001650000001435212677320771012475 0ustar jenkinsjenkins# Occitan (post 1500) translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-20 13:40+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Occitan (post 1500) \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 sonada mancada" msgstr[1] "%1 sonadas mancadas" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 messatge vocal" msgstr[1] "%1 messatges vocals" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 sonadas emesas uèi" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 sonadas recebudas uèi" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 SMS recebuts uèi" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 SMS mandats uèi" #: approver/approver.cpp:518 msgid "Accept" msgstr "Acceptar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Lo numèro de sonada es pas disponible" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Sonada dempuèi %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Sonada dempuèi un numèro privat" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Sonada dempuèi un numèro desconegut" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Anullar" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "Refusar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Demorar en linha + Respondre" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Serai tardièr de 20 minutas." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Soi tardièr. Soi en camin." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Messatge de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Pas cap de sonada emesa uèi" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Pas cap de sonada emesa uèi" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Pas de SMS recebuts uèi" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Pas de SMS recebuts uèi" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "D'acòrdi" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Sonadas telefonicas" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Causissètz una carta SIM :" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Numèro privat" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Numèro privat" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Respondre" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Enregistrar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "O planhi, soi encara ocupat. Vos rapelarai pus tard." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 minutas passadas a sonar uèi" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servici telefonic" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprovador de servici telefonic" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador de servici telefonic" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Lo messatge pòt pas èsser mandat." #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Numèro desconegut" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Sonaire desconegut" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Numèro desconegut" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Veire lo messatge" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Messatjariá Vocala" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "" ./po/sv.po0000644000015600001650000001516512677320771012527 0ustar jenkinsjenkins# 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. # clone , 2015. msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-04-03 05:36+0000\n" "Last-Translator: Josef Andersson \n" "Language-Team: Swedish\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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: sv\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 missat samtal" msgstr[1] "%1 missade samtal" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 röstmeddelande" msgstr[1] "%1 röstmeddelanden" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 samtal gjorda idag" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 samtal mottagna idag" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 textmeddelanden mottagna idag" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 textmeddelanden skickade idag" #: approver/approver.cpp:518 msgid "Accept" msgstr "Acceptera" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Ring upp" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Uppringarens nummer är inte tillgängligt" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Ringer från %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Ringer från dolt nummer" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Ringer från okänt nummer" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Avbryt" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Inaktivera flygläge och prova igen från meddelandeprogrammet." #: approver/approver.cpp:540 msgid "Decline" msgstr "Avvisa" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Avsluta + Svara" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Vänta + Svara" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Jag missade ditt samtal. Kan du ringa mig nu?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Jag kommer 20 minuter försent." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Jag är upptagen för tillfället. Jag ringer upp senare." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Just nu är jag upptagen. Jag ringer dig lite senare." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Jag är sen, men är på väg nu." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Jag är försenad, men jag är på väg." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Meddela och neka" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Meddelande från %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Inga samtal gjorda idag" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Inga samtal mottagna idag" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Inga textmeddelanden mottagna idag" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Inga textmeddelanden skickade idag" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonsamtal" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Ring upp mig senare." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Välj ett SIM-kort:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Dolt nummer" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Dolt nummer" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Svara" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Spara" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Skicka" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Jag är fortfarande upptagen. Ringer dig senare." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Spenderat %1 minuter i samtal idag" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonitjänst" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Godkännare av telefonitjänst" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefonitjänstindikator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Meddelandet kunde inte skickas" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Prova igen från meddelandeprogrammet." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Okänt nummer" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Okänd uppringare" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Okänt nummer" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Lås upp ditt simkort och prova igen från meddelandeprogrammet." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Visa meddelande" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Röstbrevlåda" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Meddelanden på telefonsvararen" ./po/lv.po0000644000015600001650000001557312677320771012523 0ustar jenkinsjenkins# 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. # Rūdolfs Mazurs , 2015. msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-01 07:38+0000\n" "Last-Translator: Rūdolfs Mazurs \n" "Language-Team: Latvian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: lv\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 neatbildēts zvans" msgstr[1] "%1 neatbildēti zvanu" msgstr[2] "%1 neatbildētu zvanu" #: indicator/messagingmenu.cpp:398 #, 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ņu" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Šodien veikti %1 zvani" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Šodien saņemti %1 zvani" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Šodien saņemtas %1 īsziņas" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Šodien nosūtītas %1 īsziņas" #: approver/approver.cpp:518 msgid "Accept" msgstr "Piekrist" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Atzvans" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Zvanītāja numurs nav pieejams" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Zvana no %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Zvanīšana no privātā numura" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Zvanīšana no nezināma numura" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Atcelt" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Izslēdziet lidmašīnas režīmu un mēģiniet vēlreiz no īsziņu lietotnes." #: approver/approver.cpp:540 msgid "Decline" msgstr "Noraidīt" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Beigt + atbildēt" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Aizturēt + atbildēt" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Es palaidu garām tavu zvanu - vai vari man piezvanīt tagad?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Es nokavēšu 20 minūtes." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Pašlaik esmu aizņemts. Piezvanīšu vēlāk." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Pašlaik esmu aizņemts. Piezvanīšu jums vēlāk." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Esmu aizkavējies, jau esmu ceļā." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Es esmu aizkavējies. Es tūlīt būšu." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Sūtīt īsziņu un noraidīt" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Īsziņa no %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Šodien nav veiktu zvanu" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Šodien nav saņemtu zvanu" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Šodien nav saņemtu īsziņu" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Šodien nav sūtītu īsziņu" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Labi" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Tālruņa zvani" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Lūdzu, atzvaniet man vēlāk." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Lūdzu, ievietojiet SIM karti:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Privāts numurs" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Privāts numurs" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Atbildēt" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Saglabāt" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Sūtīt" #: indicator/messagingmenu.cpp:245 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/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Šodien zvanot pavadīju %1 minūtes" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonijas pakalpojumi" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefonijas pakalpojumu apstiprinātājs" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefonijas pakalpojumu indikators" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Šo īsziņu nevarēja nosūtīt" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Mēģiniet vēlreiz no īsziņu lietotnes." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Nezināms numurs" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Nezināms zvanītājs" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Nezināms numurs" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Atbloķējiet savu SIM karti un mēģiniet vēlreiz no īsziņu lietotnes." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Skatīt īsziņu" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Balss pasts" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Balss pasta ziņojumi" ./po/id.po0000644000015600001650000001244512677320771012471 0ustar jenkinsjenkins# Indonesian translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-17 12:32+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Indonesian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:518 msgid "Accept" msgstr "" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "" ./po/ar.po0000644000015600001650000001700112677320771012470 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-07-29 19:24+0000\n" "Last-Translator: Ibrahim Saed \n" "Language-Team: Arabic \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: ar\n" #: indicator/messagingmenu.cpp:299 #, 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:398 #, 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 رسالة صوتية" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 مكالمات تم إجرائها اليوم" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 مكالمات تم استلامها اليوم" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 رسائل نصية تم تلقيها اليوم" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 رسائل نصية تم إرسالها اليوم" #: approver/approver.cpp:518 msgid "Accept" msgstr "أجب" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "معاودة الاتصال" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "رقم المتصل غير متاح حاليا" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "الاتصال من %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "اتصال من رقم خاص" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "اتصال من رقم مجهول" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "ألغِ" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "عطَل وضع الطيران ثم حاول مجددا من تطبيق الرسائل." #: approver/approver.cpp:540 msgid "Decline" msgstr "ارفض" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "لقد فاتني اتصالك ولم أرد عليه - أيمكنك معاودة الاتصال بي الآن؟" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "سأتأخر 20 دقيقة." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "أنا مشغول حاليا. سأتصل بك لاحقا." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "أنا منشغل حاليا. سأتصل بك لاحقا." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "قد أتأخر قليلا. أنا في طريقي إليك." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "رسالة من %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "لا مكالمات تم إجرائها اليوم" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "لا مكالمات تم استلامها اليوم" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "لا رسائل نصية تم تلقيها اليوم" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "لا رسائل نصية تم إرسالها اليوم" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "موافق" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "مكالمات هاتفية" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "رجاءً عاود الاتصال بي لاحقا." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "برجاء اختيار بطاقة SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "رقم خاص" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "رقم خاص" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "رد" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "رسالة قصيرة" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "احفظ" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "إرسال" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "عذرًا، ما زلت منشغلا. سأتصل بك لاحقا." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "تعذر إرسال الرسالة" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "حاول مجددا من تطبيق الرسائل" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "رقم مجهول" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "متصل مجهول" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "رقم مجهول" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "قم بفتح القفل عن بطاقة SIM ثم حاول مجددا من تطبيق الرسائل." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "عرض الرسالة" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "البريد الصوتي" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "رسائل البريد الصوتي" ./po/ko.po0000644000015600001650000001610012677320771012476 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-08-20 04:06+0000\n" "Last-Translator: MinSik CHO \n" "Language-Team: Korean \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: ko\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1개의 부재중 전화" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1개의 음성 메세지" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "오늘 %1통의 전화를 걸었습니다." #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "오늘 %1통의 전화를 받았습니다." #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "오늘 %1개의 텍스트 메시지를 받았습니다." #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "오늘 %1개의 텍스트 메시지를 보냈습니다." #: approver/approver.cpp:518 msgid "Accept" msgstr "승인" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "부재중 번호로 전화" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "발신자 번호를 표시할 수 없습니다" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1에서 전화가 걸러오는 중" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "개인 전용 번호로 전화가 걸려오는 중" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "알 수 없는 번호로 전화가 왔습니다." #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "취소" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "비행 모드를 해제한 후 메시지 프로그램에서 다시 시도해주십시오." #: approver/approver.cpp:540 msgid "Decline" msgstr "거부" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "끝내기 + 받기" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "대기 + 받기" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "전화를 받지 못했습니다. 지금 전화드려도 괜찮으십니까?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20분 정도 늦을 것 같습니다." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "지금은 바쁘니 나중에 다시 걸겠습니다." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "지금 전화를 받을 수 없습니다. 곧 연락드리겠습니다." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "지금 가고 있지만 늦을 것 같습니다." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "조금 늦어서 지금 가고 있습니다." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "메시지 & 거절" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "%1이(가) 보낸 메시지" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "오늘 건 전화가 없습니다." #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "오늘 받은 전화가 없습니다." #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "오늘 받은 텍스트 메시지가 없습니다." #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "오늘 보낸 텍스트 메시지가 없습니다." #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "확인" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "전화 통화" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "나중에 다시 걸어주십시오." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "심 카드를 선택하십시오:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "개인 전용 번호" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "개인 전용 번호" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "답장" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "심 카드 %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "문자 메세지" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "저장" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "보내기" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "죄송합니다. 지금 전화를 받을 수 없습니다. 조금 뒤 전화드리겠습니다." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "오늘 전체 통화 시간은 %1분 입니다." #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "전화 서비스" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "전화 서비스 관리자" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "전화 서비스 확인자" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "메시지를 보낼 수 없습니다." #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "메시지 프로그램에서 다시 시도해주십시오." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "알 수 없는 번호" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "알 수 없는 발신자" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "알 수 없는 번호" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "심 카드의 잠긴 상태를 해제한 후 메시지 프로그램에서 다시 시도해주십시오." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "메세지 보기" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "음성 메일" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "음성 메세지" ./po/hu.po0000644000015600001650000001532412677320771012510 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-06-30 19:08+0000\n" "Last-Translator: Richard Somlói \n" "Language-Team: Hungarian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: hu\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 nem fogadott hívás" msgstr[1] "%1 nem fogadott hívás" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 hangposta üzenet" msgstr[1] "%1 hangposta üzenet" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 hívást indított ma" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 hívást fogadott ma" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 szöveges üzenetet fogadott ma" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 szöveges üzenetet küldött ma" #: approver/approver.cpp:518 msgid "Accept" msgstr "Elfogadás" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Visszahívás" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "A hívó száma nem érhető el" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Hívás innen: %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Hívás rejtett számról" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Hívás ismeretlen számról" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Mégse" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Kapcsolja ki a repülőgépes módot , és próbálja újra az üzenetek " "alkalmazásból." #: approver/approver.cpp:540 msgid "Decline" msgstr "Elutasítás" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Befejez és válaszol" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Várakoztat és válaszol" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Elmulasztottam a hívását. Vissza tudna hívni?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20 percet kések." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Elfoglalt vagyok, később visszahívom." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Fontos dolgom van, később visszahívom." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Már úton vagyok, de késni fogok." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Már úton vagyok, de késni fogok." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Üzenet és elutasítás" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Üzenet tőle: %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Nem indított hívást ma" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Nem fogadott hívást ma" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Nem kapott szöveges üzenetet ma" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Nem küldött szöveges üzenetet ma" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonhívások" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Kérem hívjon vissza később." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Válasszon SIM kártyát:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Rejtett szám" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Rejtett szám" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Válasz" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Mentés" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Küldés" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Még elfoglalt vagyok. Később visszahívom." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 percet telefonált ma" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonszolgáltatás" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefonszolgáltatás jóváhagyó" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefonszolgáltatás indikátor" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Az üzenetet nem sikerült elküldeni" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Próbálja űjra az üzenetek alkalmazásból." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Ismeretlen szám" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Ismeretlen hívó" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Ismeretlen szám" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Oldja fel a SIM kártyáját és próbálja újra az üzenetek alkalmazásból." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Üzenet megtekintése" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Hangposta" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Hangposta üzenetek" ./po/br.po0000644000015600001650000001575112677320771012503 0ustar jenkinsjenkins# Breton translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-13 12:38+0000\n" "Last-Translator: Fohanno Thierry \n" "Language-Team: Breton \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 bellgomzadenn c'hwitet" msgstr[1] "%1 a bellgomzadennoù c'hwitet" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 gemennadenn er voest-komz" msgstr[1] "%1 a gemennadennoù er voest-komz" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 a bellgomzadennoù graet hiziv" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 a bellgomzadennoù resevet hiziv" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 a gemennadennoù testenn resevet hiziv" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 a gemennadennoù testenn kaset hiziv" #: approver/approver.cpp:518 msgid "Accept" msgstr "Asantiñ" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Gervel en-dro" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Ne c'haller ket gervel an niverenn" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "O pellgomz eus %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "O pellgomz eus un niverenn brevez" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "O pellgomz eus un niverenn dianav" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Nullañ" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Diweredekait ar mod nijerez hag esaeit en-dro diwar an arload kemennadennoù." #: approver/approver.cpp:540 msgid "Decline" msgstr "Nac'h" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Echuiñ + Respont" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Lakaat da c'hortoz + Respont" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" "C'hwitet em eus ho pellgomzadenn - ha gallout a rit gervel ac'hanon bremañ ?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20 munut dale a vo ganin." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Dever zo warnon evit bremañ. Pellgomz a rin deoc'h diwezhatoc'h." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Prez zo warnon bremañ. Pellgomz a rin deoc'h diwezhatoc'h." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Diwezhat on, ha war an hent emaon." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Dale zo ganin. War an hent emaon." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Kas ur gemennadenn & nac'h" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Kemennadenn digant %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "N'eus bet graet pellgomzadenn ebet hiziv" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "N'eus bet resevet pellgomzadenn ebet hiziv" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "N'eus bet resevet kemennadenn destenn ebet hiziv" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "N'eus bet kaset kemennadenn destenn ebet hiziv" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Mat eo" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Pellgomzadennoù" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Pellgomzit din en-dro diwezhatoc'h, mar plij." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Diuzit ur gartenn SIM, mar plij :" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Niverenn brevez" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Niverenn brevez" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Respont" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Enrollañ" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Kas" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" "Digarezit ac'hanon, prez zo warnon bepred. Gervel a rin ac'hanoc'h " "diwezhatoc'h." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Tremenet %1 munut ouzh ar pellgomz hiziv" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servij pellgomzerezh" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprouer servij pellgomzerezh" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Merker servij pellgomzerezh" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "N'eus ket bet gallet kas ar gemennadenn" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Esaeit en-dro diwar an arload kemennadennoù" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Niverenn dianav" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Galver dianav" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Niverenn dianav" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Dibrennit ho kartenn SIM hag esaeit en-dro diwar an arload kemennadennoù." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Gwelet ar gemennadenn" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Boest komz" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Kemennadennoù ar voest-komz" ./po/ne.po0000644000015600001650000001476112677320771012502 0ustar jenkinsjenkins# Nepali translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-12-07 14:15+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Nepali \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:518 msgid "Accept" msgstr "स्विकार गर्नुहोस्" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "अज्ञात नम्बर देखि कल" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "रद्द गर्नुहोस्" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "अस्वीकार गर्नुहोस्" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "मैले तपाइको कल छुटाए-के तपाई अब मलाई फोन गर्न सक्नुहुन्छ?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "म २० मिनेट ढिला हुनेछु।" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "म अहिले व्यस्त छु। पछि कल गर्छु।" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "म अहिले व्यस्त छु। तपाइलाई पछि कल गर्छु।" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "आज कुनै कलहरू गरिएन" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "ठिक छ" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "फोन कलहरू" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "कृपया मलाई पछि कल गर्नुहोस्।" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "निजी नम्बर" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "निजी नम्बर" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "जवाफ दिनुहोस्" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "एसएमएस" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "बचत गर्नुहोस्" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "पठाउनुहोस्" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "माफ गर्नुहोस्, म अझै पनि व्यस्त छु। तपाईंलाई पछी कल गर्नेछू।" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "अज्ञात कलर" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "अज्ञात नम्बर" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "संदेश हेर्नुहोस्" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "भ्वाइसमेल" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "" ./po/my.po0000644000015600001650000001515012677320771012516 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-07-29 19:29+0000\n" "Last-Translator: PS Jenkins bot \n" "Language-Team: Burmese \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: my\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 လွတ်သွားသောခေါ်ဆိုမှု့" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 အသံ message" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:518 msgid "Accept" msgstr "လက်ခံ" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "ခေါ်ဆိုသည့်နံပါတ်မှာမရရှိနိုင်ပါ" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1 မှခေါ်နေသည်" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "လျှို့ဝှက်နံပါတ်မှခေါ်နေသည်" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "မသိရှိသောနံပါတ်မှခေါ်နေသည်" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "ပယ်ဖျက်မည်" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "ငြင်းပယ်" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "ကျွန်ုပ်သင်၏ခေါ်ဆိုမှု့ကိုမကိုင်မိပါ။ အခုပြန်လည်ခေါ်ဆိုနိုင်သလား။" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "ကျွန်ုပ် မိနစ် ၂၀ နောက်ကျမည်" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "ကျွန်ုပ်ယခုအလုပ်များနေသည်။နောက်မှ ပြန်လည်ခေါ်ဆိုလိုက်မည်" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "ကျွန်ုပ်သွားတာနောက်ကျနေပြီ။လမ်းတွင်ရောက်နေပြီ။" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "ဖုန်းခေါ်ဆိုမည်" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "စာတိုပို့စနစ်" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "သိမ်းမည်" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "ဆောရီး၊ အလုပ်များနေသေးသည်။ နောက်မှပြန်ခေါ်လိုက်မည်" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "မသိသောခေါ်ဆိုသူ" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "အသံနှင့်စာများ" ./po/sl.po0000644000015600001650000001561012677320771012510 0ustar jenkinsjenkins# Slovenian translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-25 09:39+0000\n" "Last-Translator: Dražen Matešić \n" "Language-Team: Slovenian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || " "n%100==4 ? 3 : 0);\n" "X-Launchpad-Export-Date: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 zgrešenih klicev" msgstr[1] "%1 zgrešen klic" msgstr[2] "%1 zgrešena klica" msgstr[3] "%1 zgrešeni klici" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 glasovnih sporočil" msgstr[1] "%1 glasovno sporočilo" msgstr[2] "%1 glasovni sporočili" msgstr[3] "%1 glasovna sporočila" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 današnjih opravljenih klicev" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 danes prejetih klicev" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 danes prejetih besedilnih sporočil" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 danes poslanih besedilnih sporočil" #: approver/approver.cpp:518 msgid "Accept" msgstr "Sprejmi" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Povratni klic" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Številka klicatelja ni na voljo" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Klic od %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Klic od zasebne številke" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Klic od neznane številke" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Prekliči" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Onemogočite letalski način ter poskusite znova iz programa sporočanja." #: approver/approver.cpp:540 msgid "Decline" msgstr "Zavrni" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Končaj + Odgovori" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Zadrži + Odgovori" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Zgrešil sem tvoj klic - me lahko pokličeš zdaj?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Zamudil bom 20 minut." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Trenutno sem zaseden. Pokličem kasneje." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Trenutno sem zaseden. Poklical te bom kasneje." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Pozen sem, sem že na poti" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Zamujam. Sem že na poti." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Sporoči in zavrni" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Sporočilo od %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Danes ni bilo opravljenih klicev" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Danes ni bilo prejetih klicev" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Danes ni bilo prejetih besedilnih sporočil" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Danes ni bilo poslanih besedilnih sporočil" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "V redu" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonski klici" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Kasneje me prosim pokliči nazaj." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Izberite kartico SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Zasebna številka" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Zasebna številka" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Odgovori" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Shrani" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Pošlji" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Oprosti, še vedno sem zaseden. Poklical te bom kasneje." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 danes porabljenih minut za klice" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonska storitev" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Odobritelj telefonske storitve" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Kazalnik telefonske storitve" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Tega sporočila ni bilo mogoče poslati" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Poskusite znova iz programa za sporočanje." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Neznana številka" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Neznan klicatelj" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Neznana številka" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Odklenite kartico sim ter poskusite znova iz programa za sporočanje." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ogled sporočila" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Glasovna pošta" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Sporočila glasovne pošte" ./po/cy.po0000644000015600001650000001515112677320771012505 0ustar jenkinsjenkins# Welsh translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-07-19 22:43+0000\n" "Last-Translator: Owen Llywelyn \n" "Language-Team: Welsh \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==2 ? 1 : (n != 8 && n != 11) ? " "2 : 3;\n" "X-Launchpad-Export-Date: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "Methwyd %1 galwad" msgstr[1] "Methwyd %1 galwad" msgstr[2] "Methwyd %1 galwad" msgstr[3] "Methwyd %1 galwad" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 neges llais" msgstr[1] "%1 neges llais" msgstr[2] "%1 neges llais" msgstr[3] "%1 neges llais" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Gwnaed %1 galwad heddiw" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Derbyniwyd %1 galwad heddiw" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Derbyniwyd %1 neges destun heddiw" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Anfonwyd %1 neges destun heddiw" #: approver/approver.cpp:518 msgid "Accept" msgstr "Derbyn" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Galw nôl" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Rhif galw ddim ar gael" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Yn galw o %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Yn galw o rif preifat" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Yn galw o rif anhysbys" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Diddymu" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Dadweithredu modd hedfan a cheisio eto o'r ap negeseuon." #: approver/approver.cpp:540 msgid "Decline" msgstr "Gwrthod" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Gorffen + Ateb" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Dal + Ateb" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Methais eich galwad - allwch chi alw nawr?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Byddaf 20 munud yn hwyr." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Rwy'n brysur nawr. Ffonia i wedyn." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Rwy'n brysur nawr. Ffonia i wedyn." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Rwy'n hwyr ond ar fy ffordd nawr." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Rwy'n hwyr ond ar fy ffordd." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Anfon neges & gwrthod" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Anfon neges o %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Heb wneud galwad heddiw." #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Heb dderbyn galwad heddiw." #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Heb dderbyn neges destun heddiw." #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Heb anfon neges destun heddiw." #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Iawn" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Galwadau Ffôn" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Ffoniwch fi wedyn." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Dewiswch gerdyn SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Rhif Preifat" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Rhif preifat" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Ateb" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Cadw" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Anfon" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Rwy'n brysur ac fe ffonia i wedyn." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Treuliwyd %1 munud ar alwadau heddiw" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Gwasanaeth Teleffoni" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Darparwr Gwasanaeth Teleffoni" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Dangosydd Gwasanaeth Teleffoni" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Methwyd anfon y neges" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Ceisiwch eto o'r ap negeseuon." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Rhif Anhysbys" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Galwr anhysbys" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Rhif anhysbys" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Datglowch eich cerdyn SIM a cheisiwch eto o'r ap negeseuon." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Gweld neges" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Neges llais" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Negeseuon llais" ./po/it.po0000644000015600001650000001531512677320771012510 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-04-22 07:01+0000\n" "Last-Translator: alexisme \n" "Language-Team: Italian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: it\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 chiamata persa" msgstr[1] "%1 chiamate perse" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 messaggio in segreteria" msgstr[1] "%1 messaggi in segreteria" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Chiamate fatte oggi %1" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Chiamate ricevute oggi %1" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Messaggi di testo ricevuti oggi %1" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Messaggi di testo inviati oggi %1" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accetta" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Richiama" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Numero chiamante non disponibile" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Chiamata da %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Chiamata da numero privato" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Chiamata da numero sconosciuto" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Annulla" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Disattivare la modalità aereo e riprovare dall'app dei messaggi." #: approver/approver.cpp:540 msgid "Decline" msgstr "Rifiuta" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Termina + Rispondi" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Tenere premuto + risposta" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Ho perso la tua chiamata. Puoi richiamarmi ora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Sarò in ritardo di 20 minuti." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Sono momentaneamente occupato/a. Richiamerò più tardi." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Sono momentaneamente occupato/a. Ti richiamerò più tardi." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Sono in ritardo, sto arrivando!" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Sono in ritardo. Sto per arrivare." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Messaggio e rifiuta" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Messaggio da %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Nessuna chiamata effettuata oggi" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Nessuna chiamata ricevuta oggi" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Nessun messaggio di testo ricevuto oggi" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Nessun messaggio di testo inviato oggi" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Chiamate telefoniche" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Per cortesia richiamami più tardi." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Selezionare una scheda SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Numero privato" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Numero privato" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Rispondi" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Salva" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Invia" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Mi dispiace, sono ancora occupato/a. Ti richiamerò più tardi." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Effettuati %1 minuti di chiamate oggi" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servizio di telefonia" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Servizio di telefonia" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicatore servizio di telefonia" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Impossibile inviare il messaggio" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Riprivare dall'app dei messaggi." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Numero sconosciuto" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Chiamante sconosciuto" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Numero sconosciuto" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Sbloccare la scheda SIM e riprovare dall'app dei messaggi." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Vedi messaggio" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Segreteria" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Messaggi in segreteria" ./po/gd.po0000644000015600001650000001650112677320771012464 0ustar jenkinsjenkins# Gaelic; Scottish translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # GunChleoc , 2014. msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-27 00:54+0000\n" "Last-Translator: Akerbeltz \n" "Language-Team: Fòram na Gàidhlig\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : " "(n > 2 && n < 20) ? 2 : 3;\n" "X-Launchpad-Export-Date: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: gd\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "Chaill thu %1 ghairm" msgstr[1] "Chaill thu %1 ghairm" msgstr[2] "Chaill thu %1 gairmean" msgstr[3] "Chaill thu %1 gairm" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 teachdaireachd gutha" msgstr[1] "%1 theachdaireachd gutha" msgstr[2] "%1 teachdaireachd angutha" msgstr[3] "%1 teachdaireachd gutha" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Chaidh %1 gairmean a chur an-diugh" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Chaidh %1 gairmean fhaighinn an-diugh" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Chaidh %1 teachdaireachdan fhaighinn an-diugh" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Chaidh %1 teachdaireachdan a chur an-diugh" #: approver/approver.cpp:518 msgid "Accept" msgstr "Freagair" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Fònaig air ais" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Chan eil fhios dè àireamh a tha aig an neach eile" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Fòn o %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Fòn o àireamh phrìobhaideach" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Fòn o àireamh nach aithne dhuinn" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Sguir dheth" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Cuir am modh itealain à comas is feuch ris a-rithist o aplacaid nan " "teachdaireachdan." #: approver/approver.cpp:540 msgid "Decline" msgstr "Diùlt" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Crìochnaich + Freagair" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Cum ⁊ freagair" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Chaill mi do ghairm - an cuir thu fòn air ais thugam an-dràsta?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Bidh mi fadalach 20 mionaidean" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Tha mi trang an-dràsta fhèin. Bruidhnidh mi riut an ceann greis." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Tha mi trang an-dràsta fhèin. Cuiridh mi fòn air ais thugad." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Tha mi fadalach ach air an t-slighe a-nis." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Tha mi fadalach ach air an t-slighe." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Teachdaireachd ⁊ diùlt" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Teachdaireachd o %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Cha do chuireadh gairm an-diugh" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Cha d' fhuaireadh gairm an-diugh" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Cha d' fhuaireadh teachdaireachd an-diugh" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Cha do chuireadh teachdaireachd an-diugh" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ceart ma-thà" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Gairmean fòn" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Saoil an cuir thu fòn air ais thugam an ceann greis?" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Tagh cairt SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Àireamh phrìobhaideach" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Àireamh phrìobhaideach" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Freagair" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Sàbhail" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Cuir" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" "Tha mi duilich, tha mi trang fhathast. Cuiridh mi fòn air ais thugad as a " "dhèidh seo." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Chuireadh seachad %1 mionaidean ann an gairmean an-diugh" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Seirbheis fòn" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aontaichear na seirbheise fòn" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Taisbeanair na seirbheise fòn" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Cha b' urrainn dhuinn an teachdaireachd a chur" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Feuch ris a-rithist o aplacaid nan teachdaireachdan." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Àireamh nach aithne dhuinn" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Chan eil fhios cò tha fònadh" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Àireamh nach aithne dhuinn" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Thoir a' ghlas far na cairt SIM agad is feuch ris a-rithist o aplacaid nan " "teachdaireachdan." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Seall an teachdaireachd" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Post-gutha" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Teachdaireachdan gutha" ./po/km.po0000644000015600001650000001725412677320771012507 0ustar jenkinsjenkins# Khmer translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-09-01 10:08+0000\n" "Last-Translator: Sophea Sok \n" "Language-Team: Khmer \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "ខកខាន​ទទួល %1" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "សារ​ជា​សំឡេង %1" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "ថ្ងៃនេះ​បាន​ហៅ %1 ដង" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "ថ្ងៃនេះ​បាន​ទទួល​ការ​ហៅ​ចូល %1 ដង" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "ថ្ងៃនេះ​បាន​ទទួល​សារ %1" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "ថ្ងៃនេះ​បាន​ផ្ញើ​សារ %1" #: approver/approver.cpp:518 msgid "Accept" msgstr "ព្រម​ទទួល" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "មិន​មាន​លេខ​អ្នក​ហៅ" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "កំពុង​ហៅ​ពី %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "កំពុង​ហៅ​ពី​លេខ​ឯកជន" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "កំពុង​ហៅ​ពី​លេខ​មិន​ស្គាល់" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "បោះបង់" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "បដិសេធ" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "ចុច​ជាប់ + ឆ្លើយ" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" "ខ្ញុំមិន​បាន​ទទួលការ​ហៅ​របស់​អ្នក- តើ​អ្នក​អាច​ហៅ​មក​ខ្ញុំ​ឥឡូវ​បាន​ទេ?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "ខ្ញុំ​នឹង​យឺត ២០នាទី។" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "ខ្ញុំ​រវល់​ណាស់​ពេល​នេះ។ ខ្ញុំ​នឹង​ហៅ​អ្នក​ពេល​ក្រោយ។" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "ខ្ញុំ​យឺត​ហើយ។ ខ្ញុំ​នៅ​តាម​ផ្លូវ។" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "សារ​ពី %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "ថ្ងៃនេះ​មិន​បាន​ហៅ" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "ថ្ងៃនេះ​មិន​បាន​ទទួល​ការ​ហៅ" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "ថ្ងៃនេះ​មិន​បាន​ទទួល​សារ​អត្ថបទ" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "ថ្ងៃនេះ​មិន​បាន​ផ្ញើ​សារ" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "យល់ព្រម" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "ការ​ហៅ​ទូរស័ព្ទ" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "សូមជ្រើសស៊ី​ម​កាត ៖" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "លេខ​ឯកជន" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "លេខ​ឯកជន" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "ឆ្លើយតប" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "ស៊ីម %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "សារ SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "រក្សា​ទុក" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "សូម​ទោស ខ្ញុំ​កំពុង​រវល់។ ខ្ញុំ​នឹង​ហៅ​ទៅ​អ្នក​ពេល​ក្រោយ។" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "ថ្ងៃនេះ​អ្នក​បាន​ហៅ %1 នាទី" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "សេវាកម្ម​ទូរស័ព្ទ" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "ក្រុមហ៊ុន​អនុម័ត​សេវាកម្ម​ទូរស័ព្ទ" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "សូចនាករ​សេវាកម្ម​ទូរស័ព្ទ" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "មិន​ស្គាល់​លេខ" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "មិន​ស្គាល់​អ្នក​ហៅ" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "មិន​ស្គាល់​លេខ" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "មើល​សារ" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "សារ​ជា​សំឡេង" ./po/el.po0000644000015600001650000001753612677320771012503 0ustar jenkinsjenkins# Greek translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-31 14:02+0000\n" "Last-Translator: tzem \n" "Language-Team: Greek \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 αναπάντητη κλήση" msgstr[1] "%1 αναπάντητες κλήσεις" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 μήνυμα στον τηλεφωνητή" msgstr[1] "%1 μηνύματα στον τηλεφωνητή" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 κλήσεις έγιναν σήμερα" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 κλήσεις δεχτήκατε σήμερα" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 μηνύματα ελήφθησαν σήμερα" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 μηνύματα στάλθηκαν σήμερα" #: approver/approver.cpp:518 msgid "Accept" msgstr "Αποδοχή" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Επανάκληση" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Ο αριθμός που καλείτε δεν είναι διαθέσιμος" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Κλήση από %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Κλήση από αριθμό με απόκρυψη" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Κλήση από άγνωστο αριθμό" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Ακύρωση" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Απενεργοποιείστε την λειτουργία πτήσης και προσπαθήστε ξανά από την εφαρμογή " "μηνυμάτων." #: approver/approver.cpp:540 msgid "Decline" msgstr "Απόρριψη" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Τέλος + Απάντηση" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Αναμονή + Απάντηση" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Δεν πρόλαβα την κλήση σου μπορείς να καλέσεις τώρα;" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Θα καθυστερήσω 20 λεπτά." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Είμαι απασχολημένος αυτή την στιγμή. Θα καλέσω αργότερα." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Είμαι απασχολημένος αυτή την στιγμή. Θα σε καλέσω αργότερα." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Καθυστέρησα λιγάκι. Έρχομαι τώρα." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Καθυστέρησα λιγάκι. Έρχομαι." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Μήνυμα & απόρριψη" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Μήνυμα από %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Δεν έγιναν κλήσεις σήμερα" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Δεν ελήφθησαν κλήσεις σήμερα" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Δεν ελήφθησαν μηνύματα σήμερα" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Δεν στάλθηκαν μηνύματα σήμερα" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Εντάξει" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Κλήσεις" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Παρακαλώ καλέστε με αργότερα." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Παρακαλώ επιλέξτε κάρτα SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Με απόκρυψη" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Με απόκρυψη" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Απάντηση" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "Κάρτα SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Αποθήκευση" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Αποστολή" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Συγνώμη είμαι ακόμη απασχολημένος. Θα σε καλέσω αργότερα." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Μιλήσατε %1 λεπτά σήμερα" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Υπηρεσία τηλεφωνίας" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Υποστήριξη τηλεφωνικής υπηρεσίας" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Ένδειξη τηλεφωνικής υπηρεσίας" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Το μήνυμα δεν μπόρεσε να σταλεί" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Προσπαθήστε ξανά από την εφαρμογή μηνυμάτων." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Άγνωστος Αριθμός" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Άγνωστος" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Άγνωστος Αριθμός" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Ξεκλειδώστε την κάρτα sim σας και προσπαθήστε ξανά από την εφαρμογή " "μηνυμάτων." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Προβολή μηνύματος" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Τηλεφωνητής" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Μηνύματα τηλεφωνητή" ./po/sr.po0000644000015600001650000001741012677320771012516 0ustar jenkinsjenkins# Serbian translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2016-03-04 15:24+0000\n" "Last-Translator: Данило Шеган \n" "Language-Team: Serbian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 пропуштен позив" msgstr[1] "%1 пропуштена позива" msgstr[2] "%1 пропуштених позива" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 говорна порука" msgstr[1] "%1 говорне поруке" msgstr[2] "%1 говорних порука" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Данас је направљено %1 позива" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Данас је примљено %1 позива" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Данас је примљено %1 текстуалних порука" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Данас је послато %1 текстуалних порука" #: approver/approver.cpp:518 msgid "Accept" msgstr "Прихвати" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Узврати позив" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Број позиваоца није доступан" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Зове са %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Позив са скривеног броја" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Позив са непознатог броја" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Откажи" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Искључите режим у авиону и покушајте поново из програма за поруке." #: approver/approver.cpp:540 msgid "Decline" msgstr "Одбиј" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Заврши и Одговори" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Задржи и одговори" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Пропустио сам твој позив — можеш ли ме сада позвати?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Касним 20 минута." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Тренутно сам заузет. Назваћу касније." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Тренутно сам заузет. Назваћу вас касније." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Касним, на путу сам." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Касним. На путу сам." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Поручи и одбиј" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Поруку шаље %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Данас није било позива" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Данас нема примљених позива" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Данас нема примљених порука" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Данас није било послатих порука" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "У реду" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Телефонски позиви" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Назовите ме касније." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Изаберите СИМ картицу:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Скривени број" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Скривени број" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Одговори" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "СИМ %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "СМС" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Сачувај" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Пошаљи" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Извините, и даље сам заузет. Назваћу вас касније." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Данас сте потрошили %1 минута на позиве" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Услуга телефонирања" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Одобравање услуге телефонирања" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Индикатор услуге телефонирања" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Не могу да пошаљем поруку" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Покушајте поново из програма за поруке." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Непознат број" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Непознат позивалац" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Непознат број" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Откључајте сим картицу и покушајте поново из програма за поруке." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Погледај поруку" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Говорна пошта" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Поруке говорне поште" ./po/ms.po0000644000015600001650000001537112677320771012515 0ustar jenkinsjenkins# Malay translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-10-22 09:26+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Malay \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 panggilan terlepas" msgstr[1] "%1 panggilan terlepas" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 panggilan mel bersuara" msgstr[1] "%1 panggilan mel bersuara" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Panggilan %1 dibuat hari ini" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Panggilan %1 diterima hari ini" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Mesej teks %1 diterima hari ini" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Mesej teks %1 dihantar hari ini" #: approver/approver.cpp:518 msgid "Accept" msgstr "Terima" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Panggilan semula" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Nombor pemanggil tidak tersedia" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Panggilan daripada %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Panggilan dari nombor persendirian" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Panggilan dari nombor tidak diketahui" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Batal" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Nyahaktifkan mod penerbangan dan cuba lagi dari aplikasi pemesejan." #: approver/approver.cpp:540 msgid "Decline" msgstr "Tolak" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Tamat + Jawab" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Tangguh + Jawab" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Saya terlepas panggilan anda - boleh anda telefon saya sekarang?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Saya akan terlambat 20 minit." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Saya sibuk pada masa ini. Saya akan menghubungi kemudian." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Saya sibuk buat masa ini. Saya akan telefon anda kemudian." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Saya terlambat, dalam perjalanan sekarang." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Saya terlewat. Saya masih dalam perjalanan." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Mesej & abai" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mesej daripada %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Tiada panggilan dibuat hari ini" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Tiada panggilan diterima hari ini" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Tiada mesej teks diterima hari ini" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Tiada mesej teks dihantar hari ini" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Panggilan Telefon" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Sila hubungi saya semula." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Sila, pilih satu kad SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Nombor Persendirian" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Nombor persendirian" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Balas" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Simpan" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Hantar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Maaf, Saya masih sibuk. Saya akan telefon anda nanti." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Guna sebanyak %1 miniy panggilan hari ini" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Perkhidmatan Telefoni" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Approver Perkhidmatan Telefoni" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Penunjuk Perkhidmatan Telefoni" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Mesej tidak dapat dihantar" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Cuba lagi menerusi aplikasi pemesejan." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Nombor Tidak Diketahui" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Pemanggil tidak diketahui" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Nombor tidak diketahui" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Nyahsekat kad sim anda dan cuba lagi melalui aplikasi pemesejan." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Lihat mesej" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Mel bersuara" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Mesej mel bersuara" ./po/da.po0000644000015600001650000001361612677320771012462 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-08-03 02:46+0000\n" "Last-Translator: Ask Hjorth Larsen \n" "Language-Team: Danish \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: da\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 ubesvaret opkald" msgstr[1] "%1 ubesvarede opkald" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 talemeddelelse" msgstr[1] "%1 talemeddelelser" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:518 msgid "Accept" msgstr "Godkend" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Ophavsnummeret er ikke tilgængeligt" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Ringer fra %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Ringer fra privat nummer" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Ringer fra ukendt nummer" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Annullér" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "Afvis" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Ventetilstand + besvar" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Jeg fik ikke besvaret dit opkald - kan du ringe til mig nu?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Jeg vil være 20 minutter forsinket." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Jeg har travlt i øjeblikket. Jeg ringer til dig senere." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Jeg bliver forsinket men er på vej." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "O.k." #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonopkald" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Privat nummer" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Svar" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Gem" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Undskyld, jeg er stadig optaget. Jeg ringer til dig senere." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefontjeneste" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefontjenestegodkender" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefontjenesteindikator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Ukendt nummer" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Ukendt person" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Vis besked" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Talemeddelelser" ./po/eu.po0000644000015600001650000001517212677320771012506 0ustar jenkinsjenkins# Basque translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-22 21:45+0000\n" "Last-Translator: Ibai Oihanguren Sala \n" "Language-Team: Basque \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "dei galdu %1" msgstr[1] "%1 dei galdu" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "ahots-mezu %1" msgstr[1] "%1 ahots-mezu" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 dei egin dituzu gaur" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 dei jaso dituzu gaur" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 testu-mezu jaso dituzu gaur" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 testu-mezu bidali dituzu gaur" #: approver/approver.cpp:518 msgid "Accept" msgstr "Onartu" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Itzuli deia" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Deitzailearen zenbakia ez dago eskuragarri" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1 zenbakitik deika" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Zenbaki pribatutik deika" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Zenbaki ezezagunetik deika" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Utzi" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Desaktibatu hegaldi modua eta saiatu berriz mezularitza aplikaziotik." #: approver/approver.cpp:540 msgid "Decline" msgstr "Baztertu" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Amaitu + Erantzun" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Itxaron + Erantzun" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Zure deia galdu dut - orain berriro deitzerik bai?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20 minutu berandu iritsiko naiz." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Orain lanpetuta nago. Deituko dizut geroago." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Une honetan lanpetuta nago. Gero deituko dizut." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Berandutu egin zait, bidean naiz." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Berandutu egin zait. Bidean naiz." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Mezua bidali eta baztertu" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "%1(r)en mezua" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Gaur ez duzu deirik egin" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Gaur ez duzu deirik jaso" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Gaur ez duzu testu-mezurik jaso" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Gaur ez duzu testu-mezurik bidali" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ados" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefono-deiak" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Dei nazazu berriro geroago, mesedez." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Hautatu SIM txartel bat:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Zenbaki pribatua" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Zenbaki pribatua" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Erantzun" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMSa" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Gorde" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Bidali" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Sentitzen dut, oraindik lanpetuta nago. Gero deituko dizut." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Gaur %1 minutu pasa dituzun deietan" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefonia-zerbitzua" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefonia-zerbitzuaren oneslea" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefonia-zerbitzuaren adierazlea" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Mezua ezin izan da bidali" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Saiatu berriz mezularitza aplikaziotik." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Zenbaki ezezaguna" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Deitzaile ezezaguna" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Zenbaki ezezaguna" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Desblokeatu SIM txartela eta saiatu berriz mezularitza aplikaziotik." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ikusi mezua" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Ahots-posta" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Ahots-mezuak" ./po/tr.po0000644000015600001650000001471312677320771012522 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-03-22 15:38+0000\n" "Last-Translator: Arda Ünlü \n" "Language-Team: Turkish \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: tr\n" #: indicator/messagingmenu.cpp:299 #, 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:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 sesli mesaj" msgstr[1] "%1 sesli mesaj" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1, çağrılar yaptı" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Bugün %1 çağrı alındı" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Bugün %1 mesaj alındı" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Bugün %1mesaj gönderildi." #: approver/approver.cpp:518 msgid "Accept" msgstr "Kabul Et" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Geri ara" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Arayan numarası kullanılamıyor" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1 kişisinden arama" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Özel numaradan arıyor" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Bilinmeyen numaradan arıyor" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "İptal" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Uçak kipini devre dışı bırakın ve mesajlaşma uygulamasından tekrar deneyin." #: approver/approver.cpp:540 msgid "Decline" msgstr "Reddet" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Bitir + Yanıtla" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Basılı tut + Yanıtla" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Telefona yetişemedim - beni şimdi arar mısın?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20 dakika geç kalacağım." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Şuanda meşgulüm. Daha sonra arayacağım." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Şu anda meşgulüm. Seni sonra arayacağım." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Geç kalıyorum, yoldayım." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Geç kalıyorum. Yoldayım." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "%1 kişisinden mesaj" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Bugün çağrı yapılmadı" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Bugün çağrı alınmadı" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Bugün mesaj alınmadı" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Bugün mesaj gönderilmedi" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Tamam" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefon Çağrıları" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Lütfen beni tekrar arayın." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Lütfen bir SIM kart seçin:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Özek Numara" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Özel numara" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Yanıtla" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Kaydet" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Gönder" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Üzgünüm, hala meşgulüm. Seni sonra arayacağım." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Bugün konuşmalarda %1 dakika harcandı" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Mesaj gönderilemedi" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Mesajlaşma uygulamasından tekrar deneyin." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Bilinmeyen Numara" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Bilinmeyen arayan" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Bilinmeyen numara" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Mesajı göster" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Sesli mesaj" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Telesekreter mesajları" ./po/hr.po0000644000015600001650000001535512677320771012511 0ustar jenkinsjenkins# Croatian translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-10-16 10:35+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Croatian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 propušteni poziv" msgstr[1] "%1 propuštena poziva" msgstr[2] "%1 propuštenih poziva" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 glasovna poruka" msgstr[1] "%1 glasovne poruke" msgstr[2] "%1 glasovnih poruka" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 današnji pozivi" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 jučerašnji pozivi" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 danas primljene poruke" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 danas poslane poruke" #: approver/approver.cpp:518 msgid "Accept" msgstr "Prihvati" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Uzvrati poziv" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Broj pozivatelja nije dostupan" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Poziv od %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Poziv od privatnog broja" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Poziv od nepoznatnog broja" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Odustani" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Isključite način rada u zrakoplovu i pokušajte ponovno iz aplikacije za " "poruke." #: approver/approver.cpp:540 msgid "Decline" msgstr "Odbaci" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Završi + Poziv" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Zadrži + Poziv" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Propustio sam vaš poziv, želite li me sada nazvati?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Kasnit ću 20 minuta." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Trenutno sam zaposlen. Nazvat ću vas kasnije." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Trenutno sam zauzet. Nazvat ću vas kasnije." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Kasnim, na putu sam." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Kasnim, na putu sam." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Poruke i otkazivanje" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Poruka od %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Danas nema ostvarenih poziva" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Danas nema dolaznih poziva" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Danas nema primljenih poruka" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Danas nema poslanih poruka" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "U redu" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Telefonski pozivi" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Nazovite me natrag kasnije." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Odaberite SIM karticu:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Privatni broj" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Privatan broj" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Odgovori" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Spremi" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Pošalji" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Isprika, Još sam zauzet. Nazvat ću vas kasnije." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Potrošeno %1 minuta na pozive danas" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Usluga telefoniranja" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Pružatelj telefonskih usluga" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Pokazatelj telefonskih usluga" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Tekstovna poruka ne može biti poslana" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Pokušajte kasnije iz aplikacije za poruke" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Nepoznat broj" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Nepoznat pozivatelj" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Nepoznat broj" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Otključajte svoju SIM karticu i pokušajte ponovno iz aplikacije za poruke." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Pogledaj poruku" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Govorna pošta" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Poruke govorne pošte" ./po/is.po0000644000015600001650000001441212677320771012504 0ustar jenkinsjenkins# Icelandic translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-09-15 08:20+0000\n" "Last-Translator: Sveinn í Felli \n" "Language-Team: Icelandic \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 ósvarað símtal" msgstr[1] "%1 ósvöruð símtöl" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 talskilaboð" msgstr[1] "%1 talskilaboð" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 símtöl héðan í dag" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 símtöl móttekin í dag" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 textaskilaboð móttekin í dag" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 textaskilaboð send í dag" #: approver/approver.cpp:518 msgid "Accept" msgstr "Samþykkja" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Númer símnotanda ekki tiltækt" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Hringir úr %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Hringir úr leyninúmeri" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Hringir úr óþekktu númeri" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Hætta við" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "Hafna" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Halda + Svara" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Ég missti af því þegar þú hringdir - geturðu hringt núna?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Ég verð 20 mínútum of seinn." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Ég er upptekinn í augnablikinu. Hringi í þig síðar." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Er að verða of seinn. Kem innan skamms." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Skilaboð frá %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Engin símtöl héðan í dag" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Engin textaskilaboð móttekin í dag" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Engin símtöl móttekin í dag" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Engin textaskilaboð send í dag" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Í lagi" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Símtöl" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Leyninúmer" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Leyninúmer" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Svara" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Vista" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Ég er ennþá upptekinn. Hringi í þig síðar." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Alls %1 mínútur í símtöl í dag" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Símaþjónusta" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Umsjón símaþjónustu" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Vaktari símaþjónustu" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Óþekkt númer" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Óþekktur símnotandi" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Óþekkt númer" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Skoða skilaboð" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Talskilaboð" ./po/en_AU.po0000644000015600001650000001503712677320771013064 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-25 05:46+0000\n" "Last-Translator: Jared Norris \n" "Language-Team: English (Australia) \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: \n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 missed call" msgstr[1] "%1 missed calls" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 voicemail message" msgstr[1] "%1 voicemail messages" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 calls made today" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 calls received today" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 text messages received today" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 text messages sent today" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accept" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Call back" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Caller number is not available" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Calling from %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Calling from private number" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Calling from unknown number" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancel" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Deactivate flight mode and try again from the messaging application." #: approver/approver.cpp:540 msgid "Decline" msgstr "Decline" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "End + Answer" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Hold + Answer" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "I missed your call - can you call me now?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "I'll be 20 minutes late." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "I'm busy at the moment. I'll call later." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "I'm busy at the moment. I'll call you later." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "I'm running late, on my way now." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "I'm running late. I'm on my way." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Message & decline" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Message from %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "No calls made today" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "No calls received today" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "No text messages received today" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "No text messages sent today" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Phone Calls" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Please call me back later." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Please, select a SIM card:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Private Number" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Private number" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Reply" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Save" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Send" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Sorry, I'm still busy. I'll call you later." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Spent %1 minutes in calls today" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telephony Service" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telephony Service Approver" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telephony Service Indicator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "The message could not be sent" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Try again from the messaging application." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Unknown Number" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Unknown caller" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Unknown number" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Unlock your sim card and try again from the messaging application." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "View message" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Voicemail" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Voicemail messages" ./po/uk.po0000644000015600001650000002052312677320771012510 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-12-10 14:46+0000\n" "Last-Translator: Yakubovsky Dmitriy(Якубовський Д.) \n" "Language-Team: Ukrainian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: uk\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 пропущений дзвінок" msgstr[1] "%1 пропущені дзвінки" msgstr[2] "%1 пропущених дзвінків" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 голосове повідомлення" msgstr[1] "%1 голосових повідомлення" msgstr[2] "%1 голосових повідомлень" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Сьогодні здійснено %1 дзвінки" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Сьогодні отримано %1 дзвінки" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Сьогодні отримано %1 текстових повідомлень" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Сьогодні надіслано %1 текстових повідомлень" #: approver/approver.cpp:518 msgid "Accept" msgstr "Прийняти" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Зворотній виклик" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Номер вхідного дзвінка недоступний" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Дзвінок від %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Дзвінок з приватного номера" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Дзвінок з невідомого номера" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Скасувати" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Вимкніть режим польоту і повторіть спробу за допомогою програми для роботи з " "повідомленнями." #: approver/approver.cpp:540 msgid "Decline" msgstr "Відхилити" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Завершити + Відповісти" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Утримання + Відповідь" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Мною пропущено Ваш дзвінок. Можете передзвонити?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Буду за 20 хвилин." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Зараз немає часу. Відповім пізніше." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Зараз не можу поговорити. Передзвоню пізніше." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Запізнююся, зараз у дорозі." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Запізнююся. У дорозі." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Повідомити і відхилити" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Повідомлення від %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Сьогодні вихідних дзвінків не було" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Сьогодні вхідних дзвінків не було" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Сьогодні текстових повідомлень не надходило" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Сьогодні текстових повідомлень не надсилалося" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Гаразд" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Телефонні дзвінки" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Будь ласка, передзвоніть пізніше." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Будь ласка, виберіть SIM-картку:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Особистий номер" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Особистий номер" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Відповісти" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "СМС" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Зберегти" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Надіслати" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Вибачте, не можу звільнитися. Передзвоню пізніше." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Сьогодні загальна тривалість дзвінків - %1 хвилин" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Служба телефонії" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Підтверджувач служби телефонії" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Індикатор служби телефонії" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Не вдалося надіслати повідомлення" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Повторіть спробу за допомогою програми для роботи з повідомленнями." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Невідомий номер" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Невідома особа" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Невідомий номер" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Розблокуйте SIM-картку і повторіть спробу за допомогою програми для роботи з " "повідомленнями." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Переглянути повідомлення" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Голосова пошта" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Повідомлення голосової пошти" ./po/fi.po0000644000015600001650000001537112677320771012474 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-12-14 19:49+0000\n" "Last-Translator: Jiri Grönroos \n" "Language-Team: Finnish \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: fi\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 vastaamaton puhelu" msgstr[1] "%1 vastaamatonta puhelua" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 vastaajaviesti" msgstr[1] "%1 vastaajaviestiä" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Soitettuja puheluita tänään %1" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Vastaanotettuja puheluita tänään %1" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Vastaanotettuja tekstiviestejä tänään %1" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Lähetettyjä tekstiviestejä tänään %1" #: approver/approver.cpp:518 msgid "Accept" msgstr "Hyväksy" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Soita takaisin" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Soittajan numero ei ole saatavilla" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Puhelu numerosta %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Puhelu salaisesta numerosta" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Puhelu tuntemattomasta numerosta" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Peru" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Poista lentotila käytöstä ja yritä lähettää viesti uudelleen " "viestisovelluksesta." #: approver/approver.cpp:540 msgid "Decline" msgstr "Hylkää" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Lopeta + vastaa" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Laita pitoon + vastaa" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "En huomannut puheluasi, voitko soittaa nyt?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Olen 20 minuuttia myöhässä." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Olen kiireinen juuri nyt. Soitan myöhemmin." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Olen kiireinen. Soitan myöhemmin." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Olen myöhässä, mutta matkalla." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Olen myöhässä, mutta silti tulossa." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Viesti + hylkää" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Viesti (%1)" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Ei soitettuja puheluita tänään" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Ei vastaanotettuja puheluita tänään" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Ei vastaanotettuja tekstiviestejä tänään" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Ei lähetettyjä tekstiviestejä tänään" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Puhelut" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Soita minulle uudelleen myöhemmin." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Aseta SIM-kortti:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Salainen numero" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Salainen numero" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Vastaa" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "Tekstiviesti" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Tallenna" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Lähetä" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Olen valitettavasti edelleen kiireinen. Soitan myöhemmin." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Puheluihin käytetty tänään %1 minuuttia" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Puhelinpalvelu" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Puhelinpalvelujen hyväksyjä" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Puhelinpalvelujen ilmaisin" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Viestin lähetys epäonnistui" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Yritä uudelleen viestisovelluksesta." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Tuntematon numero" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Tuntematon soittaja" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Tuntematon numero" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Avaa SIM-kortin lukitus ja yritä lähettää viesti uudelleen " "viestisovelluksesta." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Näytä viesti" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Vastaaja" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Vastaajaviestit" ./po/ru.po0000644000015600001650000001745512677320771012531 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-08-26 11:36+0000\n" "Last-Translator: ☠Jay ZDLin☠ \n" "Language-Team: Russian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: ru\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 пропущенный вызов" msgstr[1] "%1 пропущенных вызова" msgstr[2] "%1 пропущенных вызовов" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 голосовое сообщение" msgstr[1] "%1 голосовых сообщения" msgstr[2] "%1 голосовых сообщений" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 исходящих вызовов сегодня" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 входящих вызовов сегодня" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 получено сообщений сегодня" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 отправлено сообщений сегодня" #: approver/approver.cpp:518 msgid "Accept" msgstr "Принять" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Позвонить" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Номер абонента не доступен" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Вызов от %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Приватный вызов" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Звонок с неизвестного номера" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Отмена" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Отключите режим \"В полёте\" и попробуйте отправить сообщение снова." #: approver/approver.cpp:540 msgid "Decline" msgstr "Отклонить" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Завершить + Ответить" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Удерживать + Ответить" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Я пропустил ваш звонок - вы можете позвонить мне сейчас?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Я опоздаю на 20 минут." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "В данный момент я занят. Перезвоню позже." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "В данный момент я занят. Я позвоню тебе позже." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Задерживаюсь, уже еду." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Я опаздываю. Я уже в пути." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Сообщение и отклонить" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Сообщение от %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Нет исходящих сегодня" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Нет входящих сегодня" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Нет полученных сообщений сегодня" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Нет отправленных сообщений сегодня" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "ОК" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Вызовы" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Пожалуйста, перезвоните мне позже." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Укажите SIM-карту:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Скрытый номер" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Скрытый номер" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Ответить" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Сохранить" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Отправить" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Извини, я всё еще занят. Я позвоню тебе позже." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Продолжительность вызовов сегодня: %1 минут" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Служба телефонии" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telephony Service Approver" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Индикатор службы телефонии" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Сообщение не может быть отправлено" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Попробуйте отправить сообщение снова." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Неизвестный номер" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Неизвестный вызов" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Неизвестный номер" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Разблокируйте SIM-карту и попробуйте отправить сообщение снова." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Показать сообщение" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Голосовая почта" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Голосовые сообщения" ./po/ro.po0000644000015600001650000001557612677320771012525 0ustar jenkinsjenkins# Romanian translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-08 17:04+0000\n" "Last-Translator: Marian Vasile \n" "Language-Team: Romanian \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 % 100 > 19) || ((n % 100 " "== 0) && (n != 0))) ? 2: 1));\n" "X-Launchpad-Export-Date: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 apel pierdut" msgstr[1] "%1 apeluri pierdute" msgstr[2] "%1 de apeluri pierdute" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mesaj vocal" msgstr[1] "%1 mesaje vocale" msgstr[2] "%1 de mesaje vocale" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 apeluri efectuate astăzi" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 apeluri primite astăzi" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 mesaje text primite astăzi" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 mesaje text trimise astăzi" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accept" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Apelează inapoi" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Numărul apelantului nu este disponibil" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Apel de la %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Apel de la un număr privat" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Apel de la un număr necunoscut" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Anulează" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Dezactivați modul avion și încercați din nou din aplicația de mesagerie." #: approver/approver.cpp:540 msgid "Decline" msgstr "Refuz" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Sfârșit + Răspuns" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Reține + Răspunde" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Am pierdut apelul dumneavoastră - Vă pot suna acum?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Voi întârzia 20 de minute." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Momentan sunt ocupat. Vă sun mai târziu." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Acum sunt ocupat. Voi suna mai târziu." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Sunt înîntârziere, sunt pe drum acum." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Sunt în întârziere. Sunt deja pe drum." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Mesaj & respingere" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mesaj de la %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Niciun apel efectuat astăzi" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Niciun apel primit astăzi" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Niciun mesaj text primit astăzi" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Niciun mesaj text trimis astăzi" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "În regulă" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Apeluri telefonice" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Vă rog să mă sunați înapoi mai târziu." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Selectați un card SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Număr privat" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Număr privat" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Răspuns" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Salvează" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Trimiteți" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Îmi pare rău, sunt în continuare ocupat. Voi suna mai târziu." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Astăzi ați consumat în apeluri %1 minute" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Serviciu de telefonie" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprobator serviciu de telefonie" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicator serviciu de telefonie" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Mesajul nu a putut fi trimis" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Încercați din nou din aplicația de mesagerie" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Număr necunoscut" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Apelant necunoscut" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Număr necunoscut" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Deblocați cartela SIM și încercați din nou din aplicația de mesagerie." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Vizualizare mesaj" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Mesagerie vocală" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Mesaje vocale" ./po/he.po0000644000015600001650000001577712677320771012504 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-12 14:46+0000\n" "Last-Translator: Yaron \n" "Language-Team: Hebrew \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: he\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "שיחה %1 שלא נענתה" msgstr[1] "%1 שיחות שלא נענו" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "הודעה %1 בתא הקולי" msgstr[1] "%1 הודעות בתא הקולי" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 שיחות בוצעו היום" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 שיחות התקבלו היום" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 הודעות התקבלו היום" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 הודעות נשלחו היום" #: approver/approver.cpp:518 msgid "Accept" msgstr "קבלה" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "להתקשר בחזרה" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "מספר המען אינו זמין" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "שיחה מ%1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "שיחה ממספר פרטי" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "שיחה ממספר לא ידוע" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "ביטול" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "מוטב לנטרל את מצב הטיסה ולנסות שוב מיישום ההודעות." #: approver/approver.cpp:540 msgid "Decline" msgstr "דחיה" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "החזקה + מענה" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "פספסתי את שיחתך - אפשר להתקשר אלי בחזרה?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "אאחר ב־20 דקות." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "אין לי אפשרות לענות, אתקשר מאוחר יותר." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "אין לי אפשרות לענות כרגע. אתקשר מאוחר יותר." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "באיחור, בדרך." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "אאחר. אני בדרך." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "הודעה ודחייה" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "הודעת מאת %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "לא בוצעו שיחות היום" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "לא התקבלו שיחות היום" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "לא התקבלו הודעות היום" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "לא נשלחו הודעות היום" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "אישור" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "שיחות טלפון" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "נא להתקשר אלי מאוחר יותר." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "נא לבחור כרטיס SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "מספר חסוי" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "מספר פרטי" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "מענה" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "שמירה" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "שליחה" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "עדיין עסוק. אתקשר מאוחר יותר. סליחה." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "בזבזת %1 דקות בשיחות היום" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "שירות טלפוניה" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "מאשר שירות טלפוניה" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "מחוון שירות טלפוניה" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "לא ניתן לשלוח את ההודעה" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "כדאי לנסות שוב מיישום ההודעות." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "מספר לא ידוע" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "מתקשר לא ידוע" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "מספר לא ידוע" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "ניתן לשחרר את נעילת ה־SIM שלך ולנסות שוב דרך יישום ההודעות." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "צפייה בהודעה" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "תא קולי" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "הודעות בתא הקולי" ./po/am.po0000644000015600001650000001710112677320771012464 0ustar jenkinsjenkins# Amharic translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-19 02:38+0000\n" "Last-Translator: samson \n" "Language-Team: Amharic \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 ያልተመለሰ ጥሪ" msgstr[1] "%1 ያልተመለሱ ጥሪዎች" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 የ ድምፅ መልእክት ሳጥን" msgstr[1] "%1 የ ድምፅ መልእክቶች ሳጥን" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 ዛሬ የደወሉት" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 ዛሬ የተቀበሉዋቸው ጥሪዎች" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 ዛሬ የተቀበሉዋቸው የ ጽሁፍ መልእክቶች" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 ዛሬ የላኩዋቸው የ ጽሁፍ መልእክቶች" #: approver/approver.cpp:518 msgid "Accept" msgstr "ተቀብያለሁ" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "መልሶ መደወያ" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "የደዋዩ ቁጥር አልተገኘም" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "ደዋይ ከ %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "ደዋይ ከ ግል ቁጥር" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "ደዋይ ካልታወቀ ቁጥር" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "መሰረዣ" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "የበረራ ዘዴን ያሰናክሉ እና በ መልእክት መላኪያ መተግበሪያ እንደገና ይሞክሩ" #: approver/approver.cpp:540 msgid "Decline" msgstr "አልቀበልም" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "መጨረሻ + መመለሻ" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "ይጠብቁ + መመለሻ" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "ጥሪው አምልጧኛል - አሁን ሊደውሉልኝ ይችላሉ?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20 ደቂቆች እዘገያለሁ" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "ለጊዜው በ ስራ ላይ ነኝ: በኋላ እደውላለሁ" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "አሁን በስራ ላይ ነኝ: በኋላ እደውላለሁ" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "እዘገያለሁ ነገር ግን እየመጣሁ ነው" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "እየመጣሁ ነው: ነገር ግን እዘገያለሁ" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "መልእክት & አልተቀበሉም" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "መልእክት ከ %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "ዛሬ ምንም አልደወሉም" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "ዛሬ ምንም ጥሪ አልተቀበሉም" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "ዛሬ ምንም የ ጽሁፍ መልእክቶች አልተቀበሉም" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "ዛሬ ምንም የ ጽሁፍ መልእክቶች አልላኩም" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "እሺ" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "የስልክ ጥሪዎች" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "እባክዎን ትንሽ ቆይተው እንደገና ይደውሉ" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "እባክዎን ይምረጡየ SIM ካርድ:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "የግል ቁጥር" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "የ ግል ቁጥር" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "መመለሻ" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "ሲም %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "ኤስ ኤም ኤስ" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "ማስቀመጫ" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "መላኪያ" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "አዝናለሁ: አሁንም በስራ ላይ ነኝ: በኋላ እደውላለሁ" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "ያባከኑት ጊዜ በ %1 ደቂቃዎች በጥሪ ዛሬ" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "የ ቴሌፎን ግልጋሎት" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "የ ቴሌፎን ግልጋሎት አቅራቢ" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "የ ቴሌፎን ግልጋሎት ጠቋሚ" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "መልእክቱን መላክ አልተቻለም" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "በ መልእክት መላኪያ መተግበሪያ እንደገና ይሞክሩ" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "ያልታወቀ ቁጥር" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "ያልታወቀ ደዋይ" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "ያልታወቀ ቁጥር" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "የ እርስዎን ሲም ካርድ ይክፈቱ እና በ መልእክት መላኪያ መተግበሪያ እንደገና ይሞክሩ" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "መልእክት መመልከቻ" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "የ መልእክት ሳጥን" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "የ ድምፅ መልእክቶች ሳጥን" ./po/es.po0000644000015600001650000001535412677320771012506 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-01-19 23:48+0000\n" "Last-Translator: Adolfo Jayme \n" "Language-Team: Spanish \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: es\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 llamada perdida" msgstr[1] "%1 llamadas perdidas" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mensaje de voz" msgstr[1] "%1 mensaje de voz" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 llamadas realizadas hoy" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 llamadas recibidas hoy" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 mensajes de texto recibidos hoy" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 mensajes de texto realizados hoy" #: approver/approver.cpp:518 msgid "Accept" msgstr "Aceptar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Devolver llamada" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "El número del que llama no está disponible" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Llamada de %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Llamada desde un número privado" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Llamada desde un número desconocido" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Cancelar" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Desactive el modo avión e inténtelo de nuevo desde la aplicación de " "mensajería." #: approver/approver.cpp:540 msgid "Decline" msgstr "Rechazar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Fin + responder" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "En espera + responder" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "No pude responderte, ¿podrías llamarme ahora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Tardaré 20 minutos." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Te llamaré en cuanto pueda." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Estoy ocupado/a en este momento. Te llamaré luego." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Llegaré tarde, estoy en camino." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Se me hizo tarde, voy en camino." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Rechazar con msj." #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mensaje de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "No se realizaron llamadas hoy" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "No se recibieron llamadas hoy" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "No se recibieron mensajes de texto hoy" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "No se enviaron mensajes de texto hoy" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Aceptar" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Llamadas telefónicas" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Por favor llámame luego." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Seleccione una tarjeta SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Número privado" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Número privado" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Responder" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Guardar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Enviar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Lo siento, sigo ocupado/a. Te llamaré luego." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Ha utilizado %1 minutos en llamadas hoy" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Servicio de telefonía" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprobador del servicio de telefonía" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador del servicio de telefonía" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "No se pudo enviar el mensaje" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Inténtelo de nuevo desde la aplicación de mensajería." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Número desconocido" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Llamante desconocido" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Número desconocido" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Desbloquee la tarjeta SIM e inténtelo de nuevo desde la aplicación de " "mensajería." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ver mensaje" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Buzón de voz" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Mensajes de voz" ./po/ug.po0000644000015600001650000001712012677320771012503 0ustar jenkinsjenkins# Uyghur translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-09-23 02:42+0000\n" "Last-Translator: Gheyret T.Kenji \n" "Language-Team: Uyghur \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "ئالمىغان تېلېفون %1" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "ئۈنخەت %1" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "بۈگۈن %1 قېتىم تېلېفون قىلىندى" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "بۈگۈن %1 قېتىم تېلېفون قوبۇل قىلىندى" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "بۈگۈن %1 دانە تېكىست ئۇچۇرى قوبۇل قىلىندى" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "بۈگۈن %1 دانە تېكىست ئۇچۇرى ئەۋەتىلدى" #: approver/approver.cpp:518 msgid "Accept" msgstr "قوشۇل" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "تىلفۇن ئۇرلىۋاتىدۇ" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "تېلېفون نومۇرى يوق" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "تېلېفون %1 دىن كەلدى" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "شەخسىي نومۇردىن تېلېفون كەلدى" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "ناتونۇش تېلېفون كەلدى" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "ئەمەلدىن قالدۇر" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "ئايروپىلان ھالىتىنى ئاكتىپسىزلاڭ ۋە ئۇچۇر پروگراممىسىدا قايتا سىناپ كۆرۈڭ." #: approver/approver.cpp:540 msgid "Decline" msgstr "قوشۇلما" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "ئۈز+جاۋاپ" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "ساقلىتىپ قويۇپ جاۋاب بەر" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "تېلېفونىڭىزنى ئالالماي قالدىم، ھازىر تېلېفون قىلالامسىز؟" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "مەن 20 مىنۇت كېچىكىمەن." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "ھازىر بىرئاز ئالدىراش سەل تۈرۇپ ئۈزۈم تىلفۇن قايتۇراي" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "ھازىر ئالدىراش. كېيىن تېلېفون قىلاي." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "كچېكىپ قالدىم ھازىر يولدا" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "كېچىكىپ قالدىم. ھازىر يولدا." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "%1 دىن كەلگەن ئۇچۇر" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "بۈگۈن ھېچقانداق تېلېفون قىلىنمىدى" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "بۈگۈن ھېچقانداق تېلېفون كەلمىدى" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "بۈگۈن ھېچقانداق تېكىست ئۇچۇرى كەلمىدى" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "بۈگۈن ھېچقانداق تېكىست ئۇچۇرى ئەۋەتىلمىدى" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "تامام" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "تېلېفونلار" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "بىر ئازدىن كېيىن قايتىدىن چاقىرىڭ" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "بىر سىم كارتىسى تاللاڭ:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "شەخسىي نومۇر" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "شەخسىي نومۇر" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "جاۋاب قايتۇر" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "ساقلا" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "يوللا" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "كەچۈرۈڭ، ئالدىراشچىلىقىم تۈگىمىدى. كېيىن تېلېفون قىلاي." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "بۈگۈن تېلېفونغا %1 مىنۇت سەرپ قىلىندى" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "تېلېفون مۇلازىمىتى" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telephony Service Approver" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telephony Service Indicator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "ئۇچۇرنى ئەۋەتكىلى بولمىدى" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "ئۇچۇر پروگراممىسىدا قايتا سىناپ كۆرۈڭ." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "ناتونۇش نومۇر" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "ناتونۇش تېلېفون" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "نامەلۇم نومۇر" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "سىم كارتىڭىزنى قۇلۇپسىزلاڭ ۋە ئۇچۇر پروگراممىسىدا قايتا سىناپ كۆرۈڭ." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "ئۇچۇر كۆرسەت" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "ئۈنخەت" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "ئۈنخەتلەر" ./po/CMakeLists.txt0000644000015600001650000000320312677320771014265 0ustar jenkinsjenkinsproject(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} COMMENT "Generating translation template" COMMAND ${XGETTEXT_EXECUTABLE} --c++ --qt --add-comments=TRANSLATORS --keyword=GettextMarkExtraction --keyword=tr --keyword=tr:1,2 -D ${CMAKE_SOURCE_DIR} -s -p ${CMAKE_CURRENT_SOURCE_DIR} -o ${POT_FILE} ${I18N_SRCS} ) add_custom_target(translations COMMENT "Updating translation files" ) add_dependencies(translations ${POT_FILE}) foreach(PO_FILE ${PO_FILES}) add_custom_command(TARGET translations COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} ${PO_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/${POT_FILE} -o ${PO_FILE} ) endforeach(PO_FILE) endif() ./po/fr.po0000644000015600001650000001545212677320771012505 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-11-25 19:36+0000\n" "Last-Translator: Anne \n" "Language-Team: French \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: fr\n" #: indicator/messagingmenu.cpp:299 #, 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:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 message vocal" msgstr[1] "%1 messages vocaux" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 appels émis aujourd'hui" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 appels reçus aujourd'hui" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 SMS reçus aujourd'hui" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 SMS envoyés aujourd'hui" #: approver/approver.cpp:518 msgid "Accept" msgstr "Accepter" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Rappeler" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Le numéro d'appel n'est pas disponible" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Appel depuis %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Appel depuis un numéro privé" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Appel depuis un numéro inconnu" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Annuler" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Désactivez le mode avion, relancez l'application et réessayez à nouveau." #: approver/approver.cpp:540 msgid "Decline" msgstr "Refuser" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Terminer + Répondre" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Rester en ligne + Répondre" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "J'ai manqué votre appel - pouvez-vous m'appeler maintenant ?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "J'aurai 20 minutes de retard." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Je suis occupé pour le moment. Je vous rappellerai plus tard." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Je suis occupé(e) pour le moment. Je vous rappelle plus tard." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Je suis en retard et actuellement en chemin." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Je suis en retard. Je suis en chemin." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Envoyer un message & décliner" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Message de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Pas d'appels émis aujourd'hui" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Pas d'appels reçus aujourd'hui" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Pas de SMS reçus aujourd'hui" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Pas de SMS envoyés aujourd'hui" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Ok" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Appels téléphoniques" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Veuillez me rappeler plus tard." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Veuillez choisir une carte SIM :" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Numéro privé" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Numéro privé" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Répondre" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Enregistrer" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Envoyer" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Désolé, je suis encore occupé. Je vous rappelle plus tard." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 minutes passées à appeler aujourd'hui" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Service téléphonique" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Approbateur de service téléphonique" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicateur de service téléphonique" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Le message ne peut être envoyé." #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Essayez à nouveau depuis l'application." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Numéro inconnu" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Numéro inconnu" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Numéro inconnu" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Déverrouillez votre carte SIM et essayez à nouveau depuis l'application de " "messagerie." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Voir le message" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Messagerie vocale" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Messages vocaux" ./po/ja.po0000644000015600001650000001450712677320771012470 0ustar jenkinsjenkins# Japanese translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-11-20 05:07+0000\n" "Last-Translator: Kentaro Kazuhama \n" "Language-Team: Japanese \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1件の不在着信" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1件のボイスメール" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "本日、%1件の発信" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "本日、%1件の着信" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "本日、%1件のメッセージ受信" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "本日、%1件のメッセージ送信" #: approver/approver.cpp:518 msgid "Accept" msgstr "応答" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "その電話番号は利用できません" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1から着信中" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "内線番号から着信中" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "不明な番号から着信中" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "キャンセル" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "終了" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "保留して応答" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "電話をとれませんでした。今からかけてもらっていいですか?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "20分ぐらい遅れます。" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "今忙しいので、あとで電話します。" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "遅れています。今向かっているところです。" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "%1からのメッセージ" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "本日の発信なし" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "本日の着信なし" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "本日のメッセージの受信なし" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "本日のメッセージの送信なし" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "電話" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "内線番号" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "内線番号" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "返信" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "保存" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "すみません、まだ忙しいので、あとからかけなおします。" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "本日、%1分間の通話" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telephony Service" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telephony Service Approver" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telephony Service Indicator" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "非通知番号" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "不明な発信者" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "不明な番号" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "メッセージを表示する" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "ボイスメール" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "ボイスメールメッセージ" ./po/zh_HK.po0000644000015600001650000001251012677320771013071 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2014-07-29 19:27+0000\n" "Last-Translator: Anthony Wong \n" "Language-Team: Chinese (Hong Kong) \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: zh_HK\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "" msgstr[1] "" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "" msgstr[1] "" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "" #: approver/approver.cpp:518 msgid "Accept" msgstr "接聽" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" #: approver/approver.cpp:540 msgid "Decline" msgstr "" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "" ./po/de.po0000644000015600001650000001536612677320771012472 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-09-04 12:36+0000\n" "Last-Translator: Tobias Bannert \n" "Language-Team: German \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: de\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 verpasster Anruf" msgstr[1] "%1 verpasste Anrufe" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 Sprachnachricht" msgstr[1] "%1 Sprachnachrichten" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "Ausgehende Anrufe heute: %1" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "Erhaltene Anrufe heute: %1" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "Erhaltene SMS heute: %1" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "Gesendete SMS heute: %1" #: approver/approver.cpp:518 msgid "Accept" msgstr "Annehmen" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Zurück rufen" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Die Nummer des Anrufers ist nicht verfügbar" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Anruf von %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Anruf von einer privaten Nummer" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Anruf von einer unbekannten Nummer" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Abbrechen" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Bitte den Flugmodus deaktivieren und von der Nachrichtenanwendung erneut " "versuchen." #: approver/approver.cpp:540 msgid "Decline" msgstr "Ablehnen" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Auflegen + Antworten" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Halten + Antworten" #: indicator/messagingmenu.cpp:241 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:244 msgid "I'll be 20 minutes late." msgstr "Ich komme 20 Minuten später." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Ich kann gerade nicht. Ich rufe später zurück." #: indicator/messagingmenu.cpp:243 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." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Ich bin spät dran. Bin jetzt auf dem Weg." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Ich bin spät dran, aber auf dem Weg." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Nachricht senden & ablehnen" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Nachricht von %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Keine Anrufe heute" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Heute keine Anrufe erhalten" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Heute keine SMS erhalten" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Heute keine SMS gesendet" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "OK" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Anrufe" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Bitte mich später zurückrufen." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Bitte eine SIM-Karte auswählen:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Private Nummer" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Private Nummer" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Antworten" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Speichern" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Senden" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Leider bin ich noch beschäftigt. Ich werde Sie später anrufen." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "%1 Minuten in Anrufen heute" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Telefondienst" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Telefondienstgenehmigung" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Telefondienstbenachrichtigung" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Nachricht konnte nicht gesendet werden" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Bitte erneut von der Nachrichtenanwendung aus versuchen." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Unbekannte Nummer" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Unbekannter Anrufer" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Unbekannte Nummer" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Bitte Ihre Sim-Karte entsperren und es erneut von der Nachrichtenanwendung " "aus versuchen." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Nachricht anzeigen" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Sprachnachricht" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Sprachnachrichten" ./po/be.po0000644000015600001650000002007212677320771012456 0ustar jenkinsjenkins# Belarusian translation for telephony-service # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-12-06 09:36+0000\n" "Last-Translator: XiveZ \n" "Language-Team: Belarusian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 прапушчаны выклік" msgstr[1] "%1 прапушчаныя выклікі" msgstr[2] "%1 прапушчаных выклікаў" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 галасавое паведамленьне" msgstr[1] "%1 галасавых паведамленьня" msgstr[2] "%1 галасавых паведамленьняў" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 зыходных выклікаў сёньня" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 уваходных выклікаў сёньня" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 атрымана паведамленьняў сёньня" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 дасланана паведамленьняў сёньня" #: approver/approver.cpp:518 msgid "Accept" msgstr "Пацьвердзіць" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Патэлефанаваць" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "Нумар абаненту не дасяжны" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Выклік ад %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Прыватны нумар" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Невядомы нумар" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Скасаваць" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "Адключыце рэжым \"Лёту\" і паспрабуйце зноўку." #: approver/approver.cpp:540 msgid "Decline" msgstr "Адхіліць" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Скончыць + Адказаць" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Утрымліваць + Адказаць" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Я прапусціў вашае тэлефанаваньне - вы можаце патэлефанаваць зараз?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Я спазнюся на 20 хвілін." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "У дадзены момант я заняты. Патэлефаную пазьней." #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "У дадзены момант часу я заняты. Патэлефаную крыху пазьней." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Затрымваюся, але еду ж." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Я спазьняюся. Я ўжо ў дарозе." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Даслаць і адхіліць" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Паведамленьне ад %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Няма зыходных на сёньня" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Няма атрыманых паведамленьняў на сёньня" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Няма атрыманых паведамленняў сёння" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Няма дасланых паведамленьняў на сёньня" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Добра" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Выклікі" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Калі ласка, ператэлефануеце мне пазьней." #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Калі ласка, абярыце SIM картку:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Прыватны нумар" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Нумар схаваны" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Адказаць" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Захаваць" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Даслаць" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Прабач, але я ўсё яшчэ заняты. Я патэлефаную табе пазьней" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Працягласць выклікаў на сёньня: %1b> хвілін" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Тэлефонныя сервісы" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Сэрвісы тэлефанаваньня пацьверджаны" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Індыкатар службы тэлефанаваньня" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Гэтае паведамленьне не можа быць даслана" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Паспрабуйце даслаць паведамленьне зноўку." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Невядомы нумар" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Невядомы выклік" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Невядомы нумар" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "Разблакуйце SIM-картку і паспрабуйце даслаць паведамленьне зноўку." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Паказаць паведамленьне" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Галасавая пошта" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Галасавыя паведамленні" ./po/zh_CN.po0000644000015600001650000001456012677320771013076 0ustar jenkinsjenkins# 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: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-06-29 02:38+0000\n" "Last-Translator: Ian Li \n" "Language-Team: Chinese (Simplified) \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" "Language: \n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 个未接来电" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 个语音信息" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "今日呼出 %1 个通话" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "今日接听 %1 个通话" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "今日收到 %1 条短信" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "今日发送 %1 条短信" #: approver/approver.cpp:518 msgid "Accept" msgstr "接听" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "回电" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "没有对方来电号码" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "%1 的来电" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "私密号码来电" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "陌生号码来电" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "取消" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "关闭飞行模式并在短信应用中重试。" #: approver/approver.cpp:540 msgid "Decline" msgstr "拒绝" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "挂断 + 应答" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "挂起 + 应答" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "我错过了您的电话,您可以现在打给我吗?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "我将会迟到20分钟。" #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "此刻我正忙。稍后我将回电。" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "现在正忙,待会儿回您电话。" #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "我迟了,正在路上。" #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "快迟到了,我这就动身。" #: approver/approver.cpp:548 msgid "Message & decline" msgstr "拒接并发送短信" #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "来自 %1 的短信" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "今日无呼出" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "今日无接听" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "今日未收到短信" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "今日未发送短信" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "确定" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "手机通话" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "请稍后再呼叫我。" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "请选择一张SIM卡:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "私密号码" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "私密号码" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "回复" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM卡 %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "信息" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "保存" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "发送" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "抱歉,我还在忙,待会儿给您回电话。" #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "今日通话时长 %1 分钟" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "电话服务" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "电话服务核准" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "电话服务指示器" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "本短信无法被发送" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "请使用短信应用重试。" #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "不明号码" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "未知来电者" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "未知号码" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "请解锁你的SIM卡,然后在短信应用中重试。" #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "检视讯息" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "语音信箱" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "语音信箱信息" ./po/ast.po0000644000015600001650000001531312677320771012661 0ustar jenkinsjenkins# Asturian translation for telephony-service # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the telephony-service package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: telephony-service\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-01-16 15:24-0200\n" "PO-Revision-Date: 2015-02-11 21:28+0000\n" "Last-Translator: ivarela \n" "Language-Team: Asturian \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: 2016-03-29 05:40+0000\n" "X-Generator: Launchpad (build 17967)\n" #: indicator/messagingmenu.cpp:299 #, qt-format msgid "%1 missed call" msgid_plural "%1 missed calls" msgstr[0] "%1 llamada perdida" msgstr[1] "%1 llamaes perdíes" #: indicator/messagingmenu.cpp:398 #, qt-format msgid "%1 voicemail message" msgid_plural "%1 voicemail messages" msgstr[0] "%1 mensaxe de voz" msgstr[1] "%1 mensaxes de voz" #: indicator/metrics.cpp:48 #, qt-format msgid "%1 calls made today" msgstr "%1 llamaes feches güei" #: indicator/metrics.cpp:46 #, qt-format msgid "%1 calls received today" msgstr "%1 llamaes recibíes güei" #: indicator/metrics.cpp:44 #, qt-format msgid "%1 text messages received today" msgstr "%1 mensaxes de testu recibíos güei" #: indicator/metrics.cpp:42 #, qt-format msgid "%1 text messages sent today" msgstr "%1 mensaxes de testu unviaos güei" #: approver/approver.cpp:518 msgid "Accept" msgstr "Aceutar" #: indicator/messagingmenu.cpp:236 msgid "Call back" msgstr "Devolver llamada" #: approver/approver.cpp:464 approver/approver.cpp:479 msgid "Caller number is not available" msgstr "El númberu al que tas llamando nun ta disponible" #: approver/approver.cpp:476 #, qt-format msgid "Calling from %1" msgstr "Llamada dende %1" #: approver/approver.cpp:470 msgid "Calling from private number" msgstr "Llamada dende un númberu priváu" #: approver/approver.cpp:473 msgid "Calling from unknown number" msgstr "Llamada dende númberu desconocíu" #: indicator/ussdindicator.cpp:142 msgid "Cancel" msgstr "Encaboxar" #: indicator/textchannelobserver.cpp:236 msgid "Deactivate flight mode and try again from the messaging application." msgstr "" "Desactiva'l mou avión ya inténtalo de nueves dende l'app de mensaxería." #: approver/approver.cpp:540 msgid "Decline" msgstr "Refugar" #: approver/approver.cpp:531 msgid "End + Answer" msgstr "Fin + responder" #: approver/approver.cpp:517 msgid "Hold + Answer" msgstr "Caltener + Contestar" #: indicator/messagingmenu.cpp:241 msgid "I missed your call - can you call me now?" msgstr "Nun pudi responder, ¿pues llamame agora?" #: indicator/messagingmenu.cpp:244 msgid "I'll be 20 minutes late." msgstr "Voi tardar 20 minutos." #: approver/approver.cpp:91 msgid "I'm busy at the moment. I'll call later." msgstr "Llámote namái pueda" #: indicator/messagingmenu.cpp:243 msgid "I'm busy at the moment. I'll call you later." msgstr "Toi ocupáu nesti intre. Llámote dempués." #: approver/approver.cpp:92 msgid "I'm running late, on my way now." msgstr "Aportaré sero, toi en camín." #: indicator/messagingmenu.cpp:242 msgid "I'm running late. I'm on my way." msgstr "Fízoseme sero. Toi en camín." #: approver/approver.cpp:548 msgid "Message & decline" msgstr "Refugar con msx." #: indicator/textchannelobserver.cpp:560 #, qt-format msgid "Message from %1" msgstr "Mensaxe de %1" #: indicator/metrics.cpp:49 indicator/metrics.cpp:51 msgid "No calls made today" msgstr "Güei nun se fexeron llamaes" #: indicator/metrics.cpp:47 msgid "No calls received today" msgstr "Güei nun se recibieron llamaes" #: indicator/metrics.cpp:45 msgid "No text messages received today" msgstr "Güei nun se recibieron mensaxes de testu" #: indicator/metrics.cpp:43 msgid "No text messages sent today" msgstr "Güei nun s'unviaron mensaxes de testu" #: indicator/textchannelobserver.cpp:312 indicator/ussdindicator.cpp:116 msgid "Ok" msgstr "Aceutar" #: indicator/telephony-service-call.desktop.in:3 msgid "Phone Calls" msgstr "Llamaes de teléfonu" #: approver/approver.cpp:93 msgid "Please call me back later." msgstr "Por favor llámame llueu" #: indicator/textchannelobserver.cpp:697 msgid "Please, select a SIM card:" msgstr "Esbilla una tarxeta SIM:" #: Ubuntu/Telephony/contactwatcher.cpp:131 msgid "Private Number" msgstr "Númberu priváu" #: approver/approver.cpp:455 indicator/messagingmenu.cpp:304 msgid "Private number" msgstr "Númberu priváu" #: indicator/ussdindicator.cpp:119 msgid "Reply" msgstr "Responder" #: handler/displaynamesettings.cpp:34 #, qt-format msgid "SIM %1" msgstr "SIM %1" #: indicator/telephony-service-sms.desktop.in:3 msgid "SMS" msgstr "SMS" #: indicator/textchannelobserver.cpp:318 msgid "Save" msgstr "Guardar" #: indicator/messagingmenu.cpp:185 indicator/messagingmenu.cpp:251 msgid "Send" msgstr "Unviar" #: indicator/messagingmenu.cpp:245 msgid "Sorry, I'm still busy. I'll call you later." msgstr "Siéntolo, sigo ocupáu/ada. Llámote llueu." #: indicator/metrics.cpp:50 #, qt-format msgid "Spent %1 minutes in calls today" msgstr "Güei usasti %1 minutos en llamaes" #: indicator/messagingmenu.cpp:56 indicator/messagingmenu.cpp:60 msgid "Telephony Service" msgstr "Serviciu telefónicu" #: approver/main.cpp:46 msgid "Telephony Service Approver" msgstr "Aprobador del serviciu telefónicu" #: indicator/main.cpp:52 msgid "Telephony Service Indicator" msgstr "Indicador del serviciu de telefonía" #: indicator/textchannelobserver.cpp:245 msgid "The message could not be sent" msgstr "Nun pudo unviase'l mensaxe" #: indicator/textchannelobserver.cpp:239 msgid "Try again from the messaging application." msgstr "Inténtalo de nueves dende l'aplicación de mensaxería." #: Ubuntu/Telephony/contactwatcher.cpp:133 msgid "Unknown Number" msgstr "Númberu desconocíu" #: approver/approver.cpp:63 msgid "Unknown caller" msgstr "Llamante desconocíu" #: approver/approver.cpp:458 indicator/messagingmenu.cpp:151 #: indicator/messagingmenu.cpp:308 indicator/textchannelobserver.cpp:487 msgid "Unknown number" msgstr "Númberu desconocíu" #: indicator/textchannelobserver.cpp:234 msgid "Unlock your sim card and try again from the messaging application." msgstr "" "Desbloquia la tarxeta SIM ya inténtalo de nueves dende l'aplicación de " "mensaxería." #: indicator/textchannelobserver.cpp:260 indicator/textchannelobserver.cpp:524 msgid "View message" msgstr "Ver mensaxe" #: indicator/messagingmenu.cpp:403 msgid "Voicemail" msgstr "Buzón de voz" #: indicator/messagingmenu.cpp:395 msgid "Voicemail messages" msgstr "Mensaxes de voz" ./protocols/0000755000015600001650000000000012677320772013136 5ustar jenkinsjenkins./protocols/ofono.protocol0000644000015600001650000000020612677320771016036 0ustar jenkinsjenkins[Protocol] Name=ofono Features=text,voice FallbackProtocol= BackgroundImage=/usr/share/telephony-service/assets/message_watermark.png ./protocols/CMakeLists.txt0000644000015600001650000000016512677320771015677 0ustar jenkinsjenkinsfile(GLOB PROTOCOL_FILES *.protocol) install(FILES ${PROTOCOL_FILES} DESTINATION ${TELEPHONY_SERVICE_DIR}/protocols) ./tools/0000755000015600001650000000000012677320772012252 5ustar jenkinsjenkins./tools/ofono-setup0000755000015600001650000001166412677320771014465 0ustar jenkinsjenkins#!/bin/sh get_telepathy_ofono_accounts() { mc-tool list | grep "^ofono/ofono/" | sort } check_mission_control_running() { # "mc-tool list" returns failure when no accounts are found, so we # check if mission control is running via dbus directly dbus-send --print-reply --reply-timeout=2000 --session --dest=org.freedesktop.Telepathy.AccountManager /org/freedesktop/Telepathy/AccountManager org.freedesktop.DBus.Properties.GetAll string:org.freedesktop.Telepathy.AccountManager | grep ValidAccounts 2>&1 > /dev/null } get_modem_objpath_for_account() { echo "$(mc-tool show $1 | sed -n 's,.*modem-objpath = \(.*\)$,\1,p')" } existing_account_for_modem_objpath() { modem_obj_path=$1 for account in $EXISTING_OFONO_ACCOUNTS; do if [ "$(get_modem_objpath_for_account $account)" = "$modem_obj_path" ]; then echo "$account" fi done } retries=0 # make sure telepathy is correctly running before we setup the accounts while ! check_mission_control_running; do retries=$((retries+1)) echo "can't connect to mission-control via dbus, retrying $retries" if [ "$retries" -eq "10" ]; then echo "maximum retries reached, aborting" exit 1 fi sleep 1 done # FIXME mission control for some reason does not start tp-ofono if there is no connection # even if always-dispatch is true on the account, this workaround fixes the problem dconf write /org/gnome/empathy/use-conn false 2>&1 > /dev/null # do not wait for a network connection to launch the connection managers dconf write /org/gnome/empathy/use-conn true 2>&1 > /dev/null EXISTING_OFONO_ACCOUNTS=$(get_telepathy_ofono_accounts) # iterate over all accounts to find duplicates for account in $EXISTING_OFONO_ACCOUNTS; do remove=0 modem_obj_path=$(get_modem_objpath_for_account $account) if [ -e $modem_obj_path ]; then # skip accounts with empty modem-objpath if any echo "account with empty modem-objpath found, removing it: $account" mc-tool remove $account 2>&1 > /dev/null continue fi for account2 in $EXISTING_OFONO_ACCOUNTS; do # ignore if same account and set flag to remove next ones if [ "$account" = "$account2" ]; then remove=1 continue; fi # check if this account was not removed already by this loop mc-tool show $account2 2>&1 > /dev/null if [ $? = 1 ]; then continue fi # check if modem-objpath is repeated if [ "$(get_modem_objpath_for_account $account2)" = "$modem_obj_path" ]; then echo "found duplicate account: $account2 modem: $modem_obj_path" mc-tool remove $account2 2>&1 > /dev/null fi done done # refresh account list after duplicates are removed EXISTING_OFONO_ACCOUNTS=$(get_telepathy_ofono_accounts) EXISTING_OFONO_ACCOUNTS_COUNT=$(get_telepathy_ofono_accounts | wc -l) MODEM_COUNT=0 # check if there is at least one modem if [ "$(getprop rild.libpath '')" != "" ]; then MODEM_COUNT=$(getprop ril.num_slots 1) fi if [ "$MODEM_COUNT" != "$EXISTING_OFONO_ACCOUNTS_COUNT" ]; then echo "modem count: $MODEM_COUNT" echo "existing ofono accounts: $EXISTING_OFONO_ACCOUNTS_COUNT" GSETTINGS_ARRAY="{" LAST_MODEM_INDEX="`expr $MODEM_COUNT - 1`" # check if all modems belong to at least one existing account for INDEX in $(seq 0 $LAST_MODEM_INDEX); do MODEM_OBJPATH=/ril_$INDEX # get previous name from gsettings if any EXISTING_NAME=$(python3 -c "array=$(gsettings get com.ubuntu.phone sim-names); print (array[\"$MODEM_OBJPATH\"])") if [ -n "$EXISTING_NAME" ]; then NAME=$EXISTING_NAME else SIM_NAME=$(gettext -d telephony-service "SIM %1") # replace the %1 with the actual index NAME=$(echo $SIM_NAME | sed "s/%1$/$(($INDEX+1))/") fi if [ "" = "$(existing_account_for_modem_objpath $MODEM_OBJPATH)" ]; then echo "no account found for modem $MODEM_OBJPATH" ACCOUNT="account$INDEX" echo "creating ofono/ofono/$ACCOUNT" mc-tool add ofono/ofono $ACCOUNT string:modem-objpath=$MODEM_OBJPATH echo "enabling ofono/ofono/$ACCOUNT" mc-tool enable ofono/ofono/$ACCOUNT mc-tool auto-connect ofono/ofono/$ACCOUNT mc-tool display ofono/ofono/$ACCOUNT "$NAME" # append this entry to the gsettings array GSETTINGS_ARRAY="$GSETTINGS_ARRAY '$MODEM_OBJPATH': '$NAME'," else echo "account found for modem $MODEM_OBJPATH" # this account already exists, just take the name from gsettings GSETTINGS_ARRAY="$GSETTINGS_ARRAY '$MODEM_OBJPATH': '$NAME'," fi done # remove the last "," if present GSETTINGS_ARRAY="$(echo $GSETTINGS_ARRAY | sed 's/,$//g')}" # set names in gsettings gsettings set com.ubuntu.phone sim-names "$GSETTINGS_ARRAY" else echo "sanity check passed" fi ./tools/CMakeLists.txt0000644000015600001650000000010412677320771015004 0ustar jenkinsjenkinsinstall(PROGRAMS ofono-setup DESTINATION ${CMAKE_INSTALL_BINDIR}) ./config.h.in0000644000015600001650000000354012677320771013136 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 static bool canRunUninstalled = true; inline bool isRunningInstalled() { static bool installed = (QCoreApplication::applicationDirPath() == QDir(("@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@")).canonicalPath()); return installed || !canRunUninstalled; } 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@/"); } } inline QString protocolsDir() { QString directory = qgetenv("TELEPHONY_SERVICE_PROTOCOLS_DIR"); if (directory.isEmpty()) { directory = telephonyServiceDir() + "/protocols"; } return directory; } ./libtelephonyservice/0000755000015600001650000000000012677320772015171 5ustar jenkinsjenkins./libtelephonyservice/applicationutils.h0000644000015600001650000000221612677320771020726 0ustar jenkinsjenkins/* * 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 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 ./libtelephonyservice/accountentryfactory.h0000644000015600001650000000201412677320771021444 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 ACCOUNTENTRYFACTORY_H #define ACCOUNTENTRYFACTORY_H #include class AccountEntry; class AccountEntryFactory { public: static AccountEntry *createEntry(const Tp::AccountPtr &account, QObject *parent = 0); }; #endif // ACCOUNTENTRYFACTORY_H ./libtelephonyservice/callmanager.h0000644000015600001650000000750012677320771017611 0ustar jenkinsjenkins/* * 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(QQmlListProperty calls READ calls NOTIFY callsChanged) Q_PROPERTY(bool callIndicatorVisible READ callIndicatorVisible WRITE setCallIndicatorVisible NOTIFY callIndicatorVisibleChanged) public: static CallManager *instance(); Q_INVOKABLE void startCall(const QString &phoneNumber, const QString &accountId = QString::null); Q_INVOKABLE void mergeCalls(CallEntry *firstCall, CallEntry *secondCall); Q_INVOKABLE void splitCall(CallEntry *callEntry); Q_INVOKABLE void playTone(const QString &key); Q_INVOKABLE bool handleMediaKey(bool doubleClick); 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); // call indicator related bool callIndicatorVisible() const; void setCallIndicatorVisible(bool visible); // 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 voicemailNumberChanged(); void emergencyNumbersChanged(); void callIndicatorVisibleChanged(bool visible); void conferenceRequestFailed(); public Q_SLOTS: void onCallChannelAvailable(Tp::CallChannelPtr channel); void onChannelObserverUnregistered(); void onCallEnded(); void onCallIndicatorVisibleChanged(bool visible); void onConferenceCallRequestFinished(bool succeeded); private: explicit CallManager(QObject *parent = 0); void refreshProperties(); void setDBusProperty(const QString &name, const QVariant &value); void setupCallEntry(CallEntry *entry); mutable QList mCallEntries; bool mNeedsUpdate; CallEntry *mConferenceCall; bool mCallIndicatorVisible; }; #endif // CALLMANAGER_H ./libtelephonyservice/accountentryfactory.cpp0000644000015600001650000000253112677320771022003 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "accountentryfactory.h" #include "accountentry.h" #include "ofonoaccountentry.h" #include "multimediaaccountentry.h" AccountEntry *AccountEntryFactory::createEntry(const Tp::AccountPtr &account, QObject *parent) { QString protocol = account.isNull() ? "" : account->protocolName(); // FIXME: check what other accounts need extra properties/methods if (protocol == "ofono") { return new OfonoAccountEntry(account, parent); } if (protocol == "multimedia") { return new MultimediaAccountEntry(account, parent); } return new AccountEntry(account, parent); } ./libtelephonyservice/tonegenerator.cpp0000644000015600001650000000671012677320771020554 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Martti Piirainen * * 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 "tonegenerator.h" #include #include #include #include /* Use tone-generator (tonegend) via D-Bus */ #define TONEGEN_DBUS_SERVICE_NAME "com.Nokia.Telephony.Tones" #define TONEGEN_DBUS_OBJ_PATH "/com/Nokia/Telephony/Tones" #define TONEGEN_DBUS_IFACE_NAME TONEGEN_DBUS_SERVICE_NAME ToneGenerator::ToneGenerator(QObject *parent) : QObject(parent), mDTMFPlaybackTimer(nullptr), mWaitingPlaybackTimer(new QTimer(this)) { // the waiting tone is played in loop connect(mWaitingPlaybackTimer, SIGNAL(timeout()), this, SLOT(playWaitingTone())); mWaitingPlaybackTimer->setSingleShot(true); } ToneGenerator::~ToneGenerator() { this->stopDTMFTone(); this->stopWaitingTone(); } ToneGenerator *ToneGenerator::instance() { static ToneGenerator *self = new ToneGenerator(); return self; } bool ToneGenerator::startEventTone(uint key) { QDBusMessage startMsg = QDBusMessage::createMethodCall( TONEGEN_DBUS_SERVICE_NAME, TONEGEN_DBUS_OBJ_PATH, TONEGEN_DBUS_IFACE_NAME, "StartEventTone" ); QList toneArgs; toneArgs << QVariant((uint)key); toneArgs << QVariant((int)0); // volume is ignored toneArgs << QVariant((uint)0); // duration is ignored startMsg.setArguments(toneArgs); return QDBusConnection::sessionBus().send(startMsg); } void ToneGenerator::playDTMFTone(uint key) { if (key > 11) { qDebug() << "Invalid DTMF tone, ignore."; return; } if (startEventTone(key)) { if (!mDTMFPlaybackTimer) { mDTMFPlaybackTimer = new QTimer(this); mDTMFPlaybackTimer->setSingleShot(true); connect(mDTMFPlaybackTimer, SIGNAL(timeout()), this, SLOT(stopDTMFTone())); } mDTMFPlaybackTimer->start(DTMF_LOCAL_PLAYBACK_DURATION); } } void ToneGenerator::stopTone() { QDBusConnection::sessionBus().send( QDBusMessage::createMethodCall( TONEGEN_DBUS_SERVICE_NAME, TONEGEN_DBUS_OBJ_PATH, TONEGEN_DBUS_IFACE_NAME, "StopTone" )); } void ToneGenerator::stopDTMFTone() { stopTone(); if (mDTMFPlaybackTimer) { mDTMFPlaybackTimer->stop(); } } void ToneGenerator::playWaitingTone() { if (mWaitingPlaybackTimer->isActive()) { stopTone(); } if (startEventTone(WAITING_TONE)) { mWaitingPlaybackTimer->start(WAITING_PLAYBACK_DURATION); } } void ToneGenerator::stopWaitingTone() { stopTone(); mWaitingPlaybackTimer->stop(); } void ToneGenerator::playCallEndedTone() { startEventTone(CALL_ENDED_TONE); QTimer::singleShot(2000, this, SLOT(stopTone())); } ./libtelephonyservice/multimediaaccountentry.cpp0000644000015600001650000000361612677320771022473 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "multimediaaccountentry.h" #include "phoneutils.h" #include "telepathyhelper.h" MultimediaAccountEntry::MultimediaAccountEntry(const Tp::AccountPtr &account, QObject *parent) : AccountEntry(account, parent) { } AccountEntry::AccountType MultimediaAccountEntry::type() const { return AccountEntry::MultimediaAccount; } bool MultimediaAccountEntry::connected() const { return !mAccount.isNull() && !mAccount->connection().isNull() && !mAccount->connection()->selfContact().isNull() && mAccount->connection()->selfContact()->presence().type() != Tp::ConnectionPresenceTypeOffline; } bool MultimediaAccountEntry::compareIds(const QString &first, const QString &second) const { return PhoneUtils::comparePhoneNumbers(first, second) > PhoneUtils::NO_MATCH; } QStringList MultimediaAccountEntry::addressableVCardFields() { return mAccount->protocolInfo().addressableVCardFields(); } void MultimediaAccountEntry::onConnectionChanged(Tp::ConnectionPtr connection) { // make sure the generic code is also run AccountEntry::onConnectionChanged(connection); } ./libtelephonyservice/callmanager.cpp0000644000015600001650000003167212677320771020153 0ustar jenkinsjenkins/* * 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 "accountentry.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(channelObserverUnregistered()), SLOT(onChannelObserverUnregistered())); connect(this, SIGNAL(hasCallsChanged()), SIGNAL(callsChanged())); connect(this, &CallManager::hasCallsChanged, [this] { Q_EMIT this->callIndicatorVisibleChanged(this->callIndicatorVisible()); }); refreshProperties(); // connect the dbus signal QDBusConnection connection = QDBusConnection::sessionBus(); connection.connect("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "com.canonical.TelephonyServiceHandler", "CallIndicatorVisibleChanged", this, SLOT(onCallIndicatorVisibleChanged(bool))); connection.connect("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "com.canonical.TelephonyServiceHandler", "ConferenceCallRequestFinished", this, SLOT(onConferenceCallRequestFinished(bool))); } void CallManager::refreshProperties() { QDBusInterface handlerPropertiesInterface("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "org.freedesktop.DBus.Properties"); QDBusReply reply = handlerPropertiesInterface.call("GetAll", "com.canonical.TelephonyServiceHandler"); if (!reply.isValid()) { qWarning() << "Failed to refresh the properties from the handler"; return; } QVariantMap map = reply.value(); mCallIndicatorVisible = map["CallIndicatorVisible"].toBool(); Q_EMIT callIndicatorVisibleChanged(mCallIndicatorVisible); } void CallManager::setDBusProperty(const QString &name, const QVariant &value) { QDBusInterface handlerPropertiesInterface("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "org.freedesktop.DBus.Properties"); handlerPropertiesInterface.call("Set", "com.canonical.TelephonyServiceHandler", name, QVariant::fromValue(QDBusVariant(value))); } 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(); } bool CallManager::callIndicatorVisible() const { return hasCalls() && mCallIndicatorVisible; } void CallManager::setCallIndicatorVisible(bool visible) { setDBusProperty("CallIndicatorVisible", visible); } 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) { AccountEntry *account; if (accountId.isNull()) { account = TelepathyHelper::instance()->defaultCallAccount(); if (!account) { account = TelepathyHelper::instance()->accounts()[0]; } } else { account = TelepathyHelper::instance()->accountForId(accountId); } if (!account) { return; } QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("StartCall", phoneNumber, account->accountId()); } void CallManager::onCallIndicatorVisibleChanged(bool visible) { mCallIndicatorVisible = visible; Q_EMIT callIndicatorVisibleChanged(visible); } void CallManager::onConferenceCallRequestFinished(bool succeeded) { if (!succeeded) { Q_EMIT conferenceRequestFailed(); } } 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, and if not in greeter mode, query the telephony-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 // Also, we have to avoid creating instances of GreeterContacts here to query if we are in greeter mode, // otherwise we might end up with a deadlock: unity -> telephony-service -> unity if (qgetenv("XDG_SESSION_CLASS") != "greeter") { 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->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(); } 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()); } void CallManager::playTone(const QString &key) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); /* calling without channel, DTMF tone is played only locally */ phoneAppHandler->call("SendDTMF", "" , key); } bool CallManager::handleMediaKey(bool doubleClick) { QDBusInterface *approverInterface = TelepathyHelper::instance()->approverInterface(); QDBusReply reply = approverInterface->call("HandleMediaKey", doubleClick); if (reply.isValid()) { return reply.value(); } return false; } ./libtelephonyservice/callnotification.cpp0000644000015600001650000001000612677320771021213 0ustar jenkinsjenkins/* * 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 "config.h" namespace C { #include } CallNotification::CallNotification(QObject *parent) : QObject(parent), mIndicatorIface("com.canonical.TelephonyServiceIndicator", "/com/canonical/TelephonyServiceIndicator", "com.canonical.TelephonyServiceIndicator") { } 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 } void CallNotification::clearCallNotification(const QString &participantId, const QString &accountId) { mIndicatorIface.asyncCall("ClearCallNotification", participantId, accountId); } ./libtelephonyservice/ussdmanager.cpp0000644000015600001650000001637312677320771020217 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 "accountentry.h" #include #include typedef QMap dbusQMap; Q_DECLARE_METATYPE(dbusQMap) USSDManager::USSDManager(AccountEntry *account, QObject *parent) : QObject(parent), mState("idle"), mAccount(account) { connect(mAccount, SIGNAL(connectedChanged()), this, SLOT(onConnectionChanged())); onConnectionChanged(); } void USSDManager::initiate(const QString &command) { QDBusInterface ussdIface(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE); ussdIface.asyncCall("Initiate", command); } void USSDManager::respond(const QString &reply) { QDBusInterface ussdIface(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE); ussdIface.asyncCall("Respond", reply); } void USSDManager::cancel() { QDBusInterface ussdIface(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE); ussdIface.asyncCall("Cancel"); } void USSDManager::connectAllSignals() { if (mBusName.isEmpty() || mObjectPath.isEmpty()) { return; } QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "StateChanged", this, SLOT(onStateChanged(QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RequestReceived", this, SIGNAL(requestReceived(QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "NotificationReceived", this, SIGNAL(notificationReceived(QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateUSSDComplete", this, SIGNAL(initiateUSSDComplete(QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RespondComplete", this, SIGNAL(respondComplete(bool, QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "BarringComplete", this, SIGNAL(barringComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ForwardingComplete", this, SIGNAL(forwardingComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "WaitingComplete", this, SIGNAL(waitingComplete(QString, QVariantMap))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLinePresentationComplete", this, SIGNAL(callingLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLineRestrictionComplete", this, SIGNAL(callingLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLineRestrictionComplete", this, SIGNAL(connectedLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLinePresentationComplete", this, SIGNAL(connectedLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().connect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateFailed", this, SIGNAL(initiateFailed())); } void USSDManager::disconnectAllSignals() { if (mBusName.isEmpty() || mObjectPath.isEmpty()) { return; } QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "StateChanged", this, SLOT(onStateChanged(QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RequestReceived", this, SIGNAL(requestReceived(QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "NotificationReceived", this, SIGNAL(notificationReceived(QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateUSSDComplete", this, SIGNAL(initiateUSSDComplete(QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "RespondComplete", this, SIGNAL(respondComplete(bool, QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "BarringComplete", this, SIGNAL(barringComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ForwardingComplete", this, SIGNAL(forwardingComplete(QString, QString, QVariantMap))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "WaitingComplete", this, SIGNAL(waitingComplete(QString, QVariantMap))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLinePresentationComplete", this, SIGNAL(callingLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "CallingLineRestrictionComplete", this, SIGNAL(callingLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLineRestrictionComplete", this, SIGNAL(connectedLineRestrictionComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "ConnectedLinePresentationComplete", this, SIGNAL(connectedLinePresentationComplete(QString, QString))); QDBusConnection::sessionBus().disconnect(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE, "InitiateFailed", this, SIGNAL(initiateFailed())); } void USSDManager::onConnectionChanged() { disconnectAllSignals(); if (mAccount->account()->connection().isNull()) { qDebug() << "USSDManager: Failed to connect signals"; return; } mBusName = mAccount->account()->connection()->busName(); mObjectPath = mAccount->account()->connection()->objectPath(); QDBusInterface ussdIface(mBusName, mObjectPath, CANONICAL_TELEPHONY_USSD_IFACE); mState = ussdIface.property("State").toString(); connectAllSignals(); } void USSDManager::onStateChanged(const QString &state) { mState = state; Q_EMIT stateChanged(mState); Q_EMIT activeChanged(); } bool USSDManager::active() const { return mState != "idle"; } QString USSDManager::state() const { return mState; } ./libtelephonyservice/multimediaaccountentry.h0000644000015600001650000000300512677320771022130 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 MULTIMEDIAACCOUNTENTRY_H #define MULTIMEDIAACCOUNTENTRY_H #include "accountentry.h" class MultimediaAccountEntry : public AccountEntry { Q_OBJECT friend class AccountEntryFactory; public: // reimplemented from AccountEntry virtual AccountEntry::AccountType type() const; virtual bool connected() const; virtual bool compareIds(const QString &first, const QString &second) const; virtual QStringList addressableVCardFields(); private Q_SLOTS: // reimplemented from AccountEntry void onConnectionChanged(Tp::ConnectionPtr connection); protected: explicit MultimediaAccountEntry(const Tp::AccountPtr &account, QObject *parent = 0); }; #endif // MULTIMEDIAACCOUNTENTRY_H ./libtelephonyservice/ringtone.h0000644000015600001650000000354712677320771017177 0ustar jenkinsjenkins/* * 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 #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); QFeedbackHapticsEffect mVibrateEffect; RingtoneWorker *mWorker; QThread mThread; }; #endif // RINGTONE_H ./libtelephonyservice/greetercontacts.h0000644000015600001650000000701712677320771020542 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 #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 Q_PROPERTY(bool greeterActive READ greeterActive NOTIFY greeterActiveChanged) public: static GreeterContacts *instance(); ~GreeterContacts(); bool greeterActive() const; void setContactFilter(const QtContacts::QContactFilter &filter); bool silentMode(); QString incomingCallSound(); QString incomingMessageSound(); bool incomingMessageVibrate(); bool incomingCallVibrate(); bool dialpadSoundsEnabled(); 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_INVOKABLE void showGreeter(); Q_SIGNALS: void contactUpdated(const QtContacts::QContact &contact); void greeterActiveChanged(); private Q_SLOTS: void greeterListPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated); 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); protected: GreeterContacts(QObject *parent = 0); private: 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; QVariant mIncomingCallVibrate; QVariant mIncomingMessageVibrate; QVariant mDialpadSoundsEnabled; bool mGreeterActive; QtContacts::QContactFilter mFilter; QMap mContacts; QMutex mMutex; }; #endif // GREETERCONTACTS_H ./libtelephonyservice/accountentry.h0000644000015600001650000000647012677320771020066 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 ACCOUNTENTRY_H #define ACCOUNTENTRY_H #include #include class Protocol; typedef struct { QString busName; QString objectPath; } ConnectionInfo; class AccountEntry : public QObject { Q_OBJECT Q_PROPERTY(AccountType type READ type CONSTANT) Q_PROPERTY(QString accountId READ accountId NOTIFY accountIdChanged) Q_PROPERTY(bool active READ active NOTIFY activeChanged) Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged) Q_PROPERTY(QString status READ status NOTIFY statusChanged) Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusMessageChanged) Q_PROPERTY(QString selfContactId READ selfContactId NOTIFY selfContactIdChanged) Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) Q_PROPERTY(QStringList addressableVCardFields READ addressableVCardFields NOTIFY addressableVCardFieldsChanged) Q_PROPERTY(Protocol* protocolInfo READ protocolInfo CONSTANT) Q_ENUMS(AccountType) friend class AccountEntryFactory; public: enum AccountType { PhoneAccount, MultimediaAccount, GenericAccount }; bool ready() const; QString accountId() const; QString displayName() const; QString status() const; QString statusMessage() const; QString selfContactId() const; void setDisplayName(const QString &name); Tp::AccountPtr account() const; virtual AccountType type() const; virtual QStringList addressableVCardFields() const; virtual bool compareIds(const QString &first, const QString &second) const; virtual bool active() const; virtual bool connected() const; Protocol *protocolInfo() const; static void addAccountLabel(const QString &accountId, QString &text); Q_SIGNALS: void accountReady(); void accountIdChanged(); void activeChanged(); void displayNameChanged(); void statusChanged(); void statusMessageChanged(); void selfContactIdChanged(); void connectedChanged(); void addressableVCardFieldsChanged(); void removed(); void connectionStatusChanged(Tp::ConnectionStatus status); protected Q_SLOTS: virtual void initialize(); virtual void watchSelfContactPresence(); virtual void onConnectionChanged(Tp::ConnectionPtr connection); virtual void onSelfContactChanged(); protected: explicit AccountEntry(const Tp::AccountPtr &account, QObject *parent = 0); Tp::AccountPtr mAccount; ConnectionInfo mConnectionInfo; bool mReady; Protocol *mProtocol; }; #endif // ACCOUNTENTRY_H ./libtelephonyservice/audiooutput.h0000644000015600001650000000273412677320771017731 0ustar jenkinsjenkins/* * 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 AUDIOOUTPUT_H #define AUDIOOUTPUT_H #include struct AudioOutputDBus { QString id; QString type; QString name; }; Q_DECLARE_METATYPE(AudioOutputDBus) typedef QList AudioOutputDBusList; Q_DECLARE_METATYPE(AudioOutputDBusList) class AudioOutput : public QObject { Q_OBJECT Q_PROPERTY(QString id READ id CONSTANT) Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString type READ type CONSTANT) public: AudioOutput(const QString &id, const QString &name, const QString &type, QObject *parent = 0); QString id() const; QString name() const; QString type() const; private: QString mId; QString mName; QString mType; }; #endif // AUDIOOUTPUT_H ./libtelephonyservice/ofonoaccountentry.cpp0000644000015600001650000002374412677320771021465 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "ofonoaccountentry.h" #include "phoneutils.h" #include "telepathyhelper.h" OfonoAccountEntry::OfonoAccountEntry(const Tp::AccountPtr &account, QObject *parent) : AccountEntry(account, parent), mVoicemailCount(0), mVoicemailIndicator(false) { // the sim lock detection is based on the status message, so whenever it // changes, it might mean the sim lock state changed too connect(this, SIGNAL(statusChanged()), SIGNAL(simLockedChanged())); connect(this, SIGNAL(statusMessageChanged()), SIGNAL(networkNameChanged())); connect(this, SIGNAL(statusMessageChanged()), SIGNAL(emergencyCallsAvailableChanged())); mUssdManager = new USSDManager(this, this); } USSDManager *OfonoAccountEntry::ussdManager() const { return mUssdManager; } QStringList OfonoAccountEntry::emergencyNumbers() const { return mEmergencyNumbers; } QString OfonoAccountEntry::countryCode() const { return mCountryCode; } QString OfonoAccountEntry::voicemailNumber() const { return mVoicemailNumber; } uint OfonoAccountEntry::voicemailCount() const { return mVoicemailCount; } bool OfonoAccountEntry::voicemailIndicator() const { return mVoicemailIndicator; } QString OfonoAccountEntry::networkName() const { // FIXME: maybe it is safer to reimplement here, but for ofono accounts the status message really is the // network name return statusMessage(); } bool OfonoAccountEntry::emergencyCallsAvailable() const { if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) { return false; } QString status = mAccount->connection()->selfContact()->presence().status(); return status != "flightmode" && status != "nomodem" && status != ""; } bool OfonoAccountEntry::simLocked() const { if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) { return false; } Tp::Presence presence = mAccount->connection()->selfContact()->presence(); return (presence.type() == Tp::ConnectionPresenceTypeAway && presence.status() == "simlocked"); } QString OfonoAccountEntry::serial() const { return mSerial; } AccountEntry::AccountType OfonoAccountEntry::type() const { return AccountEntry::PhoneAccount; } bool OfonoAccountEntry::active() const { return (!mAccount.isNull() && !mAccount->connection().isNull() && !mAccount->connection()->selfContact().isNull() && mAccount->connection()->selfContact()->presence().type() != Tp::ConnectionPresenceTypeOffline); } bool OfonoAccountEntry::connected() const { return !mAccount.isNull() && !mAccount->connection().isNull() && !mAccount->connection()->selfContact().isNull() && mAccount->connection()->selfContact()->presence().type() == Tp::ConnectionPresenceTypeAvailable; } bool OfonoAccountEntry::compareIds(const QString &first, const QString &second) const { return PhoneUtils::comparePhoneNumbers(first, second) > PhoneUtils::NO_MATCH; } QStringList OfonoAccountEntry::addressableVCardFields() { return mAccount->protocolInfo().addressableVCardFields(); } void OfonoAccountEntry::onEmergencyNumbersChanged(const QStringList &numbers) { mEmergencyNumbers = numbers; Q_EMIT emergencyNumbersChanged(); } void OfonoAccountEntry::onCountryCodeChanged(const QString &countryCode) { mCountryCode = countryCode; Q_EMIT countryCodeChanged(); } void OfonoAccountEntry::onVoicemailNumberChanged(const QString &number) { mVoicemailNumber = number; Q_EMIT voicemailNumberChanged(); } void OfonoAccountEntry::onVoicemailCountChanged(uint count) { mVoicemailCount = count; Q_EMIT voicemailCountChanged(); } void OfonoAccountEntry::onVoicemailIndicatorChanged(bool visible) { mVoicemailIndicator = visible; Q_EMIT voicemailIndicatorChanged(); } void OfonoAccountEntry::onConnectionChanged(Tp::ConnectionPtr connection) { // make sure the generic code is also run AccountEntry::onConnectionChanged(connection); QDBusConnection dbusConnection = QDBusConnection::sessionBus(); if (!connection) { // disconnect any previous dbus connections if (!mConnectionInfo.objectPath.isEmpty()) { dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "EmergencyNumbersChanged", this, SLOT(onEmergencyNumbersChanged(QStringList))); // connect the voicemail number changed signal dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailNumberChanged", this, SLOT(onVoicemailNumberChanged(QString))); dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailCountChanged", this, SLOT(onVoicemailCountChanged(uint))); dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailIndicatorChanged", this, SLOT(onVoicemailIndicatorChanged(bool))); dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "CountryCodeChanged", this, SLOT(onCountryCodeChanged(QString))); } } else { // connect the emergency numbers changed signal dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "EmergencyNumbersChanged", this, SLOT(onEmergencyNumbersChanged(QStringList))); // and get the current value of the emergency numbers QDBusInterface connIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE); QDBusReply replyNumbers = connIface.call("EmergencyNumbers"); if (replyNumbers.isValid()) { mEmergencyNumbers = replyNumbers.value(); if (mReady) { Q_EMIT emergencyNumbersChanged(); } } // connect the country code changed signal dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "CountryCodeChanged", this, SLOT(onCountryCodeChanged(QString))); // and get the current value of the country code QDBusReply replyCountryCode = connIface.call("CountryCode"); if (replyCountryCode.isValid()) { mCountryCode = replyCountryCode.value(); Q_EMIT countryCodeChanged(); } // connect the voicemail number changed signal dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailNumberChanged", this, SLOT(onVoicemailNumberChanged(QString))); QDBusInterface voicemailIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE); QDBusReply replyNumber = voicemailIface.call("VoicemailNumber"); if (replyNumber.isValid()) { mVoicemailNumber = replyNumber.value(); if (mReady) { Q_EMIT voicemailNumberChanged(); } } else { qWarning() << "Could not get voicemail number!"; } // connect the voicemail count changed signal dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailCountChanged", this, SLOT(onVoicemailCountChanged(uint))); QDBusReply replyCount = voicemailIface.call("VoicemailCount"); if (replyCount.isValid()) { mVoicemailCount = replyCount.value(); if (mReady) { Q_EMIT voicemailCountChanged(); } } // connect the voicemail indicator changed signal dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailIndicatorChanged", this, SLOT(onVoicemailIndicatorChanged(bool))); QDBusReply replyIndicator = voicemailIface.call("VoicemailIndicator"); if (replyIndicator.isValid()) { mVoicemailIndicator = replyIndicator.value(); if (mReady) { Q_EMIT voicemailIndicatorChanged(); } } // and get the serial QDBusInterface ussdIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_USSD_IFACE); mSerial = ussdIface.property("Serial").toString(); if (mReady) { Q_EMIT serialChanged(); } } } ./libtelephonyservice/dbustypes.h0000644000015600001650000000254112677320771017365 0ustar jenkinsjenkins/** * 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 DBUSTYPES #define DBUSTYPES struct MessageStruct { QDBusObjectPath path; QVariantMap properties; }; struct AttachmentStruct { QString id; QString contentType; QString filePath; }; typedef QList AttachmentList; Q_DECLARE_METATYPE(AttachmentStruct) Q_DECLARE_METATYPE(AttachmentList) typedef QList MessageList; Q_DECLARE_METATYPE(MessageStruct) Q_DECLARE_METATYPE(MessageList) QDBusArgument &operator<<(QDBusArgument &argument, const AttachmentStruct &attachment); const QDBusArgument &operator>>(const QDBusArgument &argument, AttachmentStruct &attachment); #endif ./libtelephonyservice/chatmanager.cpp0000644000015600001650000002703512677320771020155 0ustar jenkinsjenkins/* * 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 "dbustypes.h" #include "accountentry.h" #include #include #include #include QDBusArgument &operator<<(QDBusArgument &argument, const AttachmentStruct &attachment) { argument.beginStructure(); argument << attachment.id << attachment.contentType << attachment.filePath; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, AttachmentStruct &attachment) { argument.beginStructure(); argument >> attachment.id >> attachment.contentType >> attachment.filePath; argument.endStructure(); return argument; } ChatManager::ChatManager(QObject *parent) : QObject(parent), mReady(TelepathyHelper::instance()->ready()) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); // wait one second for other acknowledge calls before acknowledging messages to avoid many round trips mMessagesAckTimer.setInterval(25); mMessagesAckTimer.setSingleShot(true); connect(TelepathyHelper::instance(), SIGNAL(channelObserverUnregistered()), SLOT(onChannelObserverUnregistered())); connect(TelepathyHelper::instance(), SIGNAL(setupReady()), SLOT(onTelepathyReady())); connect(&mMessagesAckTimer, SIGNAL(timeout()), SLOT(onAckTimerTriggered())); connect(TelepathyHelper::instance(), SIGNAL(setupReady()), SLOT(onConnectedChanged())); } void ChatManager::onTelepathyReady() { mReady = true; Q_FOREACH(const Tp::TextChannelPtr &channel, mPendingChannels) { onTextChannelAvailable(channel); } mPendingChannels.clear(); } void ChatManager::onChannelObserverUnregistered() { QList tmp = mChatEntries; mChatEntries.clear(); Q_EMIT chatsChanged(); Q_FOREACH(ChatEntry *entry, tmp) { // for some reason deleteLater is not working delete entry; } } void ChatManager::onConnectedChanged() { if (TelepathyHelper::instance()->ready()) { onAckTimerTriggered(); } } ChatManager *ChatManager::instance() { static ChatManager *manager = new ChatManager(); return manager; } QString ChatManager::sendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const QVariant &attachments, const QVariantMap &properties) { AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return QString(); } // check if files should be copied to a temporary location before passing them to handler bool tmpFiles = (properties.contains("x-canonical-tmp-files") && properties["x-canonical-tmp-files"].toBool()); AttachmentList newAttachments; Q_FOREACH (const QVariant &attachment, attachments.toList()) { AttachmentStruct newAttachment; QVariantList list = attachment.toList(); newAttachment.id = list.at(0).toString(); newAttachment.contentType = list.at(1).toString(); if (tmpFiles) { // we can't give the original path to handler, as it might be removed // from history database by the time it tries to read the file, // so we duplicate the file and the handler will remove it QTemporaryFile tmpFile("/tmp/XXXXX"); tmpFile.setAutoRemove(false); if (!tmpFile.open()) { qWarning() << "Unable to create a temporary file"; return QString(); } QFile originalFile(list.at(2).toString()); if (!originalFile.open(QIODevice::ReadOnly)) { qWarning() << "Attachment file not found"; return QString(); } if (tmpFile.write(originalFile.readAll()) == -1) { qWarning() << "Failed to write attachment to a temporary file"; return QString(); } newAttachment.filePath = tmpFile.fileName(); tmpFile.close(); originalFile.close(); } else { newAttachment.filePath = list.at(2).toString(); } newAttachments << newAttachment; } QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); QDBusReply reply = phoneAppHandler->call("SendMessage", account->accountId(), recipients, message, QVariant::fromValue(newAttachments), properties); if (reply.isValid()) { return reply.value(); } return QString(); } void ChatManager::onTextChannelAvailable(Tp::TextChannelPtr channel) { if (!mReady) { mPendingChannels.append(channel); return; } ChatEntry *chatEntry = new ChatEntry(channel, this); mChatEntries.append(chatEntry); 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(invalidated(Tp::DBusProxy*,const QString&, const QString&)), SLOT(onChannelInvalidated())); Q_FOREACH(const Tp::ReceivedMessage &message, channel->messageQueue()) { onMessageReceived(message); } Q_EMIT chatsChanged(); Q_EMIT chatEntryCreated(chatEntry->account()->accountId(), chatEntry->participants(), chatEntry); } void ChatManager::onChannelInvalidated() { Tp::TextChannelPtr channel(qobject_cast(sender())); ChatEntry *chatEntry = chatEntryForChannel(channel); if (chatEntry) { mChatEntries.removeAll(chatEntry); // for some reason deleteLater is not working delete chatEntry; Q_EMIT chatsChanged(); } } ChatEntry *ChatManager::chatEntryForChannel(const Tp::TextChannelPtr &channel) { Q_FOREACH (ChatEntry *chatEntry, mChatEntries) { if (channel == chatEntry->channel()) { return chatEntry; } } return NULL; } 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); } 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; } QStringList recipients; Q_FOREACH(const Tp::ContactPtr &contact, channel->groupContacts(false)) { recipients << contact->id(); } Q_EMIT messageSent(recipients, sentMessage.text()); } void ChatManager::acknowledgeMessage(const QStringList &recipients, const QString &messageId, const QString &accountId) { AccountEntry *account = NULL; if (accountId.isNull() || accountId.isEmpty()) { account = TelepathyHelper::instance()->defaultMessagingAccount(); if (!account && !TelepathyHelper::instance()->activeAccounts().isEmpty()) { account = TelepathyHelper::instance()->activeAccounts()[0]; } } else { account = TelepathyHelper::instance()->accountForId(accountId); } if (!account) { mMessagesToAck[accountId][recipients].append(messageId); return; } mMessagesAckTimer.start(); mMessagesToAck[account->accountId()][recipients].append(messageId); } void ChatManager::acknowledgeAllMessages(const QStringList &recipients, const QString &accountId) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->asyncCall("AcknowledgeAllMessages", recipients, accountId); } 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->asyncCall("AcknowledgeMessages", it2.key(), it2.value(), accountId); ++it2; } ++it; } mMessagesToAck.clear(); } QList ChatManager::chatEntries() const { return mChatEntries; } ChatEntry *ChatManager::chatEntryForParticipants(const QString &accountId, const QStringList &participants, bool create) { if (participants.count() == 0 || accountId.isEmpty()) { return NULL; } AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return NULL; } Q_FOREACH (ChatEntry *chatEntry, mChatEntries) { int participantCount = 0; Tp::Contacts contacts = chatEntry->channel()->groupContacts(false); if (participants.count() != contacts.count()) { continue; } // iterate over participants Q_FOREACH (const Tp::ContactPtr &contact, contacts) { if (account->type() == AccountEntry::PhoneAccount || account->type() == AccountEntry::MultimediaAccount) { Q_FOREACH(const QString &participant, participants) { if (PhoneUtils::comparePhoneNumbers(participant, contact->id()) > PhoneUtils::NO_MATCH) { participantCount++; break; } } continue; } if (participants.contains(contact->id())) { participantCount++; } else { break; } } if (participantCount == participants.count()) { return chatEntry; } } if (create) { QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); phoneAppHandler->call("StartChat", accountId, participants); } return NULL; } ChatEntry *ChatManager::chatEntryForChatRoom(const QString &accountId, const QVariantMap &properties, bool create) { Q_UNUSED(accountId) Q_UNUSED(properties) Q_UNUSED(create) // FIXME: implement } QQmlListProperty ChatManager::chats() { return QQmlListProperty(this, 0, chatCount, chatAt); } int ChatManager::chatCount(QQmlListProperty *p) { return ChatManager::instance()->chatEntries().count(); } ChatEntry *ChatManager::chatAt(QQmlListProperty *p, int index) { return ChatManager::instance()->chatEntries()[index]; } ./libtelephonyservice/ringtone.cpp0000644000015600001650000000771612677320771017534 0ustar jenkinsjenkins/* * 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(NULL), mCallAudioPlaylist(this), mMessageAudioPlayer(NULL) { mCallAudioPlaylist.setPlaybackMode(QMediaPlaylist::Loop); mCallAudioPlaylist.setCurrentIndex(0); } void RingtoneWorker::playIncomingCallSound() { if (!qgetenv("PA_DISABLED").isEmpty()) { return; } if (GreeterContacts::instance()->silentMode()) { return; } // force delete all media player instances stopIncomingCallSound(); // pick up the new ringtone in case it changed in the meantime mCallAudioPlaylist.addMedia(QUrl::fromLocalFile(GreeterContacts::instance()->incomingCallSound())); mCallAudioPlayer = new QMediaPlayer(this); mCallAudioPlayer->setAudioRole(QAudio::RingtoneRole); mCallAudioPlayer->setPlaylist(&mCallAudioPlaylist); mCallAudioPlayer->play(); } void RingtoneWorker::stopIncomingCallSound() { if (mCallAudioPlayer) { // WORKAROUND: if we call stop and the stream is already over, qmediaplayer plays again. mCallAudioPlayer->pause(); mCallAudioPlayer->deleteLater(); mCallAudioPlayer = NULL; } mCallAudioPlaylist.clear(); } void RingtoneWorker::playIncomingMessageSound() { if (!qgetenv("PA_DISABLED").isEmpty()) { return; } if (GreeterContacts::instance()->silentMode()) { return; } if (!mMessageAudioPlayer) { mMessageAudioPlayer = new QMediaPlayer(this); mMessageAudioPlayer->setAudioRole(QAudio::NotificationRole); } // WORKAROUND: there is a bug in qmediaplayer/(media-hub?) that never goes into Stopped mode. if (mMessageAudioPlayer->duration() == mMessageAudioPlayer->position()) { mMessageAudioPlayer->stop(); } if (mMessageAudioPlayer->state() == QMediaPlayer::PlayingState) { return; } mMessageAudioPlayer->setMedia(QUrl::fromLocalFile(GreeterContacts::instance()->incomingMessageSound())); mMessageAudioPlayer->play(); } void RingtoneWorker::stopIncomingMessageSound() { if (mMessageAudioPlayer) { mMessageAudioPlayer->pause(); mMessageAudioPlayer->deleteLater(); mMessageAudioPlayer = NULL; } } Ringtone::Ringtone(QObject *parent) : QObject(parent) { mWorker = new RingtoneWorker(); mWorker->moveToThread(&mThread); mThread.start(); mVibrateEffect.setDuration(500); } 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() { if (GreeterContacts::instance()->incomingMessageVibrate()) { mVibrateEffect.start(); } QMetaObject::invokeMethod(mWorker, "playIncomingMessageSound", Qt::QueuedConnection); } void Ringtone::stopIncomingMessageSound() { QMetaObject::invokeMethod(mWorker, "stopIncomingMessageSound", Qt::QueuedConnection); } ./libtelephonyservice/protocol.cpp0000644000015600001650000000532012677320771017535 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "protocol.h" #include #include Protocol::Protocol(const QString &name, Features features, const QString &fallbackProtocol, const QString &backgroundImage, const QString &icon, const QString &serviceName, QObject *parent) : QObject(parent), mName(name), mFeatures(features), mFallbackProtocol(fallbackProtocol), mBackgroundImage(backgroundImage), mIcon(icon), mServiceName(serviceName) { } QString Protocol::name() const { return mName; } QString Protocol::icon() const { return mIcon; } QString Protocol::serviceName() const { return mServiceName; } Protocol::Features Protocol::features() const { return mFeatures; } QString Protocol::fallbackProtocol() const { return mFallbackProtocol; } QString Protocol::backgroundImage() const { return mBackgroundImage; } Protocol *Protocol::fromFile(const QString &fileName) { QFileInfo file(fileName); if (!file.isReadable() || file.suffix() != "protocol") { return 0; } QString protocolName = file.baseName(); QSettings settings(fileName, QSettings::IniFormat); settings.setIniCodec("UTF-8"); settings.beginGroup("Protocol"); QString name = settings.value("Name", protocolName).toString(); QStringList featureList = settings.value("Features").toStringList(); Protocol::Features features; Q_FOREACH(const QString &feature, featureList) { if (feature == "text") { features |= Protocol::TextChats; } else if (feature == "voice") { features |= Protocol::VoiceCalls; } } QString fallbackProtocol = settings.value("FallbackProtocol").toString(); QString backgroundImage = settings.value("BackgroundImage").toString(); QString icon = settings.value("Icon").toString(); QString serviceName = settings.value("ServiceName").toString(); return new Protocol(name, features, fallbackProtocol, backgroundImage, icon, serviceName); } ./libtelephonyservice/contactemailaddress.h0000644000015600001650000000251712677320771021357 0ustar jenkinsjenkins/* * 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 ./libtelephonyservice/phoneutils.cpp0000644000015600001650000001121412677320771020065 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Renato Araujo Oliveira Filho * 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 "phoneutils.h" #include #include #include #include #include #include QString PhoneUtils::mCountryCode = QString(); PhoneUtils::PhoneUtils(QObject *parent) : QObject(parent) { } void PhoneUtils::setCountryCode(const QString &countryCode) { mCountryCode = countryCode; } QString PhoneUtils::countryCode() { if (!mCountryCode.isEmpty()) { return mCountryCode; } QString countryCode = QLocale::system().name().split("_").last(); if (countryCode.size() < 2) { // fallback to US if no valid country code was provided, otherwise libphonenumber // will fail to parse any numbers return QString("US"); } return countryCode; } QString PhoneUtils::normalizePhoneNumber(const QString &phoneNumber) { static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance(); if (!isPhoneNumber(phoneNumber)) { return phoneNumber; } std::string number = phoneNumber.toStdString(); phonenumberUtil->NormalizeDiallableCharsOnly(&number); return QString::fromStdString(number); } PhoneUtils::PhoneNumberMatchType PhoneUtils::comparePhoneNumbers(const QString &phoneNumberA, const QString &phoneNumberB) { static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance(); // just do a simple string comparison if we are dealing with non phone numbers if (!isPhoneNumber(phoneNumberA) || !isPhoneNumber(phoneNumberB)) { return phoneNumberA == phoneNumberB ? PhoneUtils::EXACT_MATCH : PhoneUtils::INVALID_NUMBER; } QString normalizedPhoneNumberA = normalizePhoneNumber(phoneNumberA); QString normalizedPhoneNumberB = normalizePhoneNumber(phoneNumberB); if (normalizedPhoneNumberA.size() < 7 || normalizedPhoneNumberB.size() < 7) { return normalizedPhoneNumberA == normalizedPhoneNumberB ? PhoneUtils::EXACT_MATCH : PhoneUtils::NO_MATCH; } i18n::phonenumbers::PhoneNumberUtil::MatchType match = phonenumberUtil-> IsNumberMatchWithTwoStrings(phoneNumberA.toStdString(), phoneNumberB.toStdString()); return (PhoneNumberMatchType)match; } bool PhoneUtils::isPhoneNumber(const QString &phoneNumber) { static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance(); std::string formattedNumber; i18n::phonenumbers::PhoneNumber number; i18n::phonenumbers::PhoneNumberUtil::ErrorType error; error = phonenumberUtil->Parse(phoneNumber.toStdString(), countryCode().toStdString(), &number); switch(error) { case i18n::phonenumbers::PhoneNumberUtil::INVALID_COUNTRY_CODE_ERROR: qWarning() << "Invalid country code for:" << phoneNumber; return false; case i18n::phonenumbers::PhoneNumberUtil::NOT_A_NUMBER: qWarning() << "The phone number is not a valid number:" << phoneNumber; return false; case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_AFTER_IDD: case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_NSN: case i18n::phonenumbers::PhoneNumberUtil::TOO_LONG_NSN: qWarning() << "Invalid phone number" << phoneNumber; return false; default: break; } return true; } bool PhoneUtils::isEmergencyNumber(const QString &phoneNumber, const QString &countryCode) { QString finalCode = countryCode; if (finalCode.isEmpty()) { finalCode = PhoneUtils::countryCode(); } static const i18n::phonenumbers::ShortNumberInfo short_info; return short_info.IsEmergencyNumber(normalizePhoneNumber(phoneNumber).toStdString(), finalCode.toStdString()); } ./libtelephonyservice/channelobserver.h0000644000015600001650000000437212677320771020527 0ustar jenkinsjenkins/* * 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 ./libtelephonyservice/contactutils.h0000644000015600001650000000220212677320771020051 0ustar jenkinsjenkins/* * 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 #define OFONO_UNKNOWN_NUMBER "x-ofono-unknown" #define OFONO_PRIVATE_NUMBER "x-ofono-private" QTCONTACTS_USE_NAMESPACE namespace ContactUtils { QContactManager *sharedManager(const QString &engine = "galera"); QString formatContactName(const QContact &contact); } #endif // CONTACTUTILS_H ./libtelephonyservice/contactemailaddress.cpp0000644000015600001650000000250712677320771021711 0ustar jenkinsjenkins/* * 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(); } } ./libtelephonyservice/protocolmanager.h0000644000015600001650000000705312677320771020542 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 PROTOCOLMANAGER_H #define PROTOCOLMANAGER_H #include #include #include #include "protocol.h" /// @brief Manages the list of supported protocols class ProtocolManager : public QObject { Q_OBJECT /// @brief all supported protocols Q_PROPERTY(QQmlListProperty protocols READ qmlProtocols NOTIFY protocolsChanged) /// @brief protocols that support text chats Q_PROPERTY(QQmlListProperty textProtocols READ qmlTextProtocols NOTIFY protocolsChanged) /// @brief protocols that support voice calls Q_PROPERTY(QQmlListProperty voiceProtocols READ qmlVoiceProtocols NOTIFY protocolsChanged) /// @brief the name of all supported protocols Q_PROPERTY(QStringList protocolNames READ protocolNames NOTIFY protocolsChanged) public: static ProtocolManager *instance(); /// @brief returns all supported protocols Protocols protocols() const; /// @brief return the name of all supported protocols QStringList protocolNames() const; /// @brief returns all protocols matching the given flags Protocols protocolsForFeatures(Protocol::Features features) const; /// @brief convenience function returning all protocols that support text chats Protocols textProtocols() const; /// @brief convenience function returning all protocols that support voice calls Protocols voiceProtocols() const; /// @brief returns the protocol information for the given @ref protocolName or 0 if not supported Protocol *protocolByName(const QString &protocolName) const; /// @brief checks if a given @ref protocolName is supported bool isProtocolSupported(const QString &protocolName) const; // QML protocols property helpers QQmlListProperty qmlProtocols(); static int qmlProtocolsCount(QQmlListProperty *p); static Protocol *qmlProtocolsAt(QQmlListProperty *p, int index); // QML textProtocols property helpers QQmlListProperty qmlTextProtocols(); static int qmlTextProtocolsCount(QQmlListProperty *p); static Protocol *qmlTextProtocolsAt(QQmlListProperty *p, int index); // QML voiceProtocols property helpers QQmlListProperty qmlVoiceProtocols(); static int qmlVoiceProtocolsCount(QQmlListProperty *p); static Protocol *qmlVoiceProtocolsAt(QQmlListProperty *p, int index); Q_SIGNALS: void protocolsChanged(); protected Q_SLOTS: void loadSupportedProtocols(); protected: explicit ProtocolManager(const QString &dir, QObject *parent = 0); private: Protocols mProtocols; QFileSystemWatcher mFileWatcher; QString mProtocolsDir; }; #endif // PROTOCOLMANAGER_H ./libtelephonyservice/chatentry.cpp0000644000015600001650000000704312677320771017701 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "telepathyhelper.h" #include "accountentry.h" #include "chatentry.h" #include #include #include Q_DECLARE_METATYPE(ContactChatStates) ChatEntry::ChatEntry(const Tp::TextChannelPtr &channel, QObject *parent) : QObject(parent), mChannel(channel) { qRegisterMetaType(); mAccount = TelepathyHelper::instance()->accountForConnection(mChannel->connection()); Q_FOREACH (Tp::ContactPtr contact, mChannel->groupContacts(false)) { ContactChatState *state = new ContactChatState(contact->id(), mChannel->chatState(contact)); mChatStates[contact->id()] = state; } connect(channel.data(), SIGNAL(chatStateChanged(const Tp::ContactPtr &, Tp::ChannelChatState)), this, SLOT(onChatStateChanged(const Tp::ContactPtr &,Tp::ChannelChatState))); connect(channel.data(), SIGNAL(groupMembersChanged(const Tp::Contacts &, const Tp::Contacts &, const Tp::Contacts &, const Tp::Contacts &, const Tp::Channel::GroupMemberChangeDetails &)), this, SIGNAL(participantsChanged())); } ChatEntry::~ChatEntry() { QMap tmp = mChatStates; mChatStates.clear(); Q_EMIT chatStatesChanged(); QMapIterator it(tmp); while (it.hasNext()) { it.next(); delete it.value(); } } void ChatEntry::onChatStateChanged(const Tp::ContactPtr &contact, Tp::ChannelChatState state) { if (mChatStates.contains(contact->id())) { mChatStates[contact->id()]->setState(state); return; } ContactChatState *newState = new ContactChatState(contact->id(), state); mChatStates[contact->id()] = newState; Q_EMIT chatStatesChanged(); } ChatEntry::ChatType ChatEntry::chatType() { return (ChatType)mChannel->targetHandleType(); } Tp::TextChannelPtr ChatEntry::channel() { return mChannel; } QStringList ChatEntry::participants() { QStringList participantList; Q_FOREACH (Tp::ContactPtr contact, mChannel->groupContacts(false)) { participantList << contact->id(); } return participantList; } AccountEntry *ChatEntry::account() { return mAccount; } QQmlListProperty ChatEntry::chatStates() { return QQmlListProperty(this, 0, chatStatesCount, chatStatesAt); } int ChatEntry::chatStatesCount(QQmlListProperty *p) { ChatEntry *entry = qobject_cast(p->object); if (!entry) { return 0; } return entry->mChatStates.count(); } ContactChatState *ChatEntry::chatStatesAt(QQmlListProperty *p, int index) { ChatEntry *entry = qobject_cast(p->object); if (!entry) { return 0; } return entry->mChatStates.values()[index]; } ./libtelephonyservice/protocolmanager.cpp0000644000015600001650000001052512677320771021073 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "protocolmanager.h" #include "config.h" #include ProtocolManager::ProtocolManager(const QString &dir, QObject *parent) : QObject(parent), mProtocolsDir(dir) { mFileWatcher.addPath(mProtocolsDir); connect(&mFileWatcher, SIGNAL(directoryChanged(QString)), SLOT(loadSupportedProtocols())); loadSupportedProtocols(); } ProtocolManager *ProtocolManager::instance() { static ProtocolManager self(protocolsDir()); return &self; } Protocols ProtocolManager::protocols() const { return mProtocols; } QStringList ProtocolManager::protocolNames() const { QStringList names; Q_FOREACH(const Protocol *protocol, mProtocols) { names << protocol->name(); } return names; } Protocols ProtocolManager::protocolsForFeatures(Protocol::Features features) const { Protocols filtered; Q_FOREACH(Protocol *protocol, mProtocols) { if (protocol->features() & features) { filtered << protocol; } } return filtered; } Protocols ProtocolManager::textProtocols() const { return protocolsForFeatures(Protocol::TextChats); } Protocols ProtocolManager::voiceProtocols() const { return protocolsForFeatures(Protocol::VoiceCalls); } Protocol *ProtocolManager::protocolByName(const QString &protocolName) const { Q_FOREACH(Protocol *protocol, mProtocols) { if (protocol->name() == protocolName) { return protocol; } } return 0; } bool ProtocolManager::isProtocolSupported(const QString &protocolName) const { return protocolByName(protocolName) != 0; } QQmlListProperty ProtocolManager::qmlProtocols() { return QQmlListProperty(this, 0, qmlProtocolsCount, qmlProtocolsAt); } int ProtocolManager::qmlProtocolsCount(QQmlListProperty *p) { Q_UNUSED(p); return ProtocolManager::instance()->protocols().count(); } Protocol *ProtocolManager::qmlProtocolsAt(QQmlListProperty *p, int index) { Q_UNUSED(p); return ProtocolManager::instance()->protocols()[index]; } QQmlListProperty ProtocolManager::qmlTextProtocols() { return QQmlListProperty(this, 0, qmlTextProtocolsCount, qmlTextProtocolsAt); } int ProtocolManager::qmlTextProtocolsCount(QQmlListProperty *p) { Q_UNUSED(p); return ProtocolManager::instance()->textProtocols().count(); } Protocol *ProtocolManager::qmlTextProtocolsAt(QQmlListProperty *p, int index) { Q_UNUSED(p); return ProtocolManager::instance()->textProtocols()[index]; } QQmlListProperty ProtocolManager::qmlVoiceProtocols() { return QQmlListProperty(this, 0, qmlVoiceProtocolsCount, qmlVoiceProtocolsAt); } int ProtocolManager::qmlVoiceProtocolsCount(QQmlListProperty *p) { Q_UNUSED(p); return ProtocolManager::instance()->voiceProtocols().count(); } Protocol *ProtocolManager::qmlVoiceProtocolsAt(QQmlListProperty *p, int index) { Q_UNUSED(p); return ProtocolManager::instance()->voiceProtocols()[index]; } void ProtocolManager::loadSupportedProtocols() { // clear previous entries Q_FOREACH(Protocol *protocol, mProtocols) { protocol->deleteLater(); } mProtocols.clear(); // and scan the directory QDir dir(mProtocolsDir); Q_FOREACH(QString entry, dir.entryList()) { if (!entry.endsWith(".protocol")) { continue; } Protocol *protocol = Protocol::fromFile(dir.absoluteFilePath(entry)); if (protocol) { protocol->setParent(this); mProtocols << protocol; } } Q_EMIT protocolsChanged(); } ./libtelephonyservice/ussdmanager.h0000644000015600001650000000531512677320771017656 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 AccountEntry; class USSDManager : public QObject { Q_OBJECT Q_PROPERTY(bool active READ active NOTIFY activeChanged) Q_PROPERTY(QString state READ state NOTIFY stateChanged) public: explicit USSDManager(AccountEntry *account, QObject *parent = 0); Q_INVOKABLE void initiate(const QString &command); Q_INVOKABLE void respond(const QString &reply); Q_INVOKABLE void cancel(); bool active() const; QString state() const; public Q_SLOTS: void onStateChanged(const QString &state); Q_SIGNALS: void activeChanged(); 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 Q_SLOTS: void onConnectionChanged(); private: void connectAllSignals(); void disconnectAllSignals(); QString mState; QString mBusName; QString mObjectPath; AccountEntry *mAccount; }; #endif // USSDMANAGER_H ./libtelephonyservice/telepathyhelper.cpp0000644000015600001650000004436412677320771021106 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 "accountentry.h" #include "ofonoaccountentry.h" #include "accountentryfactory.h" #include "chatmanager.h" #include "callmanager.h" #include "config.h" #include "greetercontacts.h" #include "protocolmanager.h" #include "qgsettings.h" #include #include #include #include #include template<> bool qMapLessThanKey(const QStringList &key1, const QStringList &key2) { return key1.size() > key2.size(); // sort by operator> ! } TelepathyHelper::TelepathyHelper(QObject *parent) : QObject(parent), mPendingAccountReady(0), mDefaultCallAccount(NULL), mDefaultMessagingAccount(NULL), mChannelObserver(0), mReady(false), mChannelObserverPtr(NULL), mHandlerInterface(0), mPhoneSettings(new QGSettings("com.ubuntu.phone")), mApproverInterface(0), mFlightModeInterface("org.freedesktop.URfkill", "/org/freedesktop/URfkill", "org.freedesktop.URfkill", QDBusConnection::systemBus()) { mAccountFeatures << Tp::Account::FeatureCore << Tp::Account::FeatureProtocolInfo; 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); connect(mPhoneSettings, SIGNAL(changed(QString)), this, SLOT(onSettingsChanged(QString))); connect(&mFlightModeInterface, SIGNAL(FlightModeChanged(bool)), this, SIGNAL(flightModeChanged())); mMmsGroupChat = mPhoneSettings->get("mmsGroupChatEnabled").value(); } TelepathyHelper::~TelepathyHelper() { mPhoneSettings->deleteLater(); } 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 AccountEntry *account, mAccounts) { ids << account->accountId(); } } else if (!GreeterContacts::instance()->isGreeterMode()) { // if we are in greeter mode, we should not initialize the handler to get the account IDs QDBusReply reply = handlerInterface()->call("AccountIds"); if (reply.isValid()) { ids = reply.value(); } } return ids; } void TelepathyHelper::setMmsGroupChat(bool enable) { mPhoneSettings->set("mmsGroupChatEnabled", enable); } bool TelepathyHelper::mmsGroupChat() { return mMmsGroupChat; } bool TelepathyHelper::flightMode() { QDBusReply reply = mFlightModeInterface.call("IsFlightMode"); if (reply.isValid()) { return reply; } return false; } void TelepathyHelper::setFlightMode(bool value) { mFlightModeInterface.asyncCall("FlightMode", value); } QList TelepathyHelper::accounts() const { return mAccounts; } QList TelepathyHelper::activeAccounts() const { QList activeAccountList; Q_FOREACH(AccountEntry *account, mAccounts) { if (account->active() && account->type() != AccountEntry::MultimediaAccount) { activeAccountList << account; } } return activeAccountList; } bool TelepathyHelper::multiplePhoneAccounts() const { int count = 0; Q_FOREACH(AccountEntry *account, phoneAccounts()) { if (account->active()) { count++; } } return (count > 1); } QList TelepathyHelper::phoneAccounts() const { QList accountList; Q_FOREACH(AccountEntry *account, mAccounts) { if (account->type() == AccountEntry::PhoneAccount) { accountList << account; } } return accountList; } QQmlListProperty TelepathyHelper::qmlPhoneAccounts() { return QQmlListProperty(this, 0, phoneAccountsCount, phoneAccountAt); } QQmlListProperty TelepathyHelper::qmlAccounts() { return QQmlListProperty(this, 0, accountsCount, accountAt); } QQmlListProperty TelepathyHelper::qmlActiveAccounts() { return QQmlListProperty(this, 0, activeAccountsCount, activeAccountAt); } ChannelObserver *TelepathyHelper::channelObserver() const { return mChannelObserver; } QDBusInterface *TelepathyHelper::handlerInterface() const { // delay the loading of the handler interface, as it seems this is triggering // the dbus activation of the handler process if (!mHandlerInterface) { mHandlerInterface = new QDBusInterface("com.canonical.TelephonyServiceHandler", "/com/canonical/TelephonyServiceHandler", "com.canonical.TelephonyServiceHandler", QDBusConnection::sessionBus(), const_cast(this)); } return mHandlerInterface; } QDBusInterface *TelepathyHelper::approverInterface() const { if (!mApproverInterface) { mApproverInterface = new QDBusInterface("org.freedesktop.Telepathy.Client.TelephonyServiceApprover", "/com/canonical/Approver", "com.canonical.TelephonyServiceApprover", QDBusConnection::sessionBus(), const_cast(this)); } return mApproverInterface; } bool TelepathyHelper::ready() const { return mReady; } void TelepathyHelper::registerChannelObserver(const QString &observerName) { QString name = observerName; if (name.isEmpty()) { name = "TelephonyPluginObserver"; } if (mChannelObserver) { unregisterClient(mChannelObserver); } mChannelObserver = new ChannelObserver(this); mChannelObserverPtr = Tp::AbstractClientPtr(mChannelObserver); if (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() { unregisterClient(mChannelObserver); mChannelObserver->deleteLater(); mChannelObserverPtr.reset(); mChannelObserver = NULL; Q_EMIT channelObserverUnregistered(); } void TelepathyHelper::setupAccountEntry(AccountEntry *entry) { connect(entry, SIGNAL(connectedChanged()), SIGNAL(activeAccountsChanged())); connect(entry, SIGNAL(accountReady()), SLOT(onAccountReady())); connect(entry, SIGNAL(removed()), SLOT(onAccountRemoved())); OfonoAccountEntry *ofonoAccount = qobject_cast(entry); if (ofonoAccount) { connect(ofonoAccount, SIGNAL(emergencyCallsAvailableChanged()), SIGNAL(emergencyCallsAvailableChanged())); } } bool 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 ); } } return succeeded; } bool TelepathyHelper::unregisterClient(Tp::AbstractClient *client) { Tp::AbstractClientPtr clientPtr(client); if (clientPtr) { return mClientRegistrar->unregisterClient(clientPtr); } return false; } AccountEntry *TelepathyHelper::accountForConnection(const Tp::ConnectionPtr &connection) const { if (connection.isNull()) { return 0; } Q_FOREACH(AccountEntry *accountEntry, mAccounts) { if (accountEntry->account()->connection() == connection) { return accountEntry; } } return 0; } AccountEntry *TelepathyHelper::accountForId(const QString &accountId) const { Q_FOREACH(AccountEntry *account, mAccounts) { if (account->accountId() == accountId) { return account; } } return 0; } 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; } int TelepathyHelper::phoneAccountsCount(QQmlListProperty *p) { Q_UNUSED(p) return TelepathyHelper::instance()->phoneAccounts().count(); } int TelepathyHelper::accountsCount(QQmlListProperty *p) { Q_UNUSED(p) return TelepathyHelper::instance()->accounts().count(); } AccountEntry *TelepathyHelper::phoneAccountAt(QQmlListProperty *p, int index) { Q_UNUSED(p) return TelepathyHelper::instance()->phoneAccounts()[index]; } AccountEntry *TelepathyHelper::accountAt(QQmlListProperty *p, int index) { Q_UNUSED(p) return TelepathyHelper::instance()->accounts()[index]; } int TelepathyHelper::activeAccountsCount(QQmlListProperty *p) { return TelepathyHelper::instance()->activeAccounts().count(); } AccountEntry *TelepathyHelper::activeAccountAt(QQmlListProperty *p, int index) { return TelepathyHelper::instance()->activeAccounts()[index]; } void TelepathyHelper::onAccountRemoved() { AccountEntry *account = qobject_cast(sender()); if (!account) { return; } mAccounts.removeAll(account); Q_EMIT accountIdsChanged(); Q_EMIT accountsChanged(); Q_EMIT phoneAccountsChanged(); Q_EMIT activeAccountsChanged(); onSettingsChanged("defaultSimForMessages"); onSettingsChanged("defaultSimForCalls"); } void TelepathyHelper::onNewAccount(const Tp::AccountPtr &account) { AccountEntry *accountEntry = AccountEntryFactory::createEntry(account, this); setupAccountEntry(accountEntry); mAccounts.append(accountEntry); QMap sortedOfonoAccounts; QMap sortedOtherAccounts; Q_FOREACH(AccountEntry *account, mAccounts) { QString modemObjName = account->account()->parameters().value("modem-objpath").toString(); if (modemObjName.isEmpty()) { sortedOtherAccounts[account->accountId()] = account; } else { sortedOfonoAccounts[modemObjName] = account; } } mAccounts = QList() << sortedOfonoAccounts.values() << sortedOtherAccounts.values() ; Q_EMIT accountIdsChanged(); Q_EMIT accountsChanged(); Q_EMIT phoneAccountsChanged(); Q_EMIT activeAccountsChanged(); onSettingsChanged("defaultSimForMessages"); onSettingsChanged("defaultSimForCalls"); Q_EMIT accountAdded(accountEntry); } void TelepathyHelper::onAccountManagerReady(Tp::PendingOperation *op) { // if the account manager ready job returns an error, just fail silently if (op->isError()) { qCritical() << "Failed to prepare Tp::AccountManager" << op->errorName() << op->errorMessage(); return; } // handle dynamic account adding and removing connect(mAccountManager.data(), SIGNAL(newAccount(const Tp::AccountPtr &)), SLOT(onNewAccount(const Tp::AccountPtr &))); Tp::AccountSetPtr accountSet; // try to find an account of the one of supported protocols Q_FOREACH(const QString &protocol, ProtocolManager::instance()->protocolNames()) { accountSet = mAccountManager->accountsByProtocol(protocol); Q_FOREACH(const Tp::AccountPtr &account, accountSet->accounts()) { onNewAccount(account); } } // get the number of pending accounts to be processed first mPendingAccountReady = mAccounts.count(); if (mPendingAccountReady == 0) { mReady = true; Q_EMIT setupReady(); return; } Q_EMIT accountIdsChanged(); Q_EMIT accountsChanged(); Q_EMIT phoneAccountsChanged(); Q_EMIT activeAccountsChanged(); onSettingsChanged("defaultSimForMessages"); onSettingsChanged("defaultSimForCalls"); } void TelepathyHelper::onAccountReady() { if (mReady) { return; } mPendingAccountReady--; if (mPendingAccountReady == 0) { mReady = true; Q_EMIT setupReady(); } } AccountEntry *TelepathyHelper::defaultMessagingAccount() const { return mDefaultMessagingAccount; } AccountEntry *TelepathyHelper::defaultCallAccount() const { return mDefaultCallAccount; } void TelepathyHelper::setDefaultAccount(AccountType type, AccountEntry* account) { if (!account) { return; } QString modemObjName = account->account()->parameters().value("modem-objpath").toString(); if (!modemObjName.isEmpty()) { if (type == Call) { mPhoneSettings->set("defaultSimForCalls", modemObjName); } else if (type == Messaging) { mPhoneSettings->set("defaultSimForMessages", modemObjName); } } } bool TelepathyHelper::emergencyCallsAvailable() const { // FIXME: this is really ofono specific, so maybe move somewhere else? Q_FOREACH(const AccountEntry *account, mAccounts) { const OfonoAccountEntry *ofonoAccount = qobject_cast(account); if (ofonoAccount && ofonoAccount->emergencyCallsAvailable()) { return true; } } return false; } void TelepathyHelper::onSettingsChanged(const QString &key) { if (key == "defaultSimForMessages") { QString defaultSim = mPhoneSettings->get("defaultSimForMessages").value(); if (defaultSim == "ask") { mDefaultMessagingAccount = NULL; Q_EMIT defaultMessagingAccountChanged(); return; } Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { QString modemObjName = account->account()->parameters().value("modem-objpath").toString(); if (modemObjName == defaultSim) { mDefaultMessagingAccount = account; Q_EMIT defaultMessagingAccountChanged(); return; } } mDefaultMessagingAccount = NULL; Q_EMIT defaultMessagingAccountChanged(); } else if (key == "defaultSimForCalls") { QString defaultSim = mPhoneSettings->get("defaultSimForCalls").value(); if (defaultSim == "ask") { mDefaultCallAccount = NULL; Q_EMIT defaultCallAccountChanged(); return; } Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { QString modemObjName = account->account()->parameters().value("modem-objpath").toString(); if (modemObjName == defaultSim) { mDefaultCallAccount = account; Q_EMIT defaultCallAccountChanged(); return; } } mDefaultCallAccount = NULL; Q_EMIT defaultCallAccountChanged(); } else if (key == "mmsGroupChatEnabled") { mMmsGroupChat = mPhoneSettings->get("mmsGroupChatEnabled").value(); Q_EMIT mmsGroupChatChanged(); } } void TelepathyHelper::unlockSimCards() const { QDBusInterface connectivityIface("com.ubuntu.connectivity1", "/com/ubuntu/connectivity1/Private", "com.ubuntu.connectivity1.Private"); connectivityIface.asyncCall("UnlockAllModems"); } ./libtelephonyservice/callnotification.h0000644000015600001650000000255512677320771020672 0ustar jenkinsjenkins/* * 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 #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); void clearCallNotification(const QString &participantId, const QString &accountId); private: explicit CallNotification(QObject *parent = 0); QDBusInterface mIndicatorIface; }; #endif // CALLNOTIFICATION_H ./libtelephonyservice/telepathyhelper.h0000644000015600001650000001425212677320771020544 0ustar jenkinsjenkins/* * 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 #include "channelobserver.h" #define CANONICAL_TELEPHONY_VOICEMAIL_IFACE "com.canonical.Telephony.Voicemail" #define CANONICAL_TELEPHONY_AUDIOOUTPUTS_IFACE "com.canonical.Telephony.AudioOutputs" #define CANONICAL_TELEPHONY_USSD_IFACE "com.canonical.Telephony.USSD" #define CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE "com.canonical.Telephony.EmergencyMode" template<> bool qMapLessThanKey(const QStringList &key1, const QStringList &key2); class AccountEntry; class QGSettings; class TelepathyHelper : public QObject { Q_OBJECT Q_PROPERTY(bool ready READ ready NOTIFY setupReady) Q_PROPERTY(QStringList accountIds READ accountIds NOTIFY accountIdsChanged) Q_PROPERTY(QQmlListProperty accounts READ qmlAccounts NOTIFY accountsChanged) Q_PROPERTY(QQmlListProperty phoneAccounts READ qmlPhoneAccounts NOTIFY phoneAccountsChanged) Q_PROPERTY(QQmlListProperty activeAccounts READ qmlActiveAccounts NOTIFY activeAccountsChanged) Q_PROPERTY(AccountEntry *defaultMessagingAccount READ defaultMessagingAccount NOTIFY defaultMessagingAccountChanged) Q_PROPERTY(AccountEntry *defaultCallAccount READ defaultCallAccount NOTIFY defaultCallAccountChanged) Q_PROPERTY(bool flightMode READ flightMode WRITE setFlightMode NOTIFY flightModeChanged) Q_PROPERTY(bool mmsGroupChat READ mmsGroupChat WRITE setMmsGroupChat NOTIFY mmsGroupChatChanged) Q_PROPERTY(bool emergencyCallsAvailable READ emergencyCallsAvailable NOTIFY emergencyCallsAvailableChanged) Q_ENUMS(AccountType) public: enum AccountType { Call, Messaging }; ~TelepathyHelper(); static TelepathyHelper *instance(); QList accounts() const; QList phoneAccounts() const; QList activeAccounts() const; QQmlListProperty qmlAccounts(); QQmlListProperty qmlPhoneAccounts(); QQmlListProperty qmlActiveAccounts(); ChannelObserver *channelObserver() const; QDBusInterface *handlerInterface() const; QDBusInterface *approverInterface() const; AccountEntry *defaultMessagingAccount() const; AccountEntry *defaultCallAccount() const; bool mmsGroupChat(); void setMmsGroupChat(bool value); bool flightMode(); void setFlightMode(bool value); bool ready() const; QStringList accountIds(); AccountEntry *accountForConnection(const Tp::ConnectionPtr &connection) const; Q_INVOKABLE AccountEntry *accountForId(const QString &accountId) const; Q_INVOKABLE void setDefaultAccount(AccountType type, AccountEntry* account); bool emergencyCallsAvailable() const; Q_INVOKABLE void unlockSimCards() const; bool multiplePhoneAccounts() const; bool registerClient(Tp::AbstractClient *client, QString name); bool unregisterClient(Tp::AbstractClient *client); // pre-populated channel class specs for conferences static Tp::ChannelClassSpec audioConferenceSpec(); // QQmlListProperty helpers static int accountsCount(QQmlListProperty *p); static AccountEntry *accountAt(QQmlListProperty *p, int index); static int activeAccountsCount(QQmlListProperty *p); static AccountEntry *activeAccountAt(QQmlListProperty *p, int index); static int phoneAccountsCount(QQmlListProperty *p); static AccountEntry *phoneAccountAt(QQmlListProperty *p, int index); Q_SIGNALS: void channelObserverCreated(ChannelObserver *observer); void channelObserverUnregistered(); void accountIdsChanged(); void accountsChanged(); void accountAdded(AccountEntry *account); void phoneAccountsChanged(); void activeAccountsChanged(); void setupReady(); void defaultMessagingAccountChanged(); void defaultCallAccountChanged(); void flightModeChanged(); void emergencyCallsAvailableChanged(); void mmsGroupChatChanged(); public Q_SLOTS: Q_INVOKABLE void registerChannelObserver(const QString &observerName = QString::null); Q_INVOKABLE void unregisterChannelObserver(); protected: explicit TelepathyHelper(QObject *parent = 0); void setupAccountEntry(AccountEntry *entry); private Q_SLOTS: void onAccountManagerReady(Tp::PendingOperation *op); void onAccountReady(); void onNewAccount(const Tp::AccountPtr &account); void onAccountRemoved(); void onSettingsChanged(const QString&); private: Tp::AccountManagerPtr mAccountManager; Tp::Features mAccountManagerFeatures; Tp::Features mAccountFeatures; Tp::Features mContactFeatures; Tp::Features mConnectionFeatures; Tp::ClientRegistrarPtr mClientRegistrar; QList mAccounts; int mPendingAccountReady; AccountEntry *mDefaultCallAccount; AccountEntry *mDefaultMessagingAccount; ChannelObserver *mChannelObserver; bool mReady; Tp::AbstractClientPtr mChannelObserverPtr; bool mMmsGroupChat; mutable QDBusInterface *mHandlerInterface; QGSettings *mPhoneSettings; mutable QDBusInterface *mApproverInterface; QDBusInterface mFlightModeInterface; }; #endif // TELEPATHYHELPER_H ./libtelephonyservice/accountentry.cpp0000644000015600001650000001471512677320771020422 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 #include #include "accountentry.h" #include "protocolmanager.h" #include "telepathyhelper.h" Q_DECLARE_METATYPE(Tp::ConnectionPtr); AccountEntry::AccountEntry(const Tp::AccountPtr &account, QObject *parent) : QObject(parent), mAccount(account), mReady(false), mProtocol(0) { qRegisterMetaType(); initialize(); } bool AccountEntry::ready() const { return mReady; } QString AccountEntry::accountId() const { if (mAccount.isNull()) { return QString::null; } return mAccount->uniqueIdentifier(); } bool AccountEntry::active() const { return (!mAccount.isNull() && !mAccount->connection().isNull() && !mAccount->connection()->selfContact().isNull() && mAccount->connection()->selfContact()->presence().type() != Tp::ConnectionPresenceTypeOffline); } QString AccountEntry::displayName() const { if (mAccount.isNull()) { return QString::null; } return mAccount->displayName(); } QString AccountEntry::status() const { if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) { return QString::null; } Tp::Presence presence = mAccount->connection()->selfContact()->presence(); return presence.status(); } QString AccountEntry::statusMessage() const { if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) { return QString::null; } Tp::Presence presence = mAccount->connection()->selfContact()->presence(); return presence.statusMessage(); } QString AccountEntry::selfContactId() const { if (!mAccount.isNull() && !mAccount->connection().isNull() && !mAccount->connection()->selfContact().isNull()) { return mAccount->connection()->selfContact()->id(); } return QString(); } void AccountEntry::setDisplayName(const QString &name) { if (mAccount.isNull()) { return; } mAccount->setDisplayName(name); } bool AccountEntry::connected() const { return !mAccount.isNull() && !mAccount->connection().isNull() && mAccount->connection()->status() == Tp::ConnectionStatusConnected; } Tp::AccountPtr AccountEntry::account() const { return mAccount; } AccountEntry::AccountType AccountEntry::type() const { return GenericAccount; } QStringList AccountEntry::addressableVCardFields() const { return mAccount->protocolInfo().addressableVCardFields(); } bool AccountEntry::compareIds(const QString &first, const QString &second) const { return first == second; } Protocol *AccountEntry::protocolInfo() const { return mProtocol; } void AccountEntry::initialize() { if (mAccount.isNull()) { return; } mProtocol = ProtocolManager::instance()->protocolByName(mAccount->protocolName()); // propagate the display name changes connect(mAccount.data(), SIGNAL(removed()), SIGNAL(removed())); // propagate the display name changes connect(mAccount.data(), SIGNAL(displayNameChanged(QString)), SIGNAL(displayNameChanged())); connect(mAccount.data(), SIGNAL(connectionChanged(Tp::ConnectionPtr)), SLOT(onConnectionChanged(Tp::ConnectionPtr))); connect(mAccount.data(), SIGNAL(connectionStatusChanged(Tp::ConnectionStatus)), SIGNAL(connectionStatusChanged(Tp::ConnectionStatus))); connect(this, SIGNAL(connectedChanged()), SIGNAL(activeChanged())); Q_EMIT accountIdChanged(); // we have to postpone this call to give telepathyhelper time to connect the signals QMetaObject::invokeMethod(this, "onConnectionChanged", Qt::QueuedConnection, Q_ARG(Tp::ConnectionPtr, mAccount->connection())); QMetaObject::invokeMethod(this, "accountReady", Qt::QueuedConnection); mReady = true; } void AccountEntry::watchSelfContactPresence() { if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) { return; } connect(mAccount->connection()->selfContact().data(), SIGNAL(presenceChanged(Tp::Presence)), SIGNAL(statusChanged())); connect(mAccount->connection()->selfContact().data(), SIGNAL(presenceChanged(Tp::Presence)), SIGNAL(statusMessageChanged())); connect(mAccount->connection()->selfContact().data(), SIGNAL(presenceChanged(Tp::Presence)), SIGNAL(activeChanged())); connect(mAccount->connection()->selfContact().data(), SIGNAL(presenceChanged(Tp::Presence)), SIGNAL(connectedChanged())); } void AccountEntry::onSelfContactChanged() { watchSelfContactPresence(); Q_EMIT connectedChanged(); Q_EMIT selfContactIdChanged(); } void AccountEntry::onConnectionChanged(Tp::ConnectionPtr connection) { if (!connection.isNull()) { mConnectionInfo.busName = connection->busName(); mConnectionInfo.objectPath = connection->objectPath(); connect(connection.data(), SIGNAL(selfContactChanged()), SLOT(onSelfContactChanged())); watchSelfContactPresence(); } else { mConnectionInfo.busName = QString(); mConnectionInfo.objectPath = QString(); } Q_EMIT connectedChanged(); Q_EMIT selfContactIdChanged(); } void AccountEntry::addAccountLabel(const QString &accountId, QString &text) { AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (account && account->type() == AccountEntry::PhoneAccount && TelepathyHelper::instance()->multiplePhoneAccounts()) { text += QString(" - [%1]").arg(account->displayName()); } } ./libtelephonyservice/tonegenerator.h0000644000015600001650000000325212677320771020217 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Martti Piirainen * * 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 TONEGENERATOR_H #define TONEGENERATOR_H #include class QTimer; static const int DTMF_LOCAL_PLAYBACK_DURATION = 200; /* in milliseconds */ static const int WAITING_PLAYBACK_DURATION = 8000; /* in milliseconds */ static const uint WAITING_TONE = 79; static const uint CALL_ENDED_TONE = 257; class ToneGenerator : public QObject { Q_OBJECT public: ~ToneGenerator(); static ToneGenerator *instance(); public Q_SLOTS: /** * Valid tones: 0..9 (number keys), 10 (*), 11 (#) */ void playDTMFTone(uint key); void playWaitingTone(); void stopWaitingTone(); void playCallEndedTone(); private Q_SLOTS: void stopTone(); void stopDTMFTone(); bool startEventTone(uint key); private: explicit ToneGenerator(QObject *parent = 0); QTimer* mDTMFPlaybackTimer; QTimer* mWaitingPlaybackTimer; }; #endif // TONEGENERATOR_H ./libtelephonyservice/channelobserver.cpp0000644000015600001650000001575612677320771021072 0ustar jenkinsjenkins/* * 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 "protocolmanager.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(); specList << Tp::ChannelClassSpec::unnamedTextChat(); 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(connection) Q_UNUSED(dispatchOperation) Q_UNUSED(requestsSatisfied) Q_UNUSED(observerInfo) if (!ProtocolManager::instance()->isProtocolSupported(account->protocolName())) { context->setFinishedWithError(TP_QT_ERROR_NOT_CAPABLE, "The account for this request is not supported."); return; } 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(); } ./libtelephonyservice/contactutils.cpp0000644000015600001650000000322712677320771020414 0ustar jenkinsjenkins/* * 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) { QString finalEngine = engine; if (!qgetenv("TELEPHONY_SERVICE_TEST").isEmpty()) { finalEngine = "memory"; } static QContactManager *instance = new QContactManager(finalEngine); 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; } } ./libtelephonyservice/greetercontacts.cpp0000644000015600001650000003775712677320771021113 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 #include QTCONTACTS_USE_NAMESPACE GreeterContacts *GreeterContacts::instance() { static GreeterContacts *self = new GreeterContacts(); return self; } 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(greeterListPropertiesChanged(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; } // get the current value of greeter's isActive property connection = QDBusConnection::sessionBus(); QDBusInterface greeterPropsIface("com.canonical.UnityGreeter", "/", "org.freedesktop.DBus.Properties"); QDBusReply reply = greeterPropsIface.call("Get", "com.canonical.UnityGreeter", "IsActive"); mGreeterActive = reply.isValid() && reply.value().toBool(); connection.connect("com.canonical.UnityGreeter", "/", "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(greeterPropertiesChanged(QString, QVariantMap, QStringList))); } GreeterContacts::~GreeterContacts() { } bool GreeterContacts::greeterActive() const { return mGreeterActive; } bool GreeterContacts::isGreeterMode() { return qgetenv("XDG_SESSION_CLASS") == "greeter"; } void GreeterContacts::setContactFilter(const QContactFilter &filter) { QMutexLocker locker(&mMutex); mFilter = filter; signalIfNeeded(); } bool GreeterContacts::silentMode() { QMutexLocker locker(&mMutex); if (!mSilentMode.isValid()) { mSilentMode = getUserValue("com.ubuntu.touch.AccountsService.Sound", "SilentMode"); } return mSilentMode.toBool(); } QString GreeterContacts::incomingCallSound() { QMutexLocker locker(&mMutex); if (!mIncomingCallSound.isValid()) { mIncomingCallSound = getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingCallSound"); } return mIncomingCallSound.toString(); } QString GreeterContacts::incomingMessageSound() { QMutexLocker locker(&mMutex); if (!mIncomingMessageSound.isValid()) { mIncomingMessageSound = getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingMessageSound"); } return mIncomingMessageSound.toString(); } bool GreeterContacts::incomingCallVibrate() { if (silentMode()) { QMutexLocker locker(&mMutex); return getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingCallVibrateSilentMode").toBool(); } QMutexLocker locker(&mMutex); if (!mIncomingCallVibrate.isValid()) { mIncomingCallVibrate = getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingCallVibrate"); } return mIncomingCallVibrate.toBool(); } bool GreeterContacts::incomingMessageVibrate() { if (silentMode()) { QMutexLocker locker(&mMutex); return getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingMessageVibrateSilentMode").toBool(); } QMutexLocker locker(&mMutex); if (!mIncomingMessageVibrate.isValid()) { mIncomingMessageVibrate = getUserValue("com.ubuntu.touch.AccountsService.Sound", "IncomingMessageVibrate"); } return mIncomingMessageVibrate.toBool(); } bool GreeterContacts::dialpadSoundsEnabled() { QMutexLocker locker(&mMutex); if (!mDialpadSoundsEnabled.isValid()) { mDialpadSoundsEnabled = getUserValue("com.ubuntu.touch.AccountsService.Sound", "DialpadSoundsEnabled"); } return mDialpadSoundsEnabled.toBool(); } void GreeterContacts::greeterListPropertiesChanged(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(); } } } void GreeterContacts::greeterPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated) { if (interface == "com.canonical.UnityGreeter") { if (changed.contains("IsActive")) { mGreeterActive = changed.value("IsActive").toBool(); Q_EMIT greeterActiveChanged(); } } } 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(); } return QVariant(); } 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); checkUpdatedValue(changed, invalidated, "IncomingMessageVibrate", mIncomingMessageVibrate); checkUpdatedValue(changed, invalidated, "IncomingCallVibrate", mIncomingCallVibrate); checkUpdatedValue(changed, invalidated, "DialpadSoundsEnabled", mDialpadSoundsEnabled); } } 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(); mIncomingCallVibrate = QVariant(); mIncomingMessageVibrate = QVariant(); mDialpadSoundsEnabled = 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; } void GreeterContacts::showGreeter() { QMutexLocker locker(&mMutex); QDBusInterface iface("com.canonical.UnityGreeter", "/", "com.canonical.UnityGreeter", QDBusConnection::sessionBus()); iface.call("ShowGreeter"); } ./libtelephonyservice/callentry.h0000644000015600001650000001364112677320771017343 0ustar jenkinsjenkins/* * 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 #include "audiooutput.h" class AccountEntry; 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) Q_PROPERTY(AccountEntry *account READ account) // FIXME: replace this by a more generic identifier to support accounts not based on phone numbers // 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(QString dtmfString READ dtmfString NOTIFY dtmfStringChanged) Q_PROPERTY(QString activeAudioOutput READ activeAudioOutput WRITE setActiveAudioOutput NOTIFY activeAudioOutputChanged) Q_PROPERTY(QQmlListProperty audioOutputs READ audioOutputs NOTIFY audioOutputsChanged) 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; void setActiveAudioOutput(const QString &id); QString activeAudioOutput() const; QQmlListProperty audioOutputs(); 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; AccountEntry *account() const; // QQmlListProperty helpers static int callsCount(QQmlListProperty *p); static CallEntry* callAt(QQmlListProperty *p, int index); void addCall(CallEntry *call); static int audioOutputsCount(QQmlListProperty *p); static AudioOutput* audioOutputsAt(QQmlListProperty *p, int index); protected Q_SLOTS: void onCallStateChanged(Tp::CallState state); void onCallFlagsChanged(Tp::CallFlags flags); void onCallLocalHoldStateChanged(Tp::LocalHoldState state, Tp::LocalHoldStateReason reason); void onMutedChanged(uint state); void onCallPropertiesChanged(const QString &objectPath, const QVariantMap &properties); void onAudioOutputsChanged(const AudioOutputDBusList &outputs); void onActiveAudioOutputChanged(const QString &id); // conference related stuff void onConferenceChannelMerged(const Tp::ChannelPtr &channel); void onConferenceChannelRemoved(const Tp::ChannelPtr &channel, const Tp::Channel::GroupMemberChangeDetails &details); void onInternalCallEnded(); // handler error notification void onCallHoldingFailed(const QString &objectPath); 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 activeAudioOutputChanged(); void audioOutputsChanged(); void callHoldingFailed(); private: void refreshProperties(); AccountEntry *mAccount; Tp::CallChannelPtr mChannel; QDBusInterface mMuteInterface; QDBusInterface mAudioOutputsInterface; QMap mProperties; bool mVoicemail; bool mLocalMuteState; QDateTime mActiveTimestamp; QList mCalls; QList mAudioOutputs; QString mActiveAudioOutput; }; #endif // CALLENTRY_H ./libtelephonyservice/chatentry.h0000644000015600001650000000620412677320771017344 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 CHATENTRY_H #define CHATENTRY_H #include #include class AccountEntry; class ContactChatState : public QObject { Q_OBJECT Q_PROPERTY(QString contactId READ contactId CONSTANT) Q_PROPERTY(int state READ state WRITE setState NOTIFY stateChanged) public: ContactChatState(const QString &contactId, int state) : mContactId(contactId), mState(state) {} QString contactId() { return mContactId; } int state() { return mState; } void setState(int state) { mState = state; Q_EMIT stateChanged(); } Q_SIGNALS: void stateChanged(); private: QString mContactId; int mState; }; typedef QList ContactChatStates; class ChatEntry : public QObject { Q_OBJECT Q_PROPERTY(AccountEntry* account READ account CONSTANT) Q_PROPERTY(ChatType chatType READ chatType CONSTANT) Q_PROPERTY(QStringList participants READ participants NOTIFY participantsChanged) Q_PROPERTY(QQmlListProperty chatStates READ chatStates NOTIFY chatStatesChanged) Q_ENUMS(ChatType) Q_ENUMS(ChatState) public: enum ChatType { ChatTypeNone = Tp::HandleTypeNone, ChatTypeContact = Tp::HandleTypeContact, ChatTypeRoom = Tp::HandleTypeRoom }; enum ChatState { ChannelChatStateGone = Tp::ChannelChatStateGone, ChannelChatStateInactive = Tp::ChannelChatStateInactive, ChannelChatStateActive = Tp::ChannelChatStateActive, ChannelChatStatePaused = Tp::ChannelChatStatePaused, ChannelChatStateComposing = Tp::ChannelChatStateComposing }; explicit ChatEntry(const Tp::TextChannelPtr &channel, QObject *parent = 0); ~ChatEntry(); Tp::TextChannelPtr channel(); AccountEntry *account(); QQmlListProperty chatStates(); QStringList participants(); ChatType chatType(); static int chatStatesCount(QQmlListProperty *p); static ContactChatState *chatStatesAt(QQmlListProperty *p, int index); private Q_SLOTS: void onChatStateChanged(const Tp::ContactPtr &contact, Tp::ChannelChatState state); Q_SIGNALS: void chatStatesChanged(); void participantsChanged(); private: AccountEntry *mAccount; Tp::TextChannelPtr mChannel; QMap mChatStates; }; #endif // CHATENTRY_H ./libtelephonyservice/audiooutput.cpp0000644000015600001650000000213312677320771020255 0ustar jenkinsjenkins/* * 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 "audiooutput.h" AudioOutput::AudioOutput(const QString& id, const QString& name, const QString& type, QObject *parent) : QObject(parent), mId(id), mName(name), mType(type) { } QString AudioOutput::id() const { return mId; } QString AudioOutput::name() const { return mName; } QString AudioOutput::type() const { return mType; } ./libtelephonyservice/protocol.h0000644000015600001650000000512312677320771017203 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 PROTOCOL_H #define PROTOCOL_H #include /// @brief describes one protocol and the features it supports class Protocol : public QObject { Q_OBJECT /// @brief the name of the protocol Q_PROPERTY(QString name READ name CONSTANT) /// @brief the features this protocol supports Q_PROPERTY(Features features READ features CONSTANT) /// @brief the fallback protocol to be used for operations that support it (mainly text features) Q_PROPERTY(QString fallbackProtocol READ fallbackProtocol CONSTANT) /// @brief the file path for the image that represents this protocol Q_PROPERTY(QString backgroundImage READ backgroundImage CONSTANT) /// @brief the file path for the image that represents this protocol Q_PROPERTY(QString icon READ icon CONSTANT) /// @brief the title that represents this protocol Q_PROPERTY(QString serviceName READ serviceName CONSTANT) public: enum Feature { TextChats = 0x1, VoiceCalls = 0x2 }; Q_DECLARE_FLAGS(Features, Feature) QString name() const; Features features() const; QString fallbackProtocol() const; QString backgroundImage() const; QString icon() const; QString serviceName() const; static Protocol *fromFile(const QString &fileName); friend class ProtocolManager; protected: explicit Protocol(const QString &name, Features features, const QString &fallbackProtocol = QString::null, const QString &backgroundImage = QString::null, const QString &icon = QString::null, const QString &serviceName = QString::null, QObject *parent = 0); private: QString mName; Features mFeatures; QString mFallbackProtocol; QString mBackgroundImage; QString mIcon; QString mServiceName; }; typedef QList Protocols; #endif // PROTOCOL_H ./libtelephonyservice/CMakeLists.txt0000644000015600001650000000241312677320771017730 0ustar jenkinsjenkinsset(library_SRCS accountentry.cpp accountentryfactory.cpp audiooutput.cpp applicationutils.cpp callentry.cpp callmanager.cpp callnotification.cpp channelobserver.cpp chatmanager.cpp chatentry.cpp contactutils.cpp greetercontacts.cpp multimediaaccountentry.cpp ofonoaccountentry.cpp phoneutils.cpp protocol.cpp protocolmanager.cpp ringtone.cpp telepathyhelper.cpp tonegenerator.cpp ussdmanager.cpp ) include_directories( ${TP_QT5_INCLUDE_DIRS} ${NOTIFY_INCLUDE_DIRS} ${GSETTINGS_QT_INCLUDE_DIRS} ${LibPhoneNumber_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} ${LibPhoneNumber_LIBRARIES} ${GSETTINGS_QT_LDFLAGS}) qt5_use_modules(telephonyservice Contacts Core DBus Feedback Multimedia Qml Quick) enable_coverage(telephonyservice) ./libtelephonyservice/phoneutils.h0000644000015600001650000000406612677320771017541 0ustar jenkinsjenkins/* * Copyright (C) 2012 Canonical, Ltd. * * Authors: * Gustavo Pichorim Boiko * Renato Araujo Oliveira Filho * 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 PHONEUTILS_H #define PHONEUTILS_H #include #include class PhoneUtils : public QObject { Q_OBJECT Q_ENUMS(PhoneNumberMatchType) public: enum PhoneNumberMatchType { INVALID_NUMBER = i18n::phonenumbers::PhoneNumberUtil::INVALID_NUMBER, NO_MATCH = i18n::phonenumbers::PhoneNumberUtil::NO_MATCH, SHORT_NSN_MATCH = i18n::phonenumbers::PhoneNumberUtil::SHORT_NSN_MATCH, NSN_MATCH = i18n::phonenumbers::PhoneNumberUtil::NSN_MATCH, EXACT_MATCH = i18n::phonenumbers::PhoneNumberUtil::EXACT_MATCH }; explicit PhoneUtils(QObject *parent = 0); Q_INVOKABLE static void setCountryCode(const QString &countryCode); Q_INVOKABLE static QString countryCode(); Q_INVOKABLE static PhoneNumberMatchType comparePhoneNumbers(const QString &number1, const QString &number2); Q_INVOKABLE static bool isPhoneNumber(const QString &phoneNumber); Q_INVOKABLE static QString normalizePhoneNumber(const QString &phoneNumber); Q_INVOKABLE static bool isEmergencyNumber(const QString &phoneNumber, const QString &countryCode = QString()); private: static QString mCountryCode; }; #endif // PHONEUTILS_H ./libtelephonyservice/callentry.cpp0000644000015600001650000003421512677320771017676 0ustar jenkinsjenkins/* * 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 "accountentry.h" #include "ofonoaccountentry.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_AUDIO_OUTPUTS "AudioOutputs" #define PROPERTY_ACTIVE_AUDIO_OUTPUT "ActiveAudioOutput" QDBusArgument &operator<<(QDBusArgument &argument, const AudioOutputDBus &output) { argument.beginStructure(); argument << output.id << output.type << output.name; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, AudioOutputDBus &output) { argument.beginStructure(); argument >> output.id >> output.type >> output.name; argument.endStructure(); return argument; } CallEntry::CallEntry(const Tp::CallChannelPtr &channel, QObject *parent) : QObject(parent), mChannel(channel), mVoicemail(false), mLocalMuteState(false), mMuteInterface(channel->busName(), channel->objectPath(), TELEPATHY_MUTE_IFACE), mAudioOutputsInterface(channel->busName(), channel->objectPath(), CANONICAL_TELEPHONY_AUDIOOUTPUTS_IFACE) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); mAccount = TelepathyHelper::instance()->accountForConnection(mChannel->connection()); setupCallChannel(); // connect to the DBus signal connect(TelepathyHelper::instance()->handlerInterface(), SIGNAL(CallPropertiesChanged(QString, QVariantMap)), SLOT(onCallPropertiesChanged(QString,QVariantMap))); connect(TelepathyHelper::instance()->handlerInterface(), SIGNAL(CallHoldingFailed(QString)), SLOT(onCallHoldingFailed(QString))); // in case the account is an ofono account, we can check the voicemail number OfonoAccountEntry *ofonoAccount = qobject_cast(mAccount); if (ofonoAccount && !ofonoAccount->voicemailNumber().isEmpty()) { setVoicemail(phoneNumber() == ofonoAccount->voicemailNumber()); } Q_EMIT incomingChanged(); } void CallEntry::onAudioOutputsChanged(const AudioOutputDBusList &outputs) { mAudioOutputs.clear(); while (!mAudioOutputs.isEmpty()) { mAudioOutputs.takeFirst()->deleteLater(); } Q_FOREACH(const AudioOutputDBus &output, outputs) { mAudioOutputs.append(new AudioOutput(output.id, output.name, output.type, this)); } Q_EMIT audioOutputsChanged(); } QString CallEntry::activeAudioOutput() const { return mActiveAudioOutput; } void CallEntry::setActiveAudioOutput(const QString &id) { mAudioOutputsInterface.call("SetActiveAudioOutput", id); } void CallEntry::onActiveAudioOutputChanged(const QString &id) { mActiveAudioOutput = id; Q_EMIT activeAudioOutputChanged(); } 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::onCallHoldingFailed(const QString &objectPath) { if (objectPath != mChannel->objectPath()) { return; } // make sure we get the hold state again Q_EMIT heldChanged(); } 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)), SLOT(onCallLocalHoldStateChanged(Tp::LocalHoldState,Tp::LocalHoldStateReason))); mLocalMuteState = mMuteInterface.property("LocalMuteState") == 1; 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(); QDBusConnection::sessionBus().connect(mChannel->busName(), mChannel->objectPath(), CANONICAL_TELEPHONY_AUDIOOUTPUTS_IFACE, "AudioOutputsChanged", this, SLOT(onAudioOutputsChanged(AudioOutputDBusList))); connect(&mAudioOutputsInterface, SIGNAL(ActiveAudioOutputChanged(QString)), SLOT(onActiveAudioOutputChanged(QString))); 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_AUDIOOUTPUTS_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(); } onAudioOutputsChanged(qdbus_cast(mProperties[PROPERTY_AUDIO_OUTPUTS])); onActiveAudioOutputChanged(mProperties[PROPERTY_ACTIVE_AUDIO_OUTPUT].toString()); } bool CallEntry::dialing() const { return !incoming() && (mChannel->callState() == Tp::CallStateInitialised); } bool CallEntry::incoming() const { if (!mAccount) { return false; } return mChannel->initiatorContact() != mAccount->account()->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) || mChannel->targetContact().isNull()) { return ""; } return mChannel->targetContact()->id(); } QQmlListProperty CallEntry::calls() { return QQmlListProperty(this, 0, callsCount, callAt); } QQmlListProperty CallEntry::audioOutputs() { return QQmlListProperty(this, 0, audioOutputsCount, audioOutputsAt); } 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; } AccountEntry *CallEntry::account() const { return mAccount; } 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]; } int CallEntry::audioOutputsCount(QQmlListProperty *p) { CallEntry *entry = qobject_cast(p->object); if (!entry) { return 0; } return entry->mAudioOutputs.count(); } AudioOutput *CallEntry::audioOutputsAt(QQmlListProperty *p, int index) { CallEntry *entry = qobject_cast(p->object); if (!entry) { return 0; } return entry->mAudioOutputs[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::onCallLocalHoldStateChanged(Tp::LocalHoldState state, Tp::LocalHoldStateReason reason) { if (reason == Tp::LocalHoldStateReasonResourceNotAvailable) { Q_EMIT callHoldingFailed(); } Q_EMIT heldChanged(); } 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); } ./libtelephonyservice/applicationutils.cpp0000644000015600001650000000404612677320771021264 0ustar jenkinsjenkins/* * 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 #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 if (qgetenv("TELEPHONY_SERVICE_TEST").isEmpty()) { 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; } ./libtelephonyservice/chatmanager.h0000644000015600001650000000630412677320771017616 0ustar jenkinsjenkins/* * 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 #include #include "dbustypes.h" #include "chatentry.h" class ChatManager : public QObject { Q_OBJECT Q_PROPERTY(QQmlListProperty chats READ chats NOTIFY chatsChanged) public: static ChatManager *instance(); Q_INVOKABLE QString sendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const QVariant &attachments = QVariant(), const QVariantMap &properties = QVariantMap()); Q_INVOKABLE ChatEntry *chatEntryForParticipants(const QString &accountId, const QStringList &participants, bool create = false); Q_INVOKABLE ChatEntry *chatEntryForChatRoom(const QString &accountId, const QVariantMap &properties, bool create); QQmlListProperty chats(); static int chatCount(QQmlListProperty *p); static ChatEntry* chatAt(QQmlListProperty *p, int index); Q_SIGNALS: void messageReceived(const QString &sender, const QString &message, const QDateTime ×tamp, const QString &messageId, bool unread); void messageSent(const QStringList &recipients, const QString &message); void chatsChanged(); void chatEntryCreated(QString accountId, QStringList participants, ChatEntry *chatEntry); public Q_SLOTS: void onTextChannelAvailable(Tp::TextChannelPtr channel); void onChannelInvalidated(); void onConnectedChanged(); void onMessageReceived(const Tp::ReceivedMessage &message); void onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message); void acknowledgeMessage(const QStringList &recipients, const QString &messageId, const QString &accountId); void acknowledgeAllMessages(const QStringList &recipients, const QString &accountId); private Q_SLOTS: void onChannelObserverUnregistered(); void onTelepathyReady(); protected Q_SLOTS: void onAckTimerTriggered(); private: explicit ChatManager(QObject *parent = 0); ChatEntry *chatEntryForChannel(const Tp::TextChannelPtr &channel); QList chatEntries() const; mutable QList mChatEntries; QMap > mMessagesToAck; QList mPendingChannels; QTimer mMessagesAckTimer; bool mReady; }; #endif // CHATMANAGER_H ./libtelephonyservice/ofonoaccountentry.h0000644000015600001650000000667412677320771021135 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 OFONOACCOUNTENTRY_H #define OFONOACCOUNTENTRY_H #include "accountentry.h" #include "ussdmanager.h" class OfonoAccountEntry : public AccountEntry { Q_OBJECT Q_PROPERTY(QStringList emergencyNumbers READ emergencyNumbers NOTIFY emergencyNumbersChanged) Q_PROPERTY(QString voicemailNumber READ voicemailNumber NOTIFY voicemailNumberChanged) Q_PROPERTY(uint voicemailCount READ voicemailCount NOTIFY voicemailCountChanged) Q_PROPERTY(bool voicemailIndicator READ voicemailIndicator NOTIFY voicemailIndicatorChanged) Q_PROPERTY(QString networkName READ networkName NOTIFY networkNameChanged) Q_PROPERTY(bool emergencyCallsAvailable READ emergencyCallsAvailable NOTIFY emergencyCallsAvailableChanged) Q_PROPERTY(bool simLocked READ simLocked NOTIFY simLockedChanged) Q_PROPERTY(QString serial READ serial NOTIFY serialChanged) Q_PROPERTY(QString countryCode READ countryCode NOTIFY countryCodeChanged) Q_PROPERTY(USSDManager* ussdManager READ ussdManager CONSTANT) friend class AccountEntryFactory; public: QStringList emergencyNumbers() const; QString voicemailNumber() const; uint voicemailCount() const; bool voicemailIndicator() const; QString networkName() const; QString countryCode() const; bool emergencyCallsAvailable() const; bool simLocked() const; QString serial() const; USSDManager *ussdManager() const; // reimplemented from AccountEntry virtual AccountEntry::AccountType type() const; virtual bool connected() const; virtual bool active() const; virtual bool compareIds(const QString &first, const QString &second) const; virtual QStringList addressableVCardFields(); Q_SIGNALS: void emergencyNumbersChanged(); void voicemailNumberChanged(); void voicemailCountChanged(); void voicemailIndicatorChanged(); void networkNameChanged(); void countryCodeChanged(); void emergencyCallsAvailableChanged(); void simLockedChanged(); void serialChanged(); private Q_SLOTS: void onEmergencyNumbersChanged(const QStringList &numbers); void onCountryCodeChanged(const QString &countryCode); void onVoicemailNumberChanged(const QString &number); void onVoicemailCountChanged(uint count); void onVoicemailIndicatorChanged(bool visible); // reimplemented from AccountEntry void onConnectionChanged(Tp::ConnectionPtr connection); protected: explicit OfonoAccountEntry(const Tp::AccountPtr &account, QObject *parent = 0); private: QStringList mEmergencyNumbers; QString mCountryCode; QString mVoicemailNumber; uint mVoicemailCount; bool mVoicemailIndicator; QString mSerial; USSDManager *mUssdManager; }; #endif // OFONOACCOUNTENTRY_H ./cmake_uninstall.cmake.in0000644000015600001650000000165412677320771015677 0ustar jenkinsjenkinsIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) STRING(REGEX REPLACE "\n" ";" files "${files}") FOREACH(file ${files}) MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") IF(EXISTS "$ENV{DESTDIR}${file}") EXEC_PROGRAM( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) IF(NOT "${rm_retval}" STREQUAL 0) MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") ENDIF(NOT "${rm_retval}" STREQUAL 0) ELSE(EXISTS "$ENV{DESTDIR}${file}") MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") ENDIF(EXISTS "$ENV{DESTDIR}${file}") ENDFOREACH(file) ./COPYING0000644000015600001650000010451312677320771012150 0ustar jenkinsjenkins 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 . ./Ubuntu/0000755000015600001650000000000012677320771012373 5ustar jenkinsjenkins./Ubuntu/Telephony/0000755000015600001650000000000012677320772014343 5ustar jenkinsjenkins./Ubuntu/Telephony/presencerequest.h0000644000015600001650000000566412677320771017743 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 PRESENCEREQUEST_H #define PRESENCEREQUEST_H #include #include #include #include #include "accountentry.h" class PresenceRequest : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_ENUMS(PresenceType) Q_PROPERTY(QString identifier READ identifier WRITE setIdentifier NOTIFY identifierChanged) Q_PROPERTY(QString accountId READ accountId WRITE setAccountId NOTIFY accountIdChanged) Q_PROPERTY(QString status READ status NOTIFY statusChanged) Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusMessageChanged) Q_PROPERTY(uint type READ type NOTIFY typeChanged) public: enum PresenceType { PresenceTypeUnset = Tp::ConnectionPresenceTypeUnset, PresenceTypeOffline = Tp::ConnectionPresenceTypeOffline, PresenceTypeAvailable = Tp::ConnectionPresenceTypeAvailable, PresenceTypeAway = Tp::ConnectionPresenceTypeAway, PresenceTypeExtendedAway = Tp::ConnectionPresenceTypeExtendedAway, PresenceTypeHidden = Tp::ConnectionPresenceTypeHidden, PresenceTypeBusy = Tp::ConnectionPresenceTypeBusy, PresenceTypeUnknown = Tp::ConnectionPresenceTypeUnknown, PresenceTypeError = Tp::ConnectionPresenceTypeError }; explicit PresenceRequest(QObject *parent = 0); ~PresenceRequest(); uint type() const; QString status() const; QString statusMessage() const; QString identifier() const; void setIdentifier(const QString &identifier); QString accountId() const; void setAccountId(const QString &accountId); void classBegin(); void componentComplete(); private Q_SLOTS: void startPresenceRequest(); void onPresenceChanged(); void onContactReceived(Tp::PendingOperation *op); void onAccountAdded(AccountEntry *account); Q_SIGNALS: void identifierChanged(); void accountIdChanged(); void statusChanged(); void statusMessageChanged(); void typeChanged(); private: void startSearching(); QString mIdentifier; QString mAccountId; bool mCompleted; Tp::ContactPtr mContact; }; #endif // PRESENCEREQUEST_H ./Ubuntu/Telephony/components.cpp0000644000015600001650000000735312677320771017243 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 "config.h" #include "telepathyhelper.h" #include "callentry.h" #include "chatentry.h" #include "callmanager.h" #include "callnotification.h" #include "ussdmanager.h" #include "channelobserver.h" #include "chatmanager.h" #include "contactwatcher.h" #include "greetercontacts.h" #include "phoneutils.h" #include "presencerequest.h" #include "protocolmanager.h" #include "accountentry.h" #include "audiooutput.h" #include #include #include void Components::initializeEngine(QQmlEngine *engine, const char *uri) { Q_ASSERT(engine); Q_UNUSED(uri); // if we allow config.h to look for stuff in uninstalled paths, applications // that use this plugin will try to look for protocol info in the wrong path // and fail to find them. canRunUninstalled = false; // Initialize telepathy types Tp::registerTypes(); //Tp::enableDebug(true); Tp::enableWarnings(true); mRootContext = engine->rootContext(); Q_ASSERT(mRootContext); mRootContext->setContextProperty("telepathyHelper", TelepathyHelper::instance()); mRootContext->setContextProperty("chatManager", ChatManager::instance()); mRootContext->setContextProperty("callManager", CallManager::instance()); mRootContext->setContextProperty("greeter", GreeterContacts::instance()); mRootContext->setContextProperty("callNotification", CallNotification::instance()); mRootContext->setContextProperty("protocolManager", ProtocolManager::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"); qmlRegisterUncreatableType(uri, 0, 1, "ChatEntry", "Objects of this type are created in ChatManager and made available to QML for usage"); qmlRegisterUncreatableType(uri, 0, 1, "ContactChatState", "Objects of this type are created in ChatEntry and made available to QML"); qmlRegisterUncreatableType(uri, 0, 1, "AudioOutput", "Objects of this type are created in CallEntry and made available to QML for usage"); qmlRegisterUncreatableType(uri, 0, 1, "AccountEntry", "Objects of this type are created in TelepathyHelper and made available to QML"); qmlRegisterUncreatableType(uri, 0, 1, "USSDManager", "Objects of this type are created in AccountEntry and made available to QML"); qmlRegisterUncreatableType(uri, 0, 1, "ProtocolManager", "Objects of this type are created in ProtocolManager and made available to QML"); qmlRegisterType(uri, 0, 1, "ContactWatcher"); qmlRegisterType(uri, 0, 1, "PresenceRequest"); qmlRegisterType(uri, 0, 1, "PhoneUtils"); } ./Ubuntu/Telephony/components.h0000644000015600001650000000231212677320771016676 0ustar jenkinsjenkins/* * 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: QQmlContext *mRootContext; }; #endif // COMPONENTS_H ./Ubuntu/Telephony/contactwatcher.h0000644000015600001650000000751112677320771017530 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 CONTACTWATCHER_H #define CONTACTWATCHER_H #include #include #include #include #include QTCONTACTS_USE_NAMESPACE class ContactWatcher : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString contactId READ contactId WRITE setContactId NOTIFY contactIdChanged) Q_PROPERTY(QString avatar READ avatar WRITE setAvatar NOTIFY avatarChanged) Q_PROPERTY(QString alias READ alias WRITE setAlias NOTIFY aliasChanged) Q_PROPERTY(QString identifier READ identifier WRITE setIdentifier NOTIFY identifierChanged) Q_PROPERTY(QString phoneNumber READ identifier WRITE setIdentifier NOTIFY identifierChanged) // The details property changes according to the detail type. // One property is always present on the map though, the "detailType" property. Q_PROPERTY(QVariantMap detailProperties READ detailProperties WRITE setDetailProperties NOTIFY detailPropertiesChanged) Q_PROPERTY(bool isUnknown READ isUnknown NOTIFY isUnknownChanged) Q_PROPERTY(bool interactive READ interactive NOTIFY interactiveChanged) Q_PROPERTY(QStringList addressableFields READ addressableFields WRITE setAddressableFields NOTIFY addressableFieldsChanged) public: explicit ContactWatcher(QObject *parent = 0); ~ContactWatcher(); QString contactId() const; void setContactId(const QString &id); QString avatar() const; void setAvatar(const QString &avatar); QString alias() const; void setAlias(const QString &alias); QString identifier() const; void setIdentifier(const QString &identifier); QVariantMap detailProperties() const; void setDetailProperties(const QVariantMap &properties); bool isUnknown() const; bool interactive() const; // defaults to only phone number searching QStringList addressableFields() const; void setAddressableFields(const QStringList &fields); void classBegin(); void componentComplete(); // helpers Q_INVOKABLE QVariantList wrapIntList(const QList &list); Q_INVOKABLE QList unwrapIntList(const QVariantList &list); Q_SIGNALS: void contactIdChanged(); void avatarChanged(); void aliasChanged(); void identifierChanged(); void detailPropertiesChanged(); void isUnknownChanged(); void interactiveChanged(); void addressableFieldsChanged(); protected Q_SLOTS: void onContactsAdded(QList ids); void onContactsChanged(QList ids); void onContactsRemoved(QList ids); void onResultsAvailable(); void onRequestStateChanged(QContactAbstractRequest::State state); private: void startSearching(); void clear(); void updateAlias(); QContactFetchRequest *mRequest; QString mContactId; QString mAvatar; QString mAlias; QString mIdentifier; QVariantMap mDetailProperties; bool mInteractive; bool mCompleted; QStringList mAddressableFields; }; #endif // CONTACTWATCHER_H ./Ubuntu/Telephony/presencerequest.cpp0000644000015600001650000000762312677320771020273 0ustar jenkinsjenkins/* * Copyright (C) 2015 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 "presencerequest.h" #include "telepathyhelper.h" #include #include PresenceRequest::PresenceRequest(QObject *parent) : QObject(parent), mCompleted(false) { connect(TelepathyHelper::instance(), SIGNAL(accountAdded(AccountEntry*)), SLOT(onAccountAdded(AccountEntry*))); } PresenceRequest::~PresenceRequest() { } void PresenceRequest::onAccountAdded(AccountEntry *account) { if (account->accountId() == mAccountId) { startPresenceRequest(); } } void PresenceRequest::startPresenceRequest() { if (!mCompleted || mIdentifier.isEmpty() || mAccountId.isEmpty()) { // component is not ready yet return; } AccountEntry *account = TelepathyHelper::instance()->accountForId(mAccountId); if (!account || account->account()->connection().isNull()) { mContact.reset(); onPresenceChanged(); return; } Tp::ContactManagerPtr contactManager = account->account()->connection()->contactManager(); Tp::PendingContacts *pendingContact = contactManager->contactsForIdentifiers(QStringList() << mIdentifier); connect(pendingContact, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactReceived(Tp::PendingOperation*))); } void PresenceRequest::onContactReceived(Tp::PendingOperation *op) { Tp::PendingContacts *contacts = qobject_cast(op); if (!contacts || !contacts->isValid() || contacts->contacts().length() != 1) { return; } if (mContact) { disconnect(mContact.data(), 0,0,0); } mContact = contacts->contacts()[0]; connect(mContact.data(), SIGNAL(presenceChanged(const Tp::Presence &)), this, SLOT(onPresenceChanged())); onPresenceChanged(); } void PresenceRequest::onPresenceChanged() { Q_EMIT statusChanged(); Q_EMIT statusMessageChanged(); Q_EMIT typeChanged(); } uint PresenceRequest::type() const { if (mContact) { return mContact->presence().type(); } return PresenceTypeUnset; } QString PresenceRequest::status() const { if (mContact) { return mContact->presence().status(); } return QString(); } QString PresenceRequest::statusMessage() const { if (mContact) { return mContact->presence().statusMessage(); } return QString(); } QString PresenceRequest::accountId() const { return mAccountId; } QString PresenceRequest::identifier() const { return mIdentifier; } void PresenceRequest::setIdentifier(const QString &identifier) { if (mIdentifier == identifier) { return; } mIdentifier = identifier; startPresenceRequest(); } void PresenceRequest::setAccountId(const QString &accountId) { if (mAccountId == accountId) { return; } mAccountId = accountId; AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { return; } connect(account, SIGNAL(connectedChanged()), this, SLOT(startPresenceRequest())); startPresenceRequest(); } void PresenceRequest::classBegin() { } void PresenceRequest::componentComplete() { mCompleted = true; startPresenceRequest(); } ./Ubuntu/Telephony/PhoneNumber/0000755000015600001650000000000012677320772016565 5ustar jenkinsjenkins./Ubuntu/Telephony/PhoneNumber/PhoneNumber.js0000644000015600001650000000236512677320771021352 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 . */ function onTextChange(phoneNumberItem, formatter) { if (phoneNumberItem.text === "") { return; } if (phoneNumberItem.autoFormat && (!phoneNumberItem.updateOnlyWhenFocused || phoneNumberItem.activeFocus)) { var result = formatter.formatText(phoneNumberItem.text, phoneNumberItem.cursorPosition) if (result.text !== phoneNumberItem.text) { phoneNumberItem.text = result.text phoneNumberItem.cursorPosition = result.pos } } } ./Ubuntu/Telephony/PhoneNumber/phonenumber.h0000644000015600001650000000221712677320771021261 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 TELEPHONY_PHONENUMBER_H #define TELEPHONY_PHONENUMBER_H #include #include class PhoneNumber : 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); }; #endif //TELEPHONY_PHONENUMBER_H ./Ubuntu/Telephony/PhoneNumber/asyoutypeformatter.cpp0000644000015600001650000001422512677320771023262 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 "asyoutypeformatter.h" #include #include /*! \qmltype AsYouTypeFormatter \inqmlmodule Ubuntu.Telephony.PhoneNumber 0.1 \brief The AsYouTypeFormatter is a helper class to format phone numbers \b{This component is under heavy development.} Example: \qml Item { TextField { id: field AsYouTypeFormatter { id: formatter text: field.text } Binding { target: field property: "text" value: formatter.formattedText } } } \endqml */ AsYouTypeFormatter::AsYouTypeFormatter(QObject *parent) : QObject(parent), m_formatter(0), m_defaultRegionCode(i18n::phonenumbers::RegionCode::GetUnknown()), m_enabled(true) { connect(this, SIGNAL(enabledChanged()), SLOT(updateFormattedText()), Qt::QueuedConnection); connect(this, SIGNAL(textChanged()), SLOT(updateFormattedText()), Qt::QueuedConnection); connect(this, SIGNAL(defaultRegionCodeChanged()), SLOT(updateFormattedText()), Qt::QueuedConnection); } AsYouTypeFormatter::~AsYouTypeFormatter() { if (m_formatter) { delete m_formatter; m_formatter = 0; } } /*! Specifies whether the phone number format is enabled or not. \qmlproperty bool enabled */ bool AsYouTypeFormatter::enabled() const { return m_enabled; } void AsYouTypeFormatter::setEnabled(bool enabled) { if (m_enabled != enabled) { m_enabled = enabled; Q_EMIT enabledChanged(); } } /*! Two letters region code to be used if the number does not provide a country code (+). These must be provided using ISO 3166-1 two-letter country-code format. The list of the codes can be found here: http://www.iso.org/iso/english_country_names_and_code_elements \qmlproperty string defaultRegion */ QString AsYouTypeFormatter::defaultRegionCode() const { return m_defaultRegionCode; } void AsYouTypeFormatter::setDefaultRegionCode(const QString ®ionCode) { if (m_defaultRegionCode != regionCode) { m_defaultRegionCode = regionCode; delete m_formatter; m_formatter = 0; Q_EMIT defaultRegionCodeChanged(); } } /*! Input text to be formatted \qmlproperty string text */ QString AsYouTypeFormatter::text() const { return m_rawText; } void AsYouTypeFormatter::setText(const QString &text) { if (m_rawText != text) { m_rawText = text; Q_EMIT textChanged(); } } /*! Otuput text in a phone number format if the input text is valid. \qmlproperty string formattedText */ QString AsYouTypeFormatter::formattedText() const { return m_formattedText; } /*! Clear the input and formatted text */ void AsYouTypeFormatter::clear() { m_rawText.clear(); m_formatter->Clear(); Q_EMIT textChanged(); } QVariantMap AsYouTypeFormatter::formatText(const QString &text, int cursorPosition) { int newPosition = cursorPosition; QString newText = formatTextImpl(text, &newPosition); QVariantMap result; result.insert("text", newText); result.insert("pos", newPosition); return result; } void AsYouTypeFormatter::updateFormattedText() { if (!m_enabled) { if (!m_formattedText.isEmpty()) { m_formattedText.clear(); Q_EMIT formattedTextChanged(); } return; } if (m_rawText == m_formattedText) { return; } QString newFormattedText = formatTextImpl(m_rawText, 0); if (newFormattedText != m_formattedText) { m_formattedText = newFormattedText; Q_EMIT formattedTextChanged(); } } QString AsYouTypeFormatter::formatTextImpl(const QString &text, int *cursorPosition) { static QList validChars; if (validChars.isEmpty()) { validChars << QChar(',') << QChar(';') << QChar('+') << QChar('*') << QChar('#'); } // if the number starts with "+" we will use unknown region otherwise we will use the default region QString numberRegion = m_defaultRegionCode; if (m_rawText.startsWith("+")) { numberRegion = i18n::phonenumbers::RegionCode::GetUnknown(); } // destroy current formatter if it was created with a different region if (m_formatter && (m_formatterRegionCode != numberRegion)) { delete m_formatter; m_formatter = 0; } if (m_formatter) { m_formatter->Clear(); } else { i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance(); m_formatter = phonenumberUtil->GetAsYouTypeFormatter(numberRegion.toStdString()); m_formatterRegionCode = numberRegion; } std::string result; for(int i = 0, iMax = text.size(); i < iMax; i++) { bool savePosition = (cursorPosition != 0) && (i < *cursorPosition); QChar iChar = text.at(i); if (iChar.isDigit() || validChars.contains(iChar)) { if (savePosition) { m_formatter->InputDigitAndRememberPosition(iChar.toLatin1(), &result); } else { m_formatter->InputDigit(iChar.toLatin1(), &result); } } } if (cursorPosition) { *cursorPosition = m_formatter->GetRememberedPosition(); } return QString::fromStdString(result); } ./Ubuntu/Telephony/PhoneNumber/phonenumber.cpp0000644000015600001650000000267112677320771021620 0ustar jenkinsjenkins/* * 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 "phonenumber.h" #include "asyoutypeformatter.h" #include "phoneutils.h" #include #include static QObject *phoneUtilsProvider(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new PhoneUtils; } void PhoneNumber::initializeEngine(QQmlEngine *engine, const char *uri) { Q_UNUSED(engine); Q_UNUSED(uri); } void PhoneNumber::registerTypes(const char *uri) { // @uri Telephony.PhoneNumber qmlRegisterType(uri, 0, 1, "AsYouTypeFormatter"); qmlRegisterSingletonType(uri, 0, 1, "PhoneUtils", phoneUtilsProvider); } ./Ubuntu/Telephony/PhoneNumber/phoneutils.cpp0000644000015600001650000000746412677320771021475 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 #include #include #include PhoneUtils::PhoneUtils(QObject *parent) : QObject(parent) { } PhoneUtils::~PhoneUtils() { } QString PhoneUtils::defaultRegion() const { QString locale = QLocale::system().name(); return locale.split("_").last(); } QString PhoneUtils::format(const QString &phoneNumber, const QString &defaultRegion, PhoneUtils::PhoneNumberFormat format) { std::string formattedNumber; i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat pNFormat; if (format == PhoneUtils::Auto) { // skip if it is a special number or a command if (phoneNumber.startsWith("#") || phoneNumber.startsWith("*")) { return phoneNumber; } else if (phoneNumber.startsWith("+")) { pNFormat = i18n::phonenumbers::PhoneNumberUtil::INTERNATIONAL; } else { pNFormat = i18n::phonenumbers::PhoneNumberUtil::NATIONAL; } } else { pNFormat = static_cast(format); } i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance(); i18n::phonenumbers::PhoneNumber number; i18n::phonenumbers::PhoneNumberUtil::ErrorType error; QString region = defaultRegion.isEmpty() ? this->defaultRegion() : defaultRegion; error = phonenumberUtil->Parse(phoneNumber.toStdString(), region.toStdString(), &number); switch(error) { case i18n::phonenumbers::PhoneNumberUtil::INVALID_COUNTRY_CODE_ERROR: qWarning() << "Invalid country code for:" << phoneNumber; return ""; case i18n::phonenumbers::PhoneNumberUtil::NOT_A_NUMBER: qWarning() << "The phone number is not a valid number:" << phoneNumber; return ""; case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_AFTER_IDD: case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_NSN: case i18n::phonenumbers::PhoneNumberUtil::TOO_LONG_NSN: qWarning() << "Invalid phone number" << phoneNumber; return ""; default: break; } phonenumberUtil->Format(number, pNFormat, &formattedNumber); return QString::fromStdString(formattedNumber); } bool PhoneUtils::event(QEvent *event) { if (event->type() == QEvent::LocaleChange) { Q_EMIT defaultRegionChanged(); } return QObject::event(event); } QStringList PhoneUtils::matchInText(const QString& text, const QString &defaultRegion) { if (text.isEmpty()) { return QStringList(); } QString region = defaultRegion.isEmpty() ? this->defaultRegion() : defaultRegion; QStringList matches; i18n::phonenumbers::PhoneNumberMatcher matcher(text.toStdString(), region.toStdString()); if (matcher.HasNext()) { i18n::phonenumbers::PhoneNumberMatch match; matcher.Next(&match); matches.append(QString::fromStdString(match.raw_string())); } return matches; } ./Ubuntu/Telephony/PhoneNumber/PhoneNumberInput.qml0000644000015600001650000000460412677320771022545 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 Ubuntu.Components 0.1 import Ubuntu.Telephony.PhoneNumber 0.1 import "PhoneNumber.js" as PhoneNumberJS /*! \qmltype PhoneNumberInput \inqmlmodule Ubuntu.Telephony.PhoneNumberPhoneNumberJS 0.1 \brief The PhoneNumberField element allows to format a phone-number as you type The PhoneNumberInput uses TextInput as base class \b{This component is under heavy development.} Example: \qml Item { PhoneNumberInput { autoFormat: true defaultRegion: "US" } \endqml */ TextInput { id: phoneNumberInput /*! Specifies whether the phone number format is enabled or not. \qmlproperty bool autoFormat */ property alias autoFormat: formatter.enabled /*! Two letters region code to be used if the number does not provide a country code (+). These must be provided using ISO 3166-1 two-letter country-code format. The list of the codes can be found here: http://www.iso.org/iso/english_country_names_and_code_elements \qmlproperty string defaultRegion */ property alias defaultRegion: formatter.defaultRegionCode /*! Specifies if the autoformat should format the text even if the field does not have focus Default value is true \qmlproperty bool autoFormat */ property bool updateOnlyWhenFocused: true AsYouTypeFormatter { id: formatter } onTextChanged: PhoneNumberJS.onTextChange(phoneNumberInput, formatter) onAutoFormatChanged: { if (autoFormat) { PhoneNumberJS.onTextChange(phoneNumberInput, formatter) } } } ./Ubuntu/Telephony/PhoneNumber/PhoneNumberField.qml0000644000015600001650000000456712677320771022501 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 Ubuntu.Components 0.1 import Ubuntu.Telephony.PhoneNumber 0.1 import "PhoneNumber.js" as PhoneNumberJS /*! \qmltype PhoneNumberField \inqmlmodule Ubuntu.Telephony.PhoneNumber 0.1 \brief The PhoneNumberField element allows to format a phone-number as you type The PhoneNumberInput uses TextField as base class \b{This component is under heavy development.} Example: \qml Item { PhoneNumberField { autoFormat: true defaultRegion: "US" } \endqml */ TextField { id: phoneNumberField /*! Specifies whether the phone number format is enabled or not. \qmlproperty bool autoFormat */ property alias autoFormat: formatter.enabled /*! Two letters region code to be used if the number does not provide a country code (+). These must be provided using ISO 3166-1 two-letter country-code format. The list of the codes can be found here: http://www.iso.org/iso/english_country_names_and_code_elements \qmlproperty string defaultRegion */ property alias defaultRegion: formatter.defaultRegionCode /*! Specifies if the autoformat should format the text even if the field does not have focus Default value is true \qmlproperty bool autoFormat */ property bool updateOnlyWhenFocused: true AsYouTypeFormatter { id: formatter } onTextChanged: PhoneNumberJS.onTextChange(phoneNumberField, formatter) onAutoFormatChanged: { if (autoFormat) { PhoneNumberJS.onTextChange(phoneNumberField, formatter) } } } ./Ubuntu/Telephony/PhoneNumber/qmldir0000644000015600001650000000030612677320771017776 0ustar jenkinsjenkinsmodule Ubuntu.Telephony.PhoneNumber plugin telephonyservice-phonenumber-qml PhoneNumberField 0.1 PhoneNumberField.qml PhoneNumberInput 0.1 PhoneNumberInput.qml internal PhoneNumber PhoneNumber.js ./Ubuntu/Telephony/PhoneNumber/CMakeLists.txt0000644000015600001650000000256612677320771021335 0ustar jenkinsjenkinsset(PHONENUMBER_SRCS phonenumber.h phonenumber.cpp phoneutils.h phoneutils.cpp asyoutypeformatter.h asyoutypeformatter.cpp ) set(PHONENUMBER_QMLS PhoneNumberField.qml PhoneNumberInput.qml PhoneNumber.js qmldir ) include_directories( ${LibPhoneNumber_INCLUDE_DIRS} ) add_library(telephonyservice-phonenumber-qml SHARED ${PHONENUMBER_SRCS}) qt5_use_modules(telephonyservice-phonenumber-qml Core Qml Quick) target_link_libraries(telephonyservice-phonenumber-qml ${LibPhoneNumber_LIBRARIES} ) set(PHONENUMBER_PLUGIN_DIR ${QT_INSTALL_QML}/Ubuntu/Telephony/PhoneNumber) install(TARGETS telephonyservice-phonenumber-qml DESTINATION ${PHONENUMBER_PLUGIN_DIR}) install(FILES ${PHONENUMBER_QMLS} DESTINATION ${PHONENUMBER_PLUGIN_DIR}) # make the files visible on qtcreator add_custom_target(phonenumber_QMlFiles ALL SOURCES ${PHONENUMBER_QMLS}) #copy qml files to build dir to make it possible to run without install add_custom_target(copy_qml) foreach(QML_FILE ${PHONENUMBER_QMLS}) add_custom_command(TARGET copy_qml PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${QML_FILE} ${CMAKE_CURRENT_BINARY_DIR}/) endforeach() if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) add_dependencies(telephonyservice-phonenumber-qml copy_qml) endif() ./Ubuntu/Telephony/PhoneNumber/phoneutils.h0000644000015600001650000000305012677320771021125 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 TELEPHONY_PHONEUTILS_H #define TELEPHONY_PHONEUTILS_H #include #include class PhoneUtils : public QObject { Q_OBJECT Q_PROPERTY(QString defaultRegion READ defaultRegion NOTIFY defaultRegionChanged) public: enum PhoneNumberFormat { E164 = 0, International, National, RFC3966, Auto }; PhoneUtils(QObject *parent = 0); ~PhoneUtils(); QString defaultRegion() const; Q_INVOKABLE QStringList matchInText(const QString& text, const QString &defaultRegion = QString()); Q_INVOKABLE QString format(const QString &phoneNumber, const QString &defaultRegion = QString(), PhoneNumberFormat format = Auto); virtual bool event(QEvent *event); Q_SIGNALS: void defaultRegionChanged(); }; #endif ./Ubuntu/Telephony/PhoneNumber/asyoutypeformatter.h0000644000015600001650000000446212677320771022731 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * Authors: * Renato Araujo Oliveira Filho * * 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 TELEPHONY_PHONENUMBER_ASYOUTYPEFORMATTER_H #define TELEPHONY_PHONENUMBER_ASYOUTYPEFORMATTER_H #include #include #include class AsYouTypeFormatter : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(QString defaultRegionCode READ defaultRegionCode WRITE setDefaultRegionCode NOTIFY defaultRegionCodeChanged) Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QString formattedText READ formattedText NOTIFY formattedTextChanged) public: AsYouTypeFormatter(QObject *parent = 0); ~AsYouTypeFormatter(); bool enabled() const; void setEnabled(bool enabled); QString defaultRegionCode() const; void setDefaultRegionCode(const QString ®ionCode); QString text() const; void setText(const QString &text); QString formattedText() const; public Q_SLOTS: void clear(); QVariantMap formatText(const QString &text, int cursorPosition); private Q_SLOTS: void updateFormattedText(); Q_SIGNALS: void textChanged(); void formattedTextChanged(); void defaultRegionCodeChanged(); void enabledChanged(); private: i18n::phonenumbers::AsYouTypeFormatter *m_formatter; bool m_enabled; QString m_rawText; QString m_formattedText; QString m_defaultRegionCode; QString m_formatterRegionCode; QString formatTextImpl(const QString &text, int *cursorPosition); }; #endif //TELEPHONY_PHONENUMBER_ASYOUTYPEFORMATTER_H ./Ubuntu/Telephony/conversationfeeditem.cpp0000644000015600001650000000445412677320771021272 0ustar jenkinsjenkins/* * 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; } ./Ubuntu/Telephony/contactwatcher.cpp0000644000015600001650000002607212677320771020066 0ustar jenkinsjenkins/* * Copyright (C) 2013-2015 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 "contactwatcher.h" #include "contactutils.h" #include "phoneutils.h" #include "accountentry.h" #include "telepathyhelper.h" #include #include #include #include #include #include #include #include #include namespace C { #include } ContactWatcher::ContactWatcher(QObject *parent) : QObject(parent), mRequest(0), mInteractive(false), mCompleted(false) { // addressable VCard fields defaults to "tel" only mAddressableFields << "tel"; 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))); connect(this, SIGNAL(contactIdChanged()), SIGNAL(isUnknownChanged())); } ContactWatcher::~ContactWatcher() { if (mRequest) { mRequest->cancel(); delete mRequest; } } void ContactWatcher::startSearching() { if (!mCompleted || mIdentifier.isEmpty() || !mInteractive) { // component is not ready yet or no identifier given, // or the number is not interactive and thus doesn't need contact info at all return; } // cancel current request if necessary if (mRequest) { mRequest->cancel(); mRequest->deleteLater(); } // FIXME: search for all the fields mRequest = new QContactFetchRequest(this); QContactUnionFilter topLevelFilter; Q_FOREACH(const QString &field, mAddressableFields) { if (field == "tel") { topLevelFilter.append(QContactPhoneNumber::match(mIdentifier)); } else { // FIXME: handle more fields // rely on a generic field filter QContactDetailFilter nameFilter = QContactDetailFilter(); nameFilter.setDetailType(QContactExtendedDetail::Type, QContactExtendedDetail::FieldName); nameFilter.setMatchFlags(QContactFilter::MatchExactly); nameFilter.setValue(field); QContactDetailFilter valueFilter = QContactDetailFilter(); valueFilter.setDetailType(QContactExtendedDetail::Type, QContactExtendedDetail::FieldData); valueFilter.setMatchFlags(QContactFilter::MatchExactly); valueFilter.setValue(mIdentifier); QContactIntersectionFilter intersectionFilter; intersectionFilter.append(nameFilter); intersectionFilter.append(valueFilter); topLevelFilter.append(intersectionFilter); } } mRequest->setFilter(topLevelFilter); connect(mRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), SLOT(onRequestStateChanged(QContactAbstractRequest::State))); connect(mRequest, SIGNAL(resultsAvailable()), SLOT(onResultsAvailable())); mRequest->setManager(ContactUtils::sharedManager()); mRequest->start(); } void ContactWatcher::clear() { setAlias(QString::null); setContactId(QString::null); setAvatar(QString::null); setDetailProperties(QVariantMap()); } void ContactWatcher::updateAlias() { if (mIdentifier.isEmpty()) { setAlias(QString::null); } else if (mIdentifier.startsWith(OFONO_PRIVATE_NUMBER)) { setAlias(C::dgettext("telephony-service", "Private Number")); } else if (mIdentifier.startsWith(OFONO_UNKNOWN_NUMBER)) { setAlias(C::dgettext("telephony-service", "Unknown Number")); } } QVariantList ContactWatcher::wrapIntList(const QList &list) { QVariantList resultList; Q_FOREACH(int value, list) { resultList << value; } return resultList; } QList ContactWatcher::unwrapIntList(const QVariantList &list) { QList resultList; Q_FOREACH(const QVariant &value, list) { resultList << value.toInt(); } return resultList; } QString ContactWatcher::contactId() const { return mContactId; } void ContactWatcher::setContactId(const QString &id) { if (id == mContactId) { return; } if (id == QStringLiteral("qtcontacts:::")) { mContactId = QString::null; } else { mContactId = id; } Q_EMIT contactIdChanged(); } QString ContactWatcher::avatar() const { return mAvatar; } void ContactWatcher::setAvatar(const QString &avatar) { if (avatar == mAvatar) { return; } mAvatar = avatar; Q_EMIT avatarChanged(); } QString ContactWatcher::alias() const { return mAlias; } void ContactWatcher::setAlias(const QString &alias) { if (alias == mAlias) { return; } mAlias = alias; Q_EMIT aliasChanged(); } QString ContactWatcher::identifier() const { return mIdentifier; } void ContactWatcher::setIdentifier(const QString &identifier) { if (mIdentifier == identifier) { return; } // FIXME: ofono stuff, maybe move somewhere else? const bool isPrivate = identifier.startsWith(OFONO_PRIVATE_NUMBER); const bool isUnknown = identifier.startsWith(OFONO_UNKNOWN_NUMBER); const bool isInteractive = !identifier.isEmpty() && !isPrivate && !isUnknown; mIdentifier = identifier; Q_EMIT identifierChanged(); if (isInteractive != mInteractive) { mInteractive = isInteractive; Q_EMIT interactiveChanged(); } if (mIdentifier.isEmpty() || isPrivate || isUnknown) { updateAlias(); setContactId(QString::null); setAvatar(QString::null); setDetailProperties(QVariantMap()); } else { startSearching(); } } QVariantMap ContactWatcher::detailProperties() const { return mDetailProperties; } void ContactWatcher::setDetailProperties(const QVariantMap &properties) { if (properties == mDetailProperties) { return; } mDetailProperties = properties; Q_EMIT detailPropertiesChanged(); } bool ContactWatcher::isUnknown() const { return mContactId.isNull(); } bool ContactWatcher::interactive() const { return mInteractive; } QStringList ContactWatcher::addressableFields() const { return mAddressableFields; } void ContactWatcher::setAddressableFields(const QStringList &fields) { mAddressableFields = fields; // if the addressable fields is empty, fall back to matching phone numbers if (mAddressableFields.isEmpty()) { mAddressableFields << "tel"; } Q_EMIT addressableFieldsChanged(); startSearching(); } void ContactWatcher::classBegin() { } void ContactWatcher::componentComplete() { mCompleted = true; updateAlias(); startSearching(); } void ContactWatcher::onContactsAdded(QList ids) { // ignore this signal if we have a contact already // or if we have no phone number set if (!mContactId.isNull() || mIdentifier.isEmpty()) { return; } startSearching(); } 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 startSearching(); } void ContactWatcher::onContactsRemoved(QList ids) { Q_FOREACH(const QContactId &id, ids) { if (id.toString() == mContactId) { clear(); startSearching(); break; } } } void ContactWatcher::onResultsAvailable() { QContactFetchRequest *request = qobject_cast(sender()); if (request && request->contacts().size() > 0) { QContact contact; // iterate over all contacts Q_FOREACH(const QString &field, mAddressableFields) { if (!contact.isEmpty()) { break; } if (field == "tel") { Q_FOREACH(const QContact &resultContact, request->contacts()) { Q_FOREACH(const QContactPhoneNumber phoneNumber, resultContact.details(QContactDetail::TypePhoneNumber)) { if (PhoneUtils::comparePhoneNumbers(phoneNumber.number(), mIdentifier) > PhoneUtils::NO_MATCH) { contact = resultContact; break; } } if (!contact.isEmpty()) { break; } } if (!contact.isEmpty()) { break; } } else { // FIXME: add proper support for non-phonenumber ids contact = request->contacts().at(0); break; } } setContactId(contact.id().toString()); setAvatar(contact.detail().imageUrl().toString()); setAlias(ContactUtils::formatContactName(contact)); QVariantMap detailProperties; Q_FOREACH(const QString &field, mAddressableFields) { if (field == "tel") { Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) { if (PhoneUtils::comparePhoneNumbers(phoneNumber.number(), mIdentifier) > PhoneUtils::NO_MATCH) { detailProperties["type"] = (int)QContactDetail::TypePhoneNumber; detailProperties["phoneNumberSubTypes"] = wrapIntList(phoneNumber.subTypes()); detailProperties["phoneNumberContexts"] = wrapIntList(phoneNumber.contexts()); break; } } } else { // FIXME: add proper support for more fields } } setDetailProperties(detailProperties); } } void ContactWatcher::onRequestStateChanged(QContactAbstractRequest::State state) { QContactFetchRequest *request = mRequest; if (request && state == QContactAbstractRequest::FinishedState) { mRequest = 0; request->deleteLater(); // if we got no results and we had a contact previously, we need to clear the data if (request->contacts().isEmpty() && !mContactId.isNull()) { clear(); } } } ./Ubuntu/Telephony/qmldir.in0000644000015600001650000000006412677320771016162 0ustar jenkinsjenkinsmodule Ubuntu.Telephony plugin telephonyservice-qml ./Ubuntu/Telephony/CMakeLists.txt0000644000015600001650000000136212677320771017104 0ustar jenkinsjenkins# QML plugin set(plugin_SRCS contactwatcher.cpp presencerequest.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 ) enable_coverage(telephonyservice-qml) 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(PhoneNumber) ./Ubuntu/Telephony/conversationfeeditem.h0000644000015600001650000000514112677320771020731 0ustar jenkinsjenkins/* * 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 ./Ubuntu/CMakeLists.txt0000644000015600001650000000003412677320771015130 0ustar jenkinsjenkinsadd_subdirectory(Telephony) ./run_all_tests.sh0000755000015600001650000000007212677320771014325 0ustar jenkinsjenkins#!/bin/sh export CTEST_OUTPUT_ON_FAILURE=1 make make test ./approver/0000755000015600001650000000000012677320772012750 5ustar jenkinsjenkins./approver/main.cpp0000644000015600001650000000434312677320771014403 0ustar jenkinsjenkins/* * 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; } #ifdef USE_UBUNTU_PLATFORM_API // required to make qtsensors work qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient"); #endif QObject::connect(TelepathyHelper::instance(), &TelepathyHelper::setupReady, []() { // register the approver TelepathyHelper::instance()->registerChannelObserver("TelephonyServiceObserver"); Approver *approver = new Approver(); TelepathyHelper::instance()->registerClient(approver, "TelephonyServiceApprover"); }); return app.exec(); } ./approver/approverdbus.h0000644000015600001650000000300112677320771015626 0ustar jenkinsjenkins/* * 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" #include "approver.h" /** * DBus interface for the phone approver */ class ApproverDBus : public QObject, protected QDBusContext { Q_OBJECT public: ApproverDBus(Approver *approver, QObject* parent=0); ~ApproverDBus(); bool connectToBus(); public Q_SLOTS: Q_NOREPLY void HangUpAndAcceptCall(); Q_NOREPLY void AcceptCall(); Q_NOREPLY void RejectCall(); bool HandleMediaKey(bool doubleClick); Q_SIGNALS: void hangUpAndAcceptCallRequested(); void acceptCallRequested(); void rejectCallRequested(); private: Approver *mApprover; }; #endif // APPROVERDBUS_H ./approver/approver.cpp0000644000015600001650000006657312677320771015332 0ustar jenkinsjenkins/* * Copyright (C) 2012-2014 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 "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 "protocolmanager.h" #include "tonegenerator.h" #include "telepathyhelper.h" #include "accountentry.h" #include #include #include #include #include #include #include #include #include #include #include namespace C { #include } #define TELEPHONY_SERVICE_HANDLER TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler" Approver::Approver() : Tp::AbstractClientApprover(channelFilters()), mPendingSnapDecision(NULL), mSettleTimer(new QTimer(this)) { mDefaultTitle = C::gettext("Unknown caller"); mDefaultIcon = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); ApproverDBus *dbus = new ApproverDBus(this); 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))); } QDBusConnection::systemBus().connect("com.canonical.Unity.Screen", "/com/canonical/Unity/Screen", "com.canonical.Unity.Screen", "DisplayPowerStateChange", this, SLOT(onUnityStateChanged(int,int))); // WORKAROUND: we need to use a timer as the qtubuntu sensors backend does not support setPeriod() mVibrateTimer.setInterval(4000); connect(&mVibrateTimer, SIGNAL(timeout()), &mVibrateEffect, SLOT(start())); mRejectActions["rejectMessage1"] = C::gettext("I'm busy at the moment. I'll call later."); mRejectActions["rejectMessage2"] = C::gettext("I'm running late, on my way now."); mRejectActions["rejectMessage3"] = C::gettext("Please call me back later."); mSettleTimer->setInterval(500); mSettleTimer->setSingleShot(true); connect(mSettleTimer, SIGNAL(timeout()), this, SLOT(onSettleTimerTimeout())); mSettleTimer->start(); } void Approver::onSettleTimerTimeout() { mSettleTimer->deleteLater(); mSettleTimer = NULL; } void Approver::onUnityStateChanged(int state, int reason) { if (!mPendingSnapDecision) { return; } // state == 0 is power off // reason == 2 is power key if (state == 0 && reason == 2) { Ringtone::instance()->stopIncomingCallSound(); mVibrateTimer.stop(); mVibrateEffect.setDuration(1); mVibrateEffect.start(); } } 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) { if (!ProtocolManager::instance()->isProtocolSupported(dispatchOperation->account()->protocolName())) { context->setFinishedWithError(TP_QT_ERROR_NOT_CAPABLE, "The account for this request is not supported."); return; } 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 action_reject_message(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->onRejectMessage((Tp::ChannelDispatchOperationPtr) eventData->dispatchOp, action); } } void delete_event_data(gpointer data) { if (NULL != data) delete (EventData*) data; } void Approver::updateNotification(const QContact &contact) { if (!mPendingSnapDecision) return; QString displayLabel = contact.detail().label(); 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)) { closeSnapDecision(); 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; } if (isIncoming(channel) && !callChannel->isRequested() && callChannel->callState() == Tp::CallStateInitialised) { callChannel->setRinging(); } else { onApproved(dispatchOp); return; } connect(channel.data(), SIGNAL(callStateChanged(Tp::CallState)), SLOT(onCallStateChanged(Tp::CallState))); mChannels.remove(pr); // and now set up the contact matching for either greeter mode or regular mode if (GreeterContacts::isGreeterMode()) { // show the snap decision right away because contact info might never arrive showSnapDecision(dispatchOp, channel); GreeterContacts::instance()->setContactFilter(QContactPhoneNumber::match(contact->id())); } else { AccountEntry *account = TelepathyHelper::instance()->accountForConnection(callChannel->connection()); if (!account) { qCritical() << "Call exists with no account for connection"; return; } // 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::stateChanged, [this, request, dispatchOp, channel](QContactAbstractRequest::State state) { if (!request || state != QContactAbstractRequest::FinishedState) { return; } QContact contact; // create the snap decision only after the contact match finishes if (request->contacts().size() > 0) { // use the first match contact = request->contacts().at(0); // Also notify greeter via AccountsService GreeterContacts::emitContact(contact); } showSnapDecision(dispatchOp, channel, contact); }); // FIXME: For accounts not based on phone numbers, don't try to match contacts for now if (account->type() == AccountEntry::PhoneAccount) { request->setManager(ContactUtils::sharedManager()); request->start(); } else { // just emit the signal to pretend we did a contact search Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState); } } } void Approver::onApproved(Tp::ChannelDispatchOperationPtr dispatchOp) { closeSnapDecision(); acceptCallChannels(dispatchOp); // forward the channel to the handler dispatchOp->handleWith(TELEPHONY_SERVICE_HANDLER); // and then launch the dialer-app ApplicationUtils::openUrl(QUrl("dialer:///?view=liveCall")); mDispatchOps.removeAll(dispatchOp); } void Approver::onHangUpAndApproved(Tp::ChannelDispatchOperationPtr dispatchOp) { closeSnapDecision(); // hangup existing calls if (CallManager::instance()->foregroundCall()) { CallManager::instance()->foregroundCall()->endCall(); } acceptCallChannels(dispatchOp); // 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) { closeSnapDecision(); 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(); } void Approver::onRejectMessage(Tp::ChannelDispatchOperationPtr dispatchOp, const char *action) { if (mRejectActions.contains(action)) { QString targetId = dispatchOp->channels().first()->targetContact()->id(); ChatManager::instance()->sendMessage(dispatchOp->account()->uniqueIdentifier(), QStringList() << targetId, mRejectActions[action]); } onRejected(dispatchOp); } bool Approver::showSnapDecision(const Tp::ChannelDispatchOperationPtr dispatchOperation, const Tp::ChannelPtr channel, const QContact &contact) { Tp::ContactPtr telepathyContact = channel->initiatorContact(); NotifyNotification* notification; bool hasCalls = CallManager::instance()->hasCalls(); /* initial notification */ EventData* data = new EventData(); data->self = this; data->dispatchOp = dispatchOperation; data->channel = channel; bool unknownNumber = false; AccountEntry *account = TelepathyHelper::instance()->accountForConnection(channel->connection()); if (!account) { qCritical() << "Call exists with no account for connection"; return false; } mCachedBody = QString(); if (account->type() == AccountEntry::PhoneAccount && TelepathyHelper::instance()->multiplePhoneAccounts()) { mCachedBody = QString::fromUtf8(C::gettext("On [%1]")).arg(account->displayName()); mCachedBody += "\n"; if (!telepathyContact->id().isEmpty()) { if (telepathyContact->id().startsWith(OFONO_PRIVATE_NUMBER)) { mCachedBody += QString::fromUtf8(C::gettext("Private number")); unknownNumber = true; } else if (telepathyContact->id().startsWith(OFONO_UNKNOWN_NUMBER)) { mCachedBody += QString::fromUtf8(C::gettext("Unknown number")); unknownNumber = true; } else { mCachedBody += telepathyContact->id(); } } else { mCachedBody += C::gettext("Caller number is not available"); unknownNumber = true; } } else { if (!telepathyContact->id().isEmpty()) { if (telepathyContact->id().startsWith(OFONO_PRIVATE_NUMBER)) { mCachedBody = QString::fromUtf8(C::gettext("Calling from private number")); unknownNumber = true; } else if (telepathyContact->id().startsWith(OFONO_UNKNOWN_NUMBER)) { mCachedBody = QString::fromUtf8(C::gettext("Calling from unknown number")); unknownNumber = true; } else { mCachedBody = QString::fromUtf8(C::gettext("Calling from %1")).arg(telepathyContact->id()); } } else { mCachedBody = C::gettext("Caller number is not available"); unknownNumber = true; } } QString displayLabel; QString icon; if (!contact.isEmpty()) { displayLabel = contact.detail().label(); icon = contact.detail().imageUrl().toEncoded(); } if (displayLabel.isEmpty()) { displayLabel = mDefaultTitle; } if (icon.isEmpty()) { icon = mDefaultIcon; } notification = notify_notification_new (displayLabel.toStdString().c_str(), mCachedBody.toStdString().c_str(), icon.toStdString().c_str()); notify_notification_set_hint_string(notification, "x-canonical-snap-decisions", "true"); notify_notification_set_hint_string(notification, "x-canonical-snap-decisions-swipe", "true"); notify_notification_set_hint_string(notification, "x-canonical-private-button-tint", "true"); notify_notification_set_hint_string(notification, "x-canonical-secondary-icon", "incoming-call"); notify_notification_set_hint_int32(notification, "x-canonical-snap-decisions-timeout", -1); QString acceptTitle = hasCalls ? C::gettext("Hold + Answer") : C::gettext("Accept"); notify_notification_add_action (notification, "action_accept", acceptTitle.toLocal8Bit().data(), action_accept, data, delete_event_data); #if 0 // FIXME: re-enable that once we move to fullscreen notifications if (hasCalls) { notify_notification_add_action (notification, "action_hangup_and_accept", C::gettext("End + Answer"), action_hangup_and_accept, data, delete_event_data); } #endif notify_notification_add_action (notification, "action_decline_1", C::gettext("Decline"), action_reject, data, delete_event_data); if (!unknownNumber) { notify_notification_add_action(notification, "action_decline_expansion", C::gettext("Message & decline"), action_reject, data, delete_event_data); Q_FOREACH(const QString &action, mRejectActions.keys()) { notify_notification_add_action(notification, action.toUtf8().data(), QString("message:%1").arg(mRejectActions[action]).toUtf8().data(), action_reject_message, data, delete_event_data); } } mPendingSnapDecision = notification; GError *error = NULL; if (!notify_notification_show(notification, &error)) { closeSnapDecision(); qWarning() << "Failed to show snap decision:" << error->message; g_error_free (error); return false; } if (hasCalls) { ToneGenerator::instance()->playWaitingTone(); } else { // play a ringtone Ringtone::instance()->playIncomingCallSound(); } if (!hasCalls && GreeterContacts::instance()->incomingCallVibrate()) { mVibrateEffect.setDuration(2000); mVibrateEffect.start(); mVibrateTimer.start(); } return true; } void Approver::acceptCallChannels(const Tp::ChannelDispatchOperationPtr dispatchOp) { // accept all channels Q_FOREACH(Tp::ChannelPtr channel, dispatchOp->channels()) { Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); if (callChannel && isIncoming(callChannel) && callChannel->callState() != Tp::CallStateActive) { callChannel->accept(); } } } 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; } bool Approver::isIncoming(const Tp::ChannelPtr &channel) { return channel->initiatorContact() != channel->connection()->selfContact(); } 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(); ToneGenerator::instance()->stopWaitingTone(); mVibrateTimer.stop(); // WORKAROUND: the ubuntu qt sensors backend does not support setPeriod() and stop(), // so we invoke a short vibration to simulate a stop() call mVibrateEffect.setDuration(1); mVibrateEffect.start(); } 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); } } bool Approver::handleMediaKey(bool doubleClick) { Q_UNUSED(doubleClick) // hasCalls gets the value from handler, so even if CallManager isn't ready right now, we know // if the event will be handled later bool accepted = mPendingSnapDecision || CallManager::instance()->hasCalls(); // FIXME: Telepathy-qt does not let us know if existing channels are being recovered, // so if this is the first run, call this method again when mSettleTimer is done if (mSettleTimer) { QObject::connect(mSettleTimer, &QTimer::timeout, [=]() { handleMediaKey(doubleClick); }); return accepted; } // postpone this to avoid blocking dbus method callers QMetaObject::invokeMethod(this, "processHandleMediaKey", Qt::QueuedConnection, Q_ARG(bool, doubleClick)); return accepted; } void Approver::processHandleMediaKey(bool doubleClick) { Q_UNUSED(doubleClick) if (mPendingSnapDecision) { onAcceptCallRequested(); } else if (CallManager::instance()->hasCalls()) { // if there is no incoming call, we have to hangup the current active call CallEntry *call = CallManager::instance()->foregroundCall(); if (call) { call->endCall(); } } } ./approver/approverdbus.cpp0000644000015600001650000000341012677320771016165 0ustar jenkinsjenkins/* * 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(Approver *approver, QObject* parent) : QObject(parent), mApprover(approver) { } 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(); } bool ApproverDBus::HandleMediaKey(bool doubleClick) { return mApprover->handleMediaKey(doubleClick); } ./approver/50-com.canonical.TelephonyServiceApprover.pkla0000644000015600001650000000027212677320771023555 0ustar jenkinsjenkins[Allow LightDM to read TelephonyServiceApprover fields] Identity=unix-user:lightdm Action=com.canonical.TelephonyServiceApprover.ReadAny ResultAny=no ResultInactive=yes ResultActive=yes ./approver/org.freedesktop.Telepathy.Client.TelephonyServiceApprover.service.in0000644000015600001650000000023512677320771030220 0ustar jenkinsjenkins[D-BUS Service] Name=org.freedesktop.Telepathy.Client.TelephonyServiceApprover Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-approver ./approver/com.canonical.TelephonyServiceApprover.policy0000644000015600001650000000126412677320771023705 0ustar jenkinsjenkins no yes yes no no no ./approver/approver.h0000644000015600001650000000642112677320771014761 0ustar jenkinsjenkins/* * Copyright (C) 2012-2014 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 APPROVER_H #define APPROVER_H #include #include #include #include #include #include #include #include #include QTCONTACTS_USE_NAMESPACE 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); void onRejectMessage(Tp::ChannelDispatchOperationPtr dispatchOp, const char *action); bool showSnapDecision(const Tp::ChannelDispatchOperationPtr dispatchOperation, const Tp::ChannelPtr channel, const QContact &contact = QContact()); void acceptCallChannels(const Tp::ChannelDispatchOperationPtr dispatchOp); bool handleMediaKey(bool doubleClick); protected: Tp::ChannelDispatchOperationPtr dispatchOperationForIncomingCall(); bool isIncoming(const Tp::ChannelPtr &channel); 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); void onUnityStateChanged(int state, int reason); void onSettleTimerTimeout(); void processHandleMediaKey(bool doubleClick); private: QList mDispatchOps; QMap mChannels; NotifyNotification* mPendingSnapDecision; QString mDefaultTitle; QString mDefaultIcon; QString mCachedBody; QFeedbackHapticsEffect mVibrateEffect; QTimer mVibrateTimer; QTimer *mSettleTimer; QMap mRejectActions; }; #endif // APPROVER_H ./approver/CMakeLists.txt0000644000015600001650000000355112677320771015513 0ustar jenkinsjenkins 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 Feedback) target_link_libraries(telephony-service-approver ${TP_QT5_LIBRARIES} ${NOTIFY_LIBRARIES} telephonyservice ) enable_coverage(telephony-service-approver) 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\") ") ./approver/com.canonical.TelephonyServiceApprover.xml0000644000015600001650000000116312677320771023204 0ustar jenkinsjenkins ./approver/Approver.xml0000644000015600001650000000311312677320771015265 0ustar jenkinsjenkins An interface to the phone approver application. ./approver/TelephonyServiceApprover.client0000644000015600001650000000137312677320771021162 0ustar jenkinsjenkins[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 ./icons/0000755000015600001650000000000012677320771012224 5ustar jenkinsjenkins./icons/ubuntu-mono-dark/0000755000015600001650000000000012677320771015433 5ustar jenkinsjenkins./icons/ubuntu-mono-dark/status/0000755000015600001650000000000012677320771016756 5ustar jenkinsjenkins./icons/ubuntu-mono-dark/status/16/0000755000015600001650000000000012677320772017205 5ustar jenkinsjenkins./icons/ubuntu-mono-dark/status/16/indicator-call.svg0000644000015600001650000000551212677320771022615 0ustar jenkinsjenkins image/svg+xml ./icons/ubuntu-mono-dark/status/24/0000755000015600001650000000000012677320772017204 5ustar jenkinsjenkins./icons/ubuntu-mono-dark/status/24/indicator-call.svg0000644000015600001650000000547212677320771022621 0ustar jenkinsjenkins image/svg+xml ./icons/ubuntu-mono-dark/status/22/0000755000015600001650000000000012677320772017202 5ustar jenkinsjenkins./icons/ubuntu-mono-dark/status/22/indicator-call.svg0000644000015600001650000000547212677320771022617 0ustar jenkinsjenkins image/svg+xml ./icons/hicolor/0000755000015600001650000000000012677320771013663 5ustar jenkinsjenkins./icons/hicolor/48x48/0000755000015600001650000000000012677320771014462 5ustar jenkinsjenkins./icons/hicolor/48x48/apps/0000755000015600001650000000000012677320772015426 5ustar jenkinsjenkins./icons/hicolor/48x48/apps/telephony-service-call.png0000644000015600001650000000354112677320771022514 0ustar jenkinsjenkinsPNG  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`./icons/hicolor/48x48/apps/telephony-service-message.png0000644000015600001650000000271612677320771023230 0ustar jenkinsjenkinsPNG  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`./icons/ubuntu-mono-light/0000755000015600001650000000000012677320771015621 5ustar jenkinsjenkins./icons/ubuntu-mono-light/status/0000755000015600001650000000000012677320771017144 5ustar jenkinsjenkins./icons/ubuntu-mono-light/status/16/0000755000015600001650000000000012677320772017373 5ustar jenkinsjenkins./icons/ubuntu-mono-light/status/16/indicator-call.svg0000644000015600001650000000547112677320771023007 0ustar jenkinsjenkins image/svg+xml ./icons/ubuntu-mono-light/status/24/0000755000015600001650000000000012677320772017372 5ustar jenkinsjenkins./icons/ubuntu-mono-light/status/24/indicator-call.svg0000644000015600001650000000546312677320771023007 0ustar jenkinsjenkins image/svg+xml ./icons/ubuntu-mono-light/status/22/0000755000015600001650000000000012677320772017370 5ustar jenkinsjenkins./icons/ubuntu-mono-light/status/22/indicator-call.svg0000644000015600001650000000545212677320771023003 0ustar jenkinsjenkins image/svg+xml ./icons/CMakeLists.txt0000644000015600001650000000022712677320771014765 0ustar jenkinsjenkinsset(icon_DIRS hicolor ubuntu-mono-dark ubuntu-mono-light ) install(DIRECTORY ${icon_DIRS} DESTINATION ${CMAKE_INSTALL_DATADIR}/icons) ./TODO0000644000015600001650000000123212677320771011577 0ustar jenkinsjenkinsGeneral 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. ./data/0000755000015600001650000000000012677320772012023 5ustar jenkinsjenkins./data/org.freedesktop.Notifications.xml0000644000015600001650000000350112677320771020454 0ustar jenkinsjenkins ./assets/0000755000015600001650000000000012677320772012414 5ustar jenkinsjenkins./assets/message_watermark.png0000644000015600001650000002640312677320771016627 0ustar jenkinsjenkinsPNG  IHDRwZ,sRGB,IDATxݍ봡PN (\4d(doe$||ȶ/J3oNY}Vܾ^.e?LZ bGsyya-yY.W휫9鳜ײ|f8 @h%Ձy:Z_^:q/Gv @@^e.[^uࣅoW%[J>sKK+7  @J^o&@N+`/y.y6v& @ x.h>h:ܕ`bM @}xkZBM @O:~#Z P $eȸ>=Ksa @I˞~ȢE'= Uh*+ xφ  @(m`KQ-چ @@nwLXvl:>%@pb=#@F WH7זZk^~v%w8@_N]\jx-`w_H*,__Vyεgyo"@ԙrkry?Cr&_2qw澣~ ׻V @'G܂!֜[]ymqe,-ԣn˱9.ֺYO%rޯmp2'ܝN yrc)'Bƈ3 p>һ+<˔~ZSص.eM%Э1 pN䛄t`e^UL?.GMtZ[g7%T2] vz I<[0zֆYFKeW]6"@(|{f%ޛMʍ2ԚpnVQ p,re0Y#Yh)Y&rvy['-& @ y SL#䡔#\7{.7[6?[ @ҩTx)+\vu[3[e- @5 T#^:JPς[n %ٞ7k"@ {>QlVϮ; @ z2 P$տCy P $!^K÷]znnC-r)=v;@; YxjWorK mHh+W^e,ܵ\_Jk @׫Sꡞ^dkg,;T @zuLCG݇r9{ ٣nAS W{w- sSM @zuP}m݇͑w: @ !I{4c @HQvpaܓvk @/2]Iͯƕ IUwݛnx @\UV.%'O  @ztX%ܽe|gG8@\s5zG=ߩ @̸ɷ ooW5sU @f=[{[XS/7ݝJwk @fW%rRzysmܰG,  @ 7o9ma)rP XGŵ) @@|bwKhoTt!@\@E:xBzNX G"H+NL"#iWz޺vKMG{s㒬`@ @=rλpWzwDg8@=ut< @=rλe{$s^jM-#tw= x @9zw{Jc @; w=.]sVjMuS]fw\ @{;=wG=ԋB`pJ)=w{ ut< @]N w=.˞՞ ^@]{S{$@)Ή@ 𔀞lL-o @ wz;M @yZU|E 0p7KK)' @`p* @Y ` @j  @P  @pWkX&@L. MހOZ2 @`rnT| @@-   @ w7 @jְL\@ P we @  @Z@5, @&&o@'@]a 0p7y*> @j  @P  @pWkX&@L. MހOZ2 @`rnT| @@-   @ w7 @jְL\@ P we @  @Z@5, @&&o@'@]a 0p7y*> @j  @P  @pWkX&@L. MހOZ2 @`rnT| @@-   @ w7 @jְL\@ P we @  @Z@5, @&&o@'@]a 0p7y*> @j  @P  @pWkX&@L. MހOZ2 @`rnT| @@-   @ w7 @jְL\@ P we @  @Z@5, @&&o@'@]a 0p7y*> @ԅL F 6 @JGgzz[$@h% ܵ @ @V]+I!@ +pnE @N$%piJVӲ]aQ @^=w]*;b+ pXy[a[Q @=wl @]{zԍKK)=w=(TGE8@vϝSs*MP`pg+=w [֮  @S wlv&@(w#ID !ppW.  Ah(#k؀vE^fv9  pr9|YU?8C]|B+pꞻ4[0mF%'@|&&<U8-  @i^l-ۼ  @c 赋pŎNvC @'kޮs'9TQwW^Gwc;; ptVp g* @ 3n칋S#.0 @@s}|v8dK{c @@KoSxz~]~p:K+e @)zuR}mݻiwn^0;W @ $Ot]?q0 @@S.ǮwVܩ=oFܩCH e<^kܥX[& @(X_VJ7_K)g 0@zzP] {ܔun"@|&vi@)s{?w& VV.ckb vEӣ=wq.] #}r2'x#@HhC\h9ݲ(| ~&|NfHP+^.R)\',!f\^gg"@g/{/s/|)A_^;`ze5\U,E ^{v |D0Фv2@·,1jyB d~Zf D 0@40w&遲+s97L,JNW Ϲ8x9O|v'@9}Ms9+?RYuyPsDS wl*].:Wbr8C 0?cǨܷT .=v;9V .x[+fri@zE2+? [nx1 w5=å ,DAÜU{=!HIs_%_l"@+HRVsYIo9y_@;~Qrϓis0'lw&@`?lrUp)WY|@0' wi=jj=u ÜՖ]Dx'PKo:xaN*j|k - R\2ɹ[m h, 5wKy Ü@ >>] åP<> sr6VCvvvr9. sr)= <>,PKvÜiU^]/p)m˚R{4 KyP$5 @@c1=$`r$D/^j .!W6ͧ" R.g.oK53%ikg"@ w/=Xˇ؆^ sZ RzeÜ < GQ2\d6T&&mp)s6aNl7&@@݁U1\< kyJI 8pw=P 2~cd6RBN" ܝPMåو9] w'nIK_ٹۿ sҿ @  ҿ~YK3 @@@( .!+&2lEZ-`TMV4IF;!@k>KyaN^oh" 5a F0lvQp)m s p ,K s&A@Kٮjv$@@w{( p)9i׆99Rk N짪R5aN9Y w760\mHÜܶ k2~B >OkbDҐZ\=xg0'O+ @`.nRvg.%O4 @5<$pR s)be' fJVLåcoR@Yjgr^8 Ü|B9z YOOǞ[ådsR  p0 .P.wig.%C' @R@7ߔ˴bg1N, ܝUånZݾj@R.L/ M߄*@L/aNv83w32 PhådC 0p7Pc(# "2'x @# P{L @peڽKqs]ywuHj:4'ÜZ  p .0'ݛY 0p7G;)2mM.%uyxD ww@`@ x٠ſ<3h"@ZZu +8@X3D' @pRӾWR s_GK p < P.Ӯ.%` @GOX3\aNZN* ܝU{wφK18pwܶUe˥ڼ7xD @,k}[PLj*XkIENDB`./assets/avatar-default@18.png0000644000015600001650000000471312677320771016277 0ustar jenkinsjenkinsPNG  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`./assets/contact-group.svg0000644000015600001650000003371112677320771015726 0ustar jenkinsjenkins image/svg+xml ./handler/0000755000015600001650000000000012677320772012527 5ustar jenkinsjenkins./handler/com.canonical.TelephonyServiceHandler.service.in0000644000015600001650000000021012677320771023777 0ustar jenkinsjenkins[D-BUS Service] Name=com.canonical.TelephonyServiceHandler Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-handler ./handler/Handler.xml0000644000015600001650000001643712677320771014640 0ustar jenkinsjenkins An interface to the phone handler helper application. ./handler/callhandler.cpp0000644000015600001650000003066312677320771015513 0ustar jenkinsjenkins/* * Copyright (C) 2012-2014 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 "accountentry.h" #include "tonegenerator.h" #include "greetercontacts.h" #include #include #include #define TELEPATHY_MUTE_IFACE "org.freedesktop.Telepathy.Call1.Interface.Mute" #define DBUS_PROPERTIES_IFACE "org.freedesktop.DBus.Properties" 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) { AccountEntry *accountEntry = TelepathyHelper::instance()->accountForConnection(channel->connection()); bool incoming = channel->initiatorContact() != accountEntry->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), mHangupRequested(false) { } void CallHandler::startCall(const QString &targetId, const QString &accountId) { // Request the contact to start audio call AccountEntry *accountEntry = TelepathyHelper::instance()->accountForId(accountId); if (!accountEntry) { return; } Tp::ConnectionPtr connection = accountEntry->account()->connection(); if (!connection) { return; } connect(connection->contactManager()->contactsForIdentifiers(QStringList() << targetId), 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; } Tp::PendingOperation *op = channel->requestHold(hold); connect(op, &Tp::PendingOperation::finished, [this, objectPath, op] { if (op->isError()) { Q_EMIT callHoldingFailed(objectPath); } }); } 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::setActiveAudioOutput(const QString &objectPath, const QString &id) { Tp::CallChannelPtr channel = callFromObjectPath(objectPath); QDBusInterface audioOutputsInterface(channel->busName(), channel->objectPath(), CANONICAL_TELEPHONY_AUDIOOUTPUTS_IFACE); audioOutputsInterface.call("SetActiveAudioOutput", id); } void CallHandler::sendDTMF(const QString &objectPath, const QString &key) { 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; } } /* * play locally (via tone generator) only if we are on a call, or if this is * dialpad sounds */ if (GreeterContacts::instance()->dialpadSoundsEnabled() && !GreeterContacts::instance()->silentMode() && objectPath.isEmpty() || !objectPath.isEmpty()) { ToneGenerator::instance()->playDTMFTone((uint)event); } 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()) { /* send DTMF to network (via telepathy and oFono) */ content->startDTMFTone(event); } } Q_EMIT callPropertiesChanged(channel->objectPath(), getCallProperties(channel->objectPath())); } void CallHandler::createConferenceCall(const QStringList &objectPaths) { QList calls; AccountEntry *accountEntry = 0; 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 (!accountEntry) { accountEntry = TelepathyHelper::instance()->accountForConnection(call->connection()); } // make sure all call channels belong to the same connection if (call->connection() != accountEntry->account()->connection()) { qWarning() << "It is not possible to merge channels from different accounts."; return; } calls.append(call); } if (calls.isEmpty() || !accountEntry) { 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. Tp::PendingChannelRequest *pcr = accountEntry->account()->createConferenceCall(calls, QStringList(), QDateTime::currentDateTime(), TP_QT_IFACE_CLIENT + ".TelephonyServiceHandler"); connect(pcr, &Tp::PendingChannelRequest::finished, [this, pcr] { Q_EMIT conferenceCallRequestFinished(!pcr->isError()); }); } 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) { QDBusInterface callChannelIface(channel->busName(), channel->objectPath(), DBUS_PROPERTIES_IFACE); QDBusMessage reply = callChannelIface.call("GetAll", CANONICAL_TELEPHONY_AUDIOOUTPUTS_IFACE); QVariantList args = reply.arguments(); QMap map = qdbus_cast >(args[0]); 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; } AccountEntry *accountEntry = TelepathyHelper::instance()->accountForConnection(pc->manager()->connection()); // start call to the contacts Q_FOREACH(Tp::ContactPtr contact, pc->contacts()) { accountEntry->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); if (mCallChannels.count() == 1) { mHangupRequested = true; } } void CallHandler::onCallChannelInvalidated() { Tp::CallChannelPtr channel(qobject_cast(sender())); if (channel.isNull()) { return; } mCallChannels.removeAll(channel); if (mCallChannels.isEmpty() && !mHangupRequested) { ToneGenerator::instance()->playCallEndedTone(); } mHangupRequested = false; } 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 &targetId) { Tp::CallChannelPtr channel; Q_FOREACH(const Tp::CallChannelPtr &ch, mCallChannels) { if (ch->isConference()) { continue; } AccountEntry *account = TelepathyHelper::instance()->accountForConnection(ch->connection()); if (!account) { continue; } if (account->compareIds(ch->targetContact()->id(), targetId)) { 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; } ./handler/main.cpp0000644000015600001650000000460412677320771014162 0ustar jenkinsjenkins/* * 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 "displaynamesettings.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(); QObject::connect(TelepathyHelper::instance(), &TelepathyHelper::setupReady, [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(setupReady()), &dbus, SLOT(connectToBus())); // instanciate the display name settings singleton, it will work by itself DisplayNameSettings::instance(); return app.exec(); } ./handler/callhandler.h0000644000015600001650000000520312677320771015150 0ustar jenkinsjenkins/* * 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 &targetId, const QString &accountId); void hangUpCall(const QString &objectPath); void setHold(const QString &objectPath, bool hold); void setMuted(const QString &objectPath, bool muted); void setActiveAudioOutput(const QString &objectPath, const QString &id); 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); void conferenceCallRequestFinished(bool succeeded); void callHoldingFailed(const QString &objectPath); protected: Tp::CallChannelPtr existingCall(const QString &targetId); 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; bool mHangupRequested; }; #endif // CALLHANDLER_H ./handler/displaynamesettings.cpp0000644000015600001650000000464512677320771017332 0ustar jenkinsjenkins/* * 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 "displaynamesettings.h" #include "accountentry.h" #include "telepathyhelper.h" namespace C { #include } #define DUAL_SIM_NAMES_KEY "simNames" // do not remove the following line. // it is used by the the ofono-setup script when creating new accounts #define SIM_DEFAULT_NAME C::gettext("SIM %1") DisplayNameSettings::DisplayNameSettings(QObject *parent) : QObject(parent), mSimNameSettings("com.ubuntu.phone") { connect(TelepathyHelper::instance(), SIGNAL(accountsChanged()), SLOT(onAccountsChanged())); connect(&mSimNameSettings, SIGNAL(changed(QString)), this, SLOT(onSettingsChanged(QString))); // force update during startup onSettingsChanged(DUAL_SIM_NAMES_KEY); } void DisplayNameSettings::onSettingsChanged(const QString &key) { if (key == DUAL_SIM_NAMES_KEY) { QVariantMap values = mSimNameSettings.get(DUAL_SIM_NAMES_KEY).value(); for(QVariantMap::const_iterator iter = values.begin(); iter != values.end(); ++iter) { mAccountNames[iter.key()] = iter.value().toString(); } onAccountsChanged(); } } DisplayNameSettings *DisplayNameSettings::instance() { static DisplayNameSettings *self = new DisplayNameSettings(); return self; } void DisplayNameSettings::onAccountsChanged() { Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { QString modemObjName = account->account()->parameters().value("modem-objpath").toString(); if (mAccountNames.contains(modemObjName) && account->displayName() != mAccountNames[modemObjName]) { account->setDisplayName(mAccountNames[modemObjName]); } } } ./handler/texthandler.cpp0000644000015600001650000004636312677320771015570 0ustar jenkinsjenkins/* * Copyright (C) 2012-2015 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 "texthandler.h" #include "phoneutils.h" #include "telepathyhelper.h" #include "config.h" #include "dbustypes.h" #include "accountentry.h" #include #include #include #define SMIL_TEXT_REGION "" #define SMIL_IMAGE_REGION "" #define SMIL_VIDEO_REGION "" #define SMIL_AUDIO_REGION "" #define SMIL_TEXT_PART "\ \ " #define SMIL_IMAGE_PART "\ \ " #define SMIL_VIDEO_PART "\ " #define SMIL_AUDIO_PART "\ " #define SMIL_FILE "\ \ \ %1\ \ \ \ %2\ \ " TextHandler::TextHandler(QObject *parent) : QObject(parent) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); qRegisterMetaType(); // track when the account becomes available connect(TelepathyHelper::instance(), SIGNAL(setupReady()), SLOT(onConnectedChanged())); } void TextHandler::onConnectedChanged() { if (!TelepathyHelper::instance()->ready()) { return; } // now check which accounts are connected Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) { QString accountId = account->accountId(); if (!account->connected()) { continue; } // create text channels to send the pending messages QList recipientsList; Q_FOREACH(const PendingMessage &pendingMessage, mPendingMessages) { if (accountId != pendingMessage.accountId) { continue; } bool found = false; // avoid adding twice the same list of participants Q_FOREACH(const QStringList &recipients, recipientsList) { if (recipients == pendingMessage.recipients) { found = true; break; } } if (!found) { recipientsList << pendingMessage.recipients; } } Q_FOREACH(const QStringList& recipients, recipientsList) { startChat(recipients, accountId); } } } TextHandler *TextHandler::instance() { static TextHandler *handler = new TextHandler(); return handler; } void TextHandler::startChat(const QStringList &recipients, 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 AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account->connected()) { qCritical() << "The selected account does not have a connection. AccountId:" << accountId; return; } connect(account->account()->connection()->contactManager()->contactsForIdentifiers(recipients), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactsAvailable(Tp::PendingOperation*))); } void TextHandler::startChatRoom(const QString &accountId, const QStringList &initialParticipants, const QVariantMap &properties) { Q_UNUSED(accountId) Q_UNUSED(initialParticipants) Q_UNUSED(properties) // FIXME: implement } 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[account->uniqueIdentifier()][contact->id()] = contact; } } Tp::MessagePartList TextHandler::buildMessage(const PendingMessage &pendingMessage) { Tp::MessagePartList message; Tp::MessagePart header; QString smil, regions, parts; bool hasImage = false, hasText = false, hasVideo = false, hasAudio = false, isMMS = false; AccountEntry *account = TelepathyHelper::instance()->accountForId(pendingMessage.accountId); if (!account) { // account does not exist return Tp::MessagePartList(); } bool temporaryFiles = (pendingMessage.properties.contains("x-canonical-tmp-files") && pendingMessage.properties["x-canonical-tmp-files"].toBool()); // add the remaining properties to the message header QVariantMap::const_iterator it = pendingMessage.properties.begin(); for (; it != pendingMessage.properties.end(); ++it) { header[it.key()] = QDBusVariant(it.value()); } // check if this message should be sent as an MMS if (account->type() == AccountEntry::PhoneAccount) { isMMS = (pendingMessage.attachments.size() > 0 || (header.contains("x-canonical-mms") && header["x-canonical-mms"].variant().toBool()) || (pendingMessage.recipients.size() > 1 && TelepathyHelper::instance()->mmsGroupChat())); if (isMMS) { header["x-canonical-mms"] = QDBusVariant(true); } } // this flag should not be in the message header, it's only useful for the handler header.remove("x-canonical-tmp-files"); header["message-type"] = QDBusVariant(0); message << header; // convert AttachmentList struct into telepathy Message parts Q_FOREACH(const AttachmentStruct &attachment, pendingMessage.attachments) { QByteArray fileData; QString newFilePath = QString(attachment.filePath).replace("file://", ""); QFile attachmentFile(newFilePath); if (!attachmentFile.open(QIODevice::ReadOnly)) { qWarning() << "fail to load attachment" << attachmentFile.errorString() << attachment.filePath; continue; } if (attachment.contentType.startsWith("image/")) { if (isMMS) { hasImage = true; parts += QString(SMIL_IMAGE_PART).arg(attachment.id); // check if we need to reduce de image size in case it's bigger than 300k // this check is only valid for MMS if (attachmentFile.size() > 307200) { QImage scaledImage(newFilePath); if (!scaledImage.isNull()) { QBuffer buffer(&fileData); buffer.open(QIODevice::WriteOnly); scaledImage.scaled(640, 640, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(&buffer, "jpg"); } } else { fileData = attachmentFile.readAll(); } } } else if (attachment.contentType.startsWith("video/")) { if (isMMS) { hasVideo = true; parts += QString(SMIL_VIDEO_PART).arg(attachment.id); } } else if (attachment.contentType.startsWith("audio/")) { if (isMMS) { hasAudio = true; parts += QString(SMIL_AUDIO_PART).arg(attachment.id); } } else if (attachment.contentType.startsWith("text/plain")) { if (isMMS) { hasText = true; parts += QString(SMIL_TEXT_PART).arg(attachment.id); } } else if (attachment.contentType.startsWith("text/vcard") || attachment.contentType.startsWith("text/x-vcard")) { } else if (isMMS) { // for MMS we just support the contentTypes above if (temporaryFiles) { attachmentFile.remove(); } continue; } if (fileData.isEmpty()) { fileData = attachmentFile.readAll(); } if (temporaryFiles) { attachmentFile.remove(); } if (hasVideo) { regions += QString(SMIL_VIDEO_REGION); } if (hasAudio) { regions += QString(SMIL_AUDIO_REGION); } if (hasText) { regions += QString(SMIL_TEXT_REGION); } if (hasImage) { regions += QString(SMIL_IMAGE_REGION); } Tp::MessagePart part; part["content-type"] = QDBusVariant(attachment.contentType); part["identifier"] = QDBusVariant(attachment.id); part["content"] = QDBusVariant(fileData); part["size"] = QDBusVariant(fileData.size()); message << part; } if (!pendingMessage.message.isEmpty()) { Tp::MessagePart part; QString tmpTextId("text_0.txt"); part["content-type"] = QDBusVariant(QString("text/plain")); part["identifier"] = QDBusVariant(tmpTextId); part["content"] = QDBusVariant(pendingMessage.message); part["size"] = QDBusVariant(pendingMessage.message.size()); if (isMMS) { parts += QString(SMIL_TEXT_PART).arg(tmpTextId); regions += QString(SMIL_TEXT_REGION); } message << part; } if (isMMS) { Tp::MessagePart smilPart; smil = QString(SMIL_FILE).arg(regions).arg(parts); smilPart["content-type"] = QDBusVariant(QString("application/smil")); smilPart["identifier"] = QDBusVariant(QString("smil.xml")); smilPart["content"] = QDBusVariant(smil); smilPart["size"] = QDBusVariant(smil.size()); message << smilPart; } return message; } QString TextHandler::sendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const AttachmentList &attachments, const QVariantMap &properties) { AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); if (!account) { // account does not exist return QString(); } // check if the message should be sent via multimedia account // we just use fallback to 1-1 chats if (account->type() == AccountEntry::PhoneAccount && recipients.size() == 1) { Q_FOREACH(AccountEntry *newAccount, TelepathyHelper::instance()->accounts()) { // TODO: we have to find the multimedia account that matches the same phone number, // but for now we just pick any multimedia connected account if (newAccount->type() != AccountEntry::MultimediaAccount) { continue; } // FIXME: the fallback implementation needs to be changed to use protocol info and create a map of // accounts. Also, it needs to check connection capabilities to determine if we can send message // to offline contacts. bool shouldFallback = false; // if the account is offline, dont fallback to this account if (!newAccount->connected()) { continue; } QList channels = existingChannels(recipients, newAccount->accountId()); // check if we have a channel for this contact already and get the contact pointer from there, // this way we avoid doing the while(op->isFinished()) all the time if (!channels.isEmpty()) { // if the contact is known, force fallback to this account Tp::Presence presence = channels.first()->targetContact()->presence(); shouldFallback = (presence.type() == Tp::ConnectionPresenceTypeAvailable || presence.type() == Tp::ConnectionPresenceTypeOffline); } else { Tp::PendingOperation *op = newAccount->account()->connection()->contactManager()->contactsForIdentifiers(recipients); while (!op->isFinished()) { qApp->processEvents(); } Tp::PendingContacts *pc = qobject_cast(op); if (pc) { Tp::Presence presence = pc->contacts().first()->presence(); shouldFallback = (presence.type() == Tp::ConnectionPresenceTypeAvailable || presence.type() == Tp::ConnectionPresenceTypeOffline); } } if (shouldFallback) { account = newAccount; break; } } } // keep recipient list always sorted to be able to compare QStringList sortedRecipients = recipients; sortedRecipients.sort(); PendingMessage pendingMessage = {account->accountId(), sortedRecipients, message, attachments, properties}; if (!account->connected()) { mPendingMessages.append(pendingMessage); return account->accountId(); } QList channels = existingChannels(recipients, account->accountId()); if (channels.isEmpty()) { mPendingMessages.append(pendingMessage); startChat(sortedRecipients, account->accountId()); return account->accountId(); } connect(channels.last()->send(buildMessage(pendingMessage)), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onMessageSent(Tp::PendingOperation*))); return account->accountId(); } void TextHandler::acknowledgeMessages(const QStringList &recipients, const QStringList &messageIds, const QString &accountId) { QList channels = existingChannels(recipients, accountId); if (channels.isEmpty()) { return; } QList messagesToAck; Q_FOREACH(const Tp::TextChannelPtr &channel, channels) { Q_FOREACH(const Tp::ReceivedMessage &message, channel->messageQueue()) { if (messageIds.contains(message.messageToken())) { messagesToAck.append(message); } } channel->acknowledge(messagesToAck); } } void TextHandler::acknowledgeAllMessages(const QStringList &recipients, const QString &accountId) { QList channels = existingChannels(recipients, accountId); if (channels.isEmpty()) { return; } Q_FOREACH(const Tp::TextChannelPtr &channel, channels) { channel->acknowledge(channel->messageQueue()); } } void TextHandler::onTextChannelInvalidated() { Tp::TextChannelPtr textChannel(qobject_cast(sender())); mChannels.removeAll(textChannel); AccountEntry *account = TelepathyHelper::instance()->accountForConnection(textChannel->connection()); if (account) { mContacts.remove(account->accountId()); } } void TextHandler::onTextChannelAvailable(Tp::TextChannelPtr channel) { AccountEntry *account = TelepathyHelper::instance()->accountForConnection(channel->connection()); if (!account) { return; } connect(channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,const QString&, const QString&)), SLOT(onTextChannelInvalidated())); QString accountId = account->accountId(); mChannels.append(channel); // check for pending messages for this channel if (mPendingMessages.isEmpty()) { return; } QList::iterator it = mPendingMessages.begin(); while (it != mPendingMessages.end()) { bool found = false; Q_FOREACH(const Tp::TextChannelPtr &existingChannel, existingChannels(it->recipients, it->accountId)) { if (existingChannel == channel) { // FIXME: we can't trust recipients for group chats in regular IM accounts sendMessage(it->accountId, it->recipients, it->message, it->attachments, it->properties); it = mPendingMessages.erase(it); found = true; break; } } if (!found) { ++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; } } QList TextHandler::existingChannels(const QStringList &targetIds, const QString &accountId) { QList channels; Q_FOREACH(const Tp::TextChannelPtr &channel, mChannels) { int count = 0; AccountEntry *channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection()); if (!channelAccount || channelAccount->accountId() != accountId) { continue; } // this is a special case. We have to check if we are looking for a channel open with our self contact. bool channelToSelfContact = channel->groupContacts(true).size() == 1 && targetIds.size() == 1 && channel->targetHandleType() == Tp::HandleTypeContact && channelAccount->compareIds(channel->targetId(), channelAccount->selfContactId()) && channelAccount->compareIds(targetIds.first(), channel->targetId()); // make sure we compare the recipient with the channel if (channelToSelfContact) { channels.append(channel); continue; } if (channel->groupContacts(false).size() != targetIds.size()) { continue; } Q_FOREACH(const QString &targetId, targetIds) { Q_FOREACH(const Tp::ContactPtr &channelContact, channel->groupContacts(false)) { if (channelAccount->compareIds(channelContact->id(), targetId)) { count++; } } } if (count == targetIds.size()) { channels.append(channel); } } return channels; } void TextHandler::onContactsAvailable(Tp::PendingOperation *op) { Tp::PendingContacts *pc = qobject_cast(op); if (!pc) { qCritical() << "The pending object is not a Tp::PendingContacts"; return; } AccountEntry *account = TelepathyHelper::instance()->accountForConnection(pc->manager()->connection()); startChat(account->account(), pc->contacts().toSet()); } ./handler/handlerdbus.cpp0000644000015600001650000001157212677320771015533 0ustar jenkinsjenkins/* * 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), mCallIndicatorVisible(false) { connect(CallHandler::instance(), SIGNAL(callPropertiesChanged(QString,QVariantMap)), SIGNAL(CallPropertiesChanged(QString,QVariantMap))); connect(CallHandler::instance(), SIGNAL(callHoldingFailed(QString)), SIGNAL(CallHoldingFailed(QString))); connect(CallHandler::instance(), SIGNAL(conferenceCallRequestFinished(bool)), SIGNAL(ConferenceCallRequestFinished(bool))); } 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::IsReady() { return TelepathyHelper::instance()->ready(); } bool HandlerDBus::callIndicatorVisible() const { return mCallIndicatorVisible; } void HandlerDBus::setCallIndicatorVisible(bool visible) { mCallIndicatorVisible = visible; Q_EMIT CallIndicatorVisibleChanged(visible); } 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; } QString HandlerDBus::SendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const AttachmentList &attachments, const QVariantMap &properties) { return TextHandler::instance()->sendMessage(accountId, recipients, message, attachments, properties); } void HandlerDBus::AcknowledgeMessages(const QStringList &numbers, const QStringList &messageIds, const QString &accountId) { TextHandler::instance()->acknowledgeMessages(numbers, messageIds, accountId); } void HandlerDBus::StartChat(const QString &accountId, const QStringList &participants) { TextHandler::instance()->startChat(participants, accountId); } void HandlerDBus::StartChatRoom(const QString &accountId, const QStringList &initialParticipants, const QVariantMap &properties) { TextHandler::instance()->startChatRoom(accountId, initialParticipants, properties); } void HandlerDBus::AcknowledgeAllMessages(const QStringList &numbers, const QString &accountId) { TextHandler::instance()->acknowledgeAllMessages(numbers, 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::SetActiveAudioOutput(const QString &objectPath, const QString &id) { CallHandler::instance()->setActiveAudioOutput(objectPath, id); } 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); } ./handler/texthandler.h0000644000015600001650000000505012677320771015221 0ustar jenkinsjenkins/* * 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 #include "dbustypes.h" struct PendingMessage { QString accountId; QStringList recipients; QString message; AttachmentList attachments; QVariantMap properties; }; Q_DECLARE_METATYPE(PendingMessage) class TextHandler : public QObject { Q_OBJECT public: static TextHandler *instance(); void startChat(const QStringList &recipients, const QString &accountId); void startChatRoom(const QString &accountId, const QStringList &initialParticipants, const QVariantMap &properties); void startChat(const Tp::AccountPtr &account, const Tp::Contacts &contacts); public Q_SLOTS: QString sendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const AttachmentList &attachments, const QVariantMap &properties); void acknowledgeMessages(const QStringList &recipients, const QStringList &messageIds, const QString &accountId); void acknowledgeAllMessages(const QStringList &recipients, const QString &accountId); protected Q_SLOTS: void onTextChannelAvailable(Tp::TextChannelPtr channel); void onTextChannelInvalidated(); void onContactsAvailable(Tp::PendingOperation *op); void onMessageSent(Tp::PendingOperation *op); void onConnectedChanged(); protected: QList existingChannels(const QStringList &targetIds, const QString &accountId); private: explicit TextHandler(QObject *parent = 0); Tp::MessagePartList buildMessage(const PendingMessage &pendingMessage); QList mChannels; QMap > mContacts; QList mPendingMessages; }; #endif // TEXTHANDLER_H ./handler/handler.h0000644000015600001650000000417212677320771014320 0ustar jenkinsjenkins/* * 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; QMap > mContexts; }; #endif // HANDLER_H ./handler/handlerdbus.h0000644000015600001650000000651212677320771015176 0ustar jenkinsjenkins/* * 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" #include "dbustypes.h" /** * DBus interface for the phone approver */ class HandlerDBus : public QObject, protected QDBusContext { Q_OBJECT Q_PROPERTY(bool CallIndicatorVisible READ callIndicatorVisible WRITE setCallIndicatorVisible NOTIFY CallIndicatorVisibleChanged) public: HandlerDBus(QObject* parent=0); ~HandlerDBus(); QVariantMap GetCallProperties(const QString &objectPath); bool HasCalls(); QStringList AccountIds(); bool IsReady(); bool callIndicatorVisible() const; void setCallIndicatorVisible(bool visible); public Q_SLOTS: bool connectToBus(); // messages related QString SendMessage(const QString &accountId, const QStringList &recipients, const QString &message, const AttachmentList &attachments, const QVariantMap &properties); Q_NOREPLY void AcknowledgeMessages(const QStringList &numbers, const QStringList &messageIds, const QString &accountId); Q_NOREPLY void StartChat(const QString &accountId, const QStringList &participants); Q_NOREPLY void StartChatRoom(const QString &accountId, const QStringList &initialParticipants, const QVariantMap &properties); Q_NOREPLY void AcknowledgeAllMessages(const QStringList &numbers, 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 SetActiveAudioOutput(const QString &objectPath, const QString &id); 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); void CallIndicatorVisibleChanged(bool visible); void ConferenceCallRequestFinished(bool succeeded); void CallHoldingFailed(const QString &objectPath); private: bool mCallIndicatorVisible; }; #endif // HANDLERDBUS_H ./handler/displaynamesettings.h0000644000015600001650000000235712677320771016775 0ustar jenkinsjenkins/* * 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 DISPLAYNAMESETTINGS_H #define DISPLAYNAMESETTINGS_H #include #include #include "qgsettings.h" class DisplayNameSettings : public QObject { Q_OBJECT public: static DisplayNameSettings *instance(); private Q_SLOTS: void onAccountsChanged(); void onSettingsChanged(const QString &key); private: QGSettings mSimNameSettings; explicit DisplayNameSettings(QObject *parent = 0); QMap mAccountNames; }; #endif // DISPLAYNAMESETTINGS_H ./handler/handler.cpp0000644000015600001650000001466312677320771014661 0ustar jenkinsjenkins/* * 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 "accountentry.h" #include "protocolmanager.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(connection) Q_UNUSED(requestsSatisfied) Q_UNUSED(userActionTime) Q_UNUSED(handlerInfo) if (!ProtocolManager::instance()->isProtocolSupported(account->protocolName())) { context->setFinishedWithError(TP_QT_ERROR_NOT_CAPABLE, "The account for this request is not supported."); return; } Q_FOREACH(const Tp::ChannelPtr channel, channels) { mContexts[channel.data()] = context; 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; } } } Tp::ChannelClassSpecList Handler::channelFilters() { Tp::ChannelClassSpecList specList; specList << TelepathyHelper::audioConferenceSpec(); specList << Tp::ChannelClassSpec::audioCall(); specList << Tp::ChannelClassSpec::textChat(); specList << Tp::ChannelClassSpec::unnamedTextChat(); 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); Tp::MethodInvocationContextPtr<> context = mContexts.take(textChannel.data()); if (context) { context->setFinished(); } 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.take(pr); Tp::CallChannelPtr callChannel = Tp::CallChannelPtr::dynamicCast(channel); Tp::MethodInvocationContextPtr<> context = mContexts.take(channel.data()); if(!callChannel) { if (context) { context->setFinishedWithError(TP_QT_ERROR_CONFUSED, "Channel was not a call channel"); } qCritical() << "The saved channel is not a Tp::CallChannel"; return; } // if the call is neither Accepted nor Active, it means it got dispatched directly to the handler without passing // through any approver. For phone calls, this would mean calls getting auto-accepted which is not desirable // so we return an error here bool incoming = false; AccountEntry *accountEntry = TelepathyHelper::instance()->accountForConnection(callChannel->connection()); if (accountEntry) { incoming = callChannel->initiatorContact() != accountEntry->account()->connection()->selfContact(); } if (incoming && callChannel->callState() != Tp::CallStateAccepted && callChannel->callState() != Tp::CallStateActive) { qWarning() << "Available channel was not approved by telephony-service-approver, ignoring it."; if (context) { context->setFinishedWithError(TP_QT_ERROR_NOT_CAPABLE, "Only channels approved and accepted by telephony-service-approver are supported"); } return; } if (context) { context->setFinished(); } Q_EMIT callChannelAvailable(callChannel); } ./handler/org.freedesktop.Telepathy.Client.TelephonyServiceHandler.service.in0000644000015600001650000000023312677320771027554 0ustar jenkinsjenkins[D-BUS Service] Name=org.freedesktop.Telepathy.Client.TelephonyServiceHandler Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/telephony-service-handler ./handler/TelephonyServiceHandler.client0000644000015600001650000000124412677320771020515 0ustar jenkinsjenkins[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.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=0 [org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 2] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Call1 ./handler/CMakeLists.txt0000644000015600001650000000261012677320771015265 0ustar jenkinsjenkins set(qt_SRCS callhandler.cpp displaynamesettings.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} ${GSETTINGS_QT_INCLUDE_DIRS} ) 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} ${GSETTINGS_QT_LDFLAGS} telephonyservice ) enable_coverage(telephony-service-handler) 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) ./upstart/0000755000015600001650000000000012677320772012614 5ustar jenkinsjenkins./upstart/telephony-service-indicator.conf0000644000015600001650000000031512677320771021100 0ustar jenkinsjenkinsdescription "telephony-service-indicator" author "Tiago Salem Herrmann " start on stopped ofono-setup stop on desktop-end respawn exec /usr/bin/telephony-service-indicator ./CMakeLists.txt0000644000015600001650000001072312677320771013654 0ustar jenkinsjenkinsproject(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) # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) # just to make debug easier, print the system processor message(STATUS "System processor: ${CMAKE_SYSTEM_PROCESSOR}") # Check if should build using ubuntu platform api check_include_file_cxx("ubuntu/application/init.h" USE_UBUNTU_PLATFORM_API) if (USE_UBUNTU_PLATFORM_API) add_definitions(-DUSE_UBUNTU_PLATFORM_API) endif (USE_UBUNTU_PLATFORM_API) set(TELEPHONY_SERVICE_DIR ${CMAKE_INSTALL_DATADIR}/telephony-service) configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) # uninstall target configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") find_package(Qt5Contacts) find_package(Qt5DBus) #find_package(Qt5Gui) find_package(Qt5Multimedia) find_package(Qt5Qml) #find_package(Qt5Quick) find_package(Qt5Test) find_package(Qt5Feedback) find_package(LibPhoneNumber REQUIRED) include(qt5) if(NOT CMAKE_CROSSCOMPILING) find_program(QMAKE_EXECUTABLE qmake) if(QMAKE_EXECUTABLE STREQUAL "QMAKE_EXECUTABLE-NOTFOUND") message(FATAL_ERROR "qmake not found") endif() execute_process( COMMAND ${QMAKE_EXECUTABLE} -query QT_INSTALL_QML RESULT_VARIABLE RESULT OUTPUT_VARIABLE QT_INSTALL_QML OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT RESULT EQUAL 0) message(FATAL_ERROR "Failed to determine QT_INSTALL_QML from qmake") endif() else() # qmake isn't multi-arch aware as it installs arch-specific mkspec files # in to /usr/share, so we can't use it here (we'd need a qmake binary # for the host arch using data for the target arch) set(QT_INSTALL_QML "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/qt5/qml") endif() 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) pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) add_definitions(-DQT_NO_KEYWORDS) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) # generate a macro to make it easier to enable coverage support on targets function(ENABLE_COVERAGE) get_directory_property(COVERAGE_TARGETS DIRECTORY ${CMAKE_SOURCE_DIR} COVERAGE_TARGETS) list(APPEND COVERAGE_TARGETS ${ARGN}) MESSAGE(STATUS "Enabling coverage report for target(s): ${ARGN}") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY COVERAGE_TARGETS ${COVERAGE_TARGETS}) endfunction() 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) add_subdirectory(tests) add_subdirectory(protocols) 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" ) GET_DIRECTORY_PROPERTY(COVERAGE_TARGETS DIRECTORY ${CMAKE_SOURCE_DIR} COVERAGE_TARGETS) ENABLE_COVERAGE_REPORT(TARGETS ${COVERAGE_TARGETS}) ENDIF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE])