From 08a45cc521634ebcf0f16766c547a075fe54c33047f72a57798cbc707d347a5d Mon Sep 17 00:00:00 2001 From: Hrvoje Senjan Date: Tue, 10 Mar 2015 19:15:10 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/KDE:Frameworks5/bluedevil5?expand=0&rev=14 --- bluedevil5.changes | 7 + bluedevil5.spec | 3 + sync-with-master.patch | 4003 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 4013 insertions(+) create mode 100644 sync-with-master.patch diff --git a/bluedevil5.changes b/bluedevil5.changes index a2a9722..7bd905b 100644 --- a/bluedevil5.changes +++ b/bluedevil5.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Mar 10 19:05:57 UTC 2015 - hrvoje.senjan@gmail.com + +- Added sync-with-master.patch, contains fixes for kde#343682, + kde#342581, kde#342259, kde#321560, kde#341768, kde#337193, + kde#314356, kde#332014 and many other improvements + ------------------------------------------------------------------- Fri Feb 20 02:43:48 UTC 2015 - hrvoje.senjan@gmail.com diff --git a/bluedevil5.spec b/bluedevil5.spec index 9fbf91f..086419f 100644 --- a/bluedevil5.spec +++ b/bluedevil5.spec @@ -26,6 +26,8 @@ Group: Hardware/Other Url: http://www.kde.org/ Source: bluedevil-%{version}.tar.xz Source99: %{name}-rpmlintrc +# PATCH-FIX-UPSTREAM sync-with-master.patch +Patch0: sync-with-master.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: kcoreaddons-devel BuildRequires: kdbusaddons-devel @@ -54,6 +56,7 @@ Bluetooth daemon for KDE, handling connections. %lang_package %prep %setup -q -n bluedevil-%{version} +%patch0 -p1 %build %cmake_kf5 -d build -- -DCMAKE_INSTALL_LOCALEDIR=share/locale/kf5 diff --git a/sync-with-master.patch b/sync-with-master.patch new file mode 100644 index 0000000..27a1450 --- /dev/null +++ b/sync-with-master.patch @@ -0,0 +1,4003 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 9e1f264..98a8c70 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,5 +1,6 @@ + project(bluedevil) +-set(PROJECT_VERSION "5.2.1") ++set(PROJECT_VERSION "5.2.90") ++set(PROJECT_VERSION_MAJOR 5) + + cmake_minimum_required(VERSION 2.8.12) + +@@ -8,7 +9,7 @@ configure_file(version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h) + find_package(ECM REQUIRED NO_MODULE) + set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) + +-set(QT_MIN_VERSION "5.2.0") ++set(QT_MIN_VERSION "5.4.0") + find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS + Core + Widgets +diff --git a/README b/README +index b701b77..b819ed7 100644 +--- a/README ++++ b/README +@@ -1,14 +1,11 @@ + BlueDevil runtime dependencies: +- -obex-data-server ++ -bluez5 ++ -General Bluetooth management ++ ++ -bluez-obexd + -Be able to "Browse File" aka kio_obexftp ++ -Be able to "Send Files" (bluedevil-sendfile) + -Be able to receive files + +- -obexd-client +- -Be able to Send files (bluedevil-sendfile) +- +- -If you're using Alsa: +- The best way of having "automagical headset configuration" is having the bluetooth.conf hook +- enabled +- +- NOTE: Be sure to install only obexd-client and not obexd-server, since the last will conflic +- with obex-data-server. +\ No newline at end of file ++ -pulseaudio-module-bluetooth ++ -Be able to connect A2DP profile +diff --git a/src/XmlMessages.sh b/src/XmlMessages.sh +new file mode 100755 +index 0000000..05651f5 +--- /dev/null ++++ b/src/XmlMessages.sh +@@ -0,0 +1,22 @@ ++function get_files ++{ ++ echo bluedevil-mime.xml ++} ++ ++function po_for_file ++{ ++ case "$1" in ++ bluedevil-mime.xml) ++ echo bluedevil_xml_mimetypes.po ++ ;; ++ esac ++} ++ ++function tags_for_file ++{ ++ case "$1" in ++ bluedevil-mime.xml) ++ echo comment ++ ;; ++ esac ++} +diff --git a/src/bluedevil-mime.xml b/src/bluedevil-mime.xml +index 669147d..dc4af15 100644 +--- a/src/bluedevil-mime.xml ++++ b/src/bluedevil-mime.xml +@@ -17,27 +17,195 @@ Notes: + + + Known Device ++ Poznat uređaj ++ Dispositiu conegut ++ Známé zařízení ++ Kendt enhed ++ Bekanntes Gerät ++ Γνωστή συσκευή ++ Known Device ++ Dispositivo conocido ++ Tunnettu laite ++ Périphérique connu ++ Dispositivo conosciuto ++ Bekend apparaat ++ Znane urządzenie ++ Dispositivo Conhecido ++ Dispositivo conhecido ++ Známe zariadenie ++ Znana naprava ++ познати уређај ++ познати уређај ++ poznati uređaj ++ poznati uređaj ++ Känd enhet ++ Відомий пристрій ++ 已知的裝置 + + + + + Discovered Device ++ Otkriven uređaj ++ Dispositiu descobert ++ Objevené zařízení ++ Opdaget enhed ++ Erkanntes Gerät ++ Ευρεθείσα συσκευή ++ Discovered Device ++ Dispositivo descubierto ++ Löydetty palvelu ++ Périphérique découvert ++ Dispositivo scoperto ++ Gevonden apparaat ++ Odkryte urządzenie ++ Dispositivo Descoberto ++ Dispositivo descoberto ++ Objavené zariadenie ++ Odkrita naprava ++ откривени уређај ++ откривени уређај ++ otkriveni uređaj ++ otkriveni uređaj ++ Upptäckt enhet ++ Виявлений пристрій ++ 已發現的裝置 + + + + + Service ++ Usluga ++ Servei ++ Služba ++ Tjeneste ++ Dienst ++ Υπηρεσία ++ Service ++ Servicio ++ Palvelu ++ Service ++ Servizio ++ Service ++ Usługa ++ Serviço ++ Serviço ++ Služba ++ Storitev ++ сервис ++ сервис ++ servis ++ servis ++ Tjänst ++ Служба ++ 服務 + + + Service ++ Usluga ++ Servei ++ Služba ++ Tjeneste ++ Dienst ++ Υπηρεσία ++ Service ++ Servicio ++ Palvelu ++ Service ++ Servizio ++ Service ++ Usługa ++ Serviço ++ Serviço ++ Služba ++ Storitev ++ сервис ++ сервис ++ servis ++ servis ++ Tjänst ++ Служба ++ 服務 + + + Service ++ Usluga ++ Servei ++ Služba ++ Tjeneste ++ Dienst ++ Υπηρεσία ++ Service ++ Servicio ++ Palvelu ++ Service ++ Servizio ++ Service ++ Usługa ++ Serviço ++ Serviço ++ Služba ++ Storitev ++ сервис ++ сервис ++ servis ++ servis ++ Tjänst ++ Служба ++ 服務 + + + Service ++ Usluga ++ Servei ++ Služba ++ Tjeneste ++ Dienst ++ Υπηρεσία ++ Service ++ Servicio ++ Palvelu ++ Service ++ Servizio ++ Service ++ Usługa ++ Serviço ++ Serviço ++ Služba ++ Storitev ++ сервис ++ сервис ++ servis ++ servis ++ Tjänst ++ Служба ++ 服務 + + + Service ++ Usluga ++ Servei ++ Služba ++ Tjeneste ++ Dienst ++ Υπηρεσία ++ Service ++ Servicio ++ Palvelu ++ Service ++ Servizio ++ Service ++ Usługa ++ Serviço ++ Serviço ++ Služba ++ Storitev ++ сервис ++ сервис ++ servis ++ servis ++ Tjänst ++ Служба ++ 服務 + + +diff --git a/src/bluedevil.notifyrc b/src/bluedevil.notifyrc +index bda24b0..81433dd 100644 +--- a/src/bluedevil.notifyrc ++++ b/src/bluedevil.notifyrc +@@ -1,16 +1,26 @@ + [Global] + IconName=preferences-system-bluetooth + Comment=Bluetooth system ++Comment[ast]=Sistema Bluetooth ++Comment[bs]=Bluetooth sistem + Comment[ca]=Sistema Bluetooth + Comment[cs]=Systém Bluetooth + Comment[de]=Bluetooth-System ++Comment[el]=Σύστημα Bluetooth + Comment[en_GB]=Bluetooth system + Comment[es]=Sistema Bluetooth ++Comment[et]=Bluetoothi süsteem + Comment[fi]=Bluetooth-järjestelmä + Comment[fr]=Système Bluetooth + Comment[it]=Sistema Bluetooth ++Comment[ja]=Bluetooth システム ++Comment[kk]=Bluetooth жүйесі ++Comment[ko]=블루투스 시스템 ++Comment[lt]=Bluetooth ++Comment[mr]=ब्लूटूथ प्रणाली + Comment[nb]=Blåtann-system + Comment[nl]=Bluetooth-systeem ++Comment[pa]=ਬਲਿਊਟੁੱਥ ਸਿਸਟਮ + Comment[pl]=System Bluetooth + Comment[pt]=Sistema Bluetooth + Comment[pt_BR]=Sistema Bluetooth +@@ -21,20 +31,31 @@ Comment[sr@ijekavian]=Блутут систем + Comment[sr@ijekavianlatin]=Bluetooth sistem + Comment[sr@latin]=Bluetooth sistem + Comment[sv]=Blåtandsystem ++Comment[tr]=Bluetooth sistemi + Comment[uk]=Система Bluetooth + Comment[x-test]=xxBluetooth systemxx + Comment[zh_CN]=蓝牙系统 ++Comment[zh_TW]=藍牙系統 + Name=Bluetooth ++Name[bs]=Blutut + Name[ca]=Bluetooth + Name[cs]=Bluetooth + Name[de]=Bluetooth ++Name[el]=Bluetooth + Name[en_GB]=Bluetooth + Name[es]=Bluetooth ++Name[et]=Bluetooth + Name[fi]=Bluetooth + Name[fr]=Bluetooth + Name[it]=Bluetooth ++Name[ja]=Bluetooth ++Name[kk]=Bluetooth ++Name[ko]=블루투스 ++Name[lt]=Bluetooth ++Name[mr]=ब्लूटूथ + Name[nb]=Blåtann + Name[nl]=Bluetooth ++Name[pa]=ਬਲਿਊਟੁੱਥ + Name[pl]=Bluetooth + Name[pt]=Bluetooth + Name[pt_BR]=Bluetooth +@@ -45,18 +66,23 @@ Name[sr@ijekavian]=Блутут + Name[sr@ijekavianlatin]=Bluetooth + Name[sr@latin]=Bluetooth + Name[sv]=Blåtand ++Name[tr]=Bluetooth + Name[uk]=Bluetooth + Name[x-test]=xxBluetoothxx + Name[zh_CN]=蓝牙 ++Name[zh_TW]=藍牙 + Ignore=true + + [Event/bluedevilAuthorize] + Name=Authorization Requested ++Name[bs]=Zahtijeva odobrenje + Name[ca]=Sol·licitud d'autorització + Name[cs]=Je vyžadováno udělení oprávnění + Name[de]=Autorisierung gefordert ++Name[el]=Απαιτείται ταυτοποίηση + Name[en_GB]=Authorisation Requested + Name[es]=Se ha solicitado autorización ++Name[et]=Autentimise nõue + Name[fi]=Valtuutusta pyydetty + Name[fr]=Autorisation demandée + Name[it]=Richiesta autorizzazione +@@ -72,15 +98,20 @@ Name[sr@ijekavian]=Неопходно овлашћивање + Name[sr@ijekavianlatin]=Neophodno ovlašćivanje + Name[sr@latin]=Neophodno ovlašćivanje + Name[sv]=Behörighet begärd ++Name[tr]=Yetkilendirme Gerekli + Name[uk]=Слід пройти розпізнавання + Name[x-test]=xxAuthorization Requestedxx + Name[zh_CN]=要求认证 ++Name[zh_TW]=請求認證 + Comment=A device wants to connect ++Comment[bs]=Uređaj se zeli konektovati + Comment[ca]=Un dispositiu es vol connectar + Comment[cs]=Zařízení se chce připojit + Comment[de]=Ein Gerät möchte sich verbinden ++Comment[el]=Μία συσκευή επιθυμεί να συνδεθεί + Comment[en_GB]=A device wants to connect +-Comment[es]=Un dispositivo quiere conectarse ++Comment[es]=Un dispositivo desea conectarse ++Comment[et]=Seade soovib ühendust luua + Comment[fi]=Laite haluaa ottaa yhteyden + Comment[fr]=Un périphérique veut se connecter + Comment[it]=Un dispositivo vuole connettersi +@@ -96,18 +127,23 @@ Comment[sr@ijekavian]=Уређај жели да се повеже + Comment[sr@ijekavianlatin]=Uređaj želi da se poveže + Comment[sr@latin]=Uređaj želi da se poveže + Comment[sv]=En enhet vill ansluta ++Comment[tr]=Bir aygıt bağlanmak istiyor + Comment[uk]=Отримано запит щодо з’єднання пристрою з комп’ютером + Comment[x-test]=xxA device wants to connectxx + Comment[zh_CN]=一个设备想要连接 ++Comment[zh_TW]=某個裝置希望能與您連線 + Action=Popup + + [Event/bluedevilConfirmModechange] + Name=Confirm Mode Change ++Name[bs]=Povrdi promijene moda + Name[ca]=Confirmació del canvi de mode + Name[cs]=Potvrdit změnu režimu + Name[de]=Moduswechsel bestätigen ++Name[el]=Επιβεβαίωση αλλαγής λειτουργίας + Name[en_GB]=Confirm Mode Change + Name[es]=Confirmar el cambio de modo ++Name[et]=Režiimimuutuse kinnitus + Name[fi]=Vahvistan tilan vaihto + Name[fr]=Confirmer le changement de mode + Name[it]=Conferma cambio di modalità +@@ -123,13 +159,17 @@ Name[sr@ijekavian]=Потврди промену режима + Name[sr@ijekavianlatin]=Potvrdi promenu režima + Name[sr@latin]=Potvrdi promenu režima + Name[sv]=Bekräfta lägesändring ++Name[tr]=Kip Değişikliğini Onayla + Name[uk]=Підтвердження зміни режиму + Name[x-test]=xxConfirm Mode Changexx + Name[zh_CN]=确认模式变更 ++Name[zh_TW]=確認模式變更 + Comment=Bluetooth mode is about to be changed (normal to flight for example) ++Comment[bs]=Režim blututa će biti promijenjen (npr. s normalnog na ljetni) + Comment[ca]=El mode Bluetooth és a punt de canviar (de mode normal a mode avió per exemple) + Comment[cs]=Bude změněn režim Bluetooth (např. Normální na V letadle) + Comment[de]=Der Bluetooth-Modus ist im Begriff, sich zu ändern (z. B. von normal auf Flugzeugmodus) ++Comment[el]=Η λειτουργία του Bluetooth πρόκειται να αλλάξει (π.χ. από κανονική σε πτήσης) + Comment[en_GB]=Bluetooth mode is about to be changed (normal to flight for example) + Comment[es]=El modo Bluetooth está a punto de cambiar (de normal a vuelo, por ejemplo) + Comment[fi]=Bluetooth-tilaa muutetaan (esim. tavallisesta lentokonetilaksi) +@@ -147,23 +187,31 @@ Comment[sr@ijekavian]=Режим блутута ће бити промијење + Comment[sr@ijekavianlatin]=Režim Bluetootha će biti promijenjen (npr. s normalnog na ljetni) + Comment[sr@latin]=Režim Bluetootha će biti promenjen (npr. s normalnog na letni) + Comment[sv]=Blåtandläget ska just ändras (exempelvis från normal till flygning) ++Comment[th]=โหมดของบลูทูทจะถูกเปลี่ยนโหมด (เช่น จากโหมดปกติเป็นโหมดไฟลท์ เป็นต้น) ++Comment[tr]=Bluetooth kipi değiştirilmek üzere (örn. normal -> uçuş kipi) ++Comment[ug]=كۆكچىش ھالىتى ئۆزگەرتىلدى(مەسىلەن: نورمال -› ئۈچۈشقا) + Comment[uk]=Зміна режиму роботи Bluetooth (наприклад, зі звичайного на автономний) + Comment[x-test]=xxBluetooth mode is about to be changed (normal to flight for example)xx + Comment[zh_CN]=蓝牙模式即将更改(例如从正常变到飞行模式) ++Comment[zh_TW]=即將改變藍牙模式(例如從一般模式轉換為飛航模式) + Action=Popup + + [Event/bluedevilRequestConfirmation] + Name=Confirm PIN ++Name[bs]=Potvrdi pin + Name[ca]=Confirmació del PIN + Name[cs]=Potvrdit PIN + Name[de]=PIN bestätigen ++Name[el]=Επιβεβαίωση PIN + Name[en_GB]=Confirm PIN + Name[es]=Confirmar PIN ++Name[et]=PIN-i kinnitus + Name[fi]=Vahvista PIN + Name[fr]=Confirmer le code « PIN » + Name[it]=Conferma PIN + Name[nb]=Bekreft PIN + Name[nl]=PIN bevestigen ++Name[pa]=ਤਸਦੀਕ ਪਿਨ + Name[pl]=Potwierdź numer PIN + Name[pt]=Confirmar o PIN + Name[pt_BR]=Confirmar o PIN +@@ -174,15 +222,20 @@ Name[sr@ijekavian]=Потврди ПИН + Name[sr@ijekavianlatin]=Potvrdi PIN + Name[sr@latin]=Potvrdi PIN + Name[sv]=Bekräfta PIN-kod ++Name[tr]=PIN'i Onaylayın + Name[uk]=Підтвердження PIN + Name[x-test]=xxConfirm PINxx + Name[zh_CN]=确认 PIN ++Name[zh_TW]=確認 PIN 碼 + Comment=Confirm a device request using matching PINs ++Comment[bs]=Potvrdi zahtjev uređaja koristeci odgovarajuce pinove + Comment[ca]=Confirma una sol·licitud d'un dispositiu usant PIN que coincideixin + Comment[cs]=Potvrďte požadavek zařízení použitím odpovídajících PINů + Comment[de]=Eine Geräteanforderung mit passenden PINs bestätigen ++Comment[el]=Επιβεβαίωση αίτησης συσκευής που χρησιμοποιεί ταιριαστά PIN + Comment[en_GB]=Confirm a device request using matching PINs +-Comment[es]=Confirmar la solicitud de un dispositivo usando un PIN coincidente ++Comment[es]=Confirmar la petición de un dispositivo usando PIN emparejados ++Comment[et]=Seadme nõude kinnitamine sobivate PIN-idega + Comment[fi]=Vahvista laitepyyntö käyttämällä samoja PIN-lukuja + Comment[fr]=Confirme une demande d'un périphérique utilisant une correspondance de codes « PIN » + Comment[it]=Conferma la richiesta di un dispositivo usando PIN corrispondenti +@@ -198,16 +251,20 @@ Comment[sr@ijekavian]=Потврдите захтев уређаја одгов + Comment[sr@ijekavianlatin]=Potvrdite zahtev uređaja odgovarajućim PIN‑om + Comment[sr@latin]=Potvrdite zahtev uređaja odgovarajućim PIN‑om + Comment[sv]=Bekräfta att en enhetsbegäran använder PIN-koder som stämmer ++Comment[tr]=Eşleştirme PIN'i kullanarak bir aygıt isteğini onaylayın + Comment[uk]=Підтвердження запиту пристрою відповідними PIN-кодами + Comment[x-test]=xxConfirm a device request using matching PINsxx + Comment[zh_CN]=确认设备请求使用了匹配的 PIN ++Comment[zh_TW]=利用比對 PIN 碼確認裝置的要求 + Action=Popup + + [Event/bluedevilRequestPin] + Name=Request PIN ++Name[bs]=Zahtijevaj PIN + Name[ca]=Sol·licita el PIN + Name[cs]=Vyžádat PIN + Name[de]=PIN anfordern ++Name[el]=Αίτηση PIN + Name[en_GB]=Request PIN + Name[es]=Solicitar PIN + Name[fi]=Pyydä PINiä +@@ -215,6 +272,7 @@ Name[fr]=Demande de code « PIN » + Name[it]=Richiesta PIN + Name[nb]=Be om PIN + Name[nl]=Om PIN verzoeken ++Name[pa]=ਬੇਨਤੀ ਪਿਨ + Name[pl]=Żąda numeru PIN + Name[pt]=Pedir o PIN + Name[pt_BR]=Solicitar o PIN +@@ -225,20 +283,31 @@ Name[sr@ijekavian]=Захтијевај ПИН + Name[sr@ijekavianlatin]=Zahtijevaj PIN + Name[sr@latin]=Zahtevaj PIN + Name[sv]=Begär PIN-kod ++Name[tr]=PIN iste + Name[uk]=Запит щодо PIN-коду + Name[x-test]=xxRequest PINxx + Name[zh_CN]=请求 PIN ++Name[zh_TW]=需要 PIN 碼 + Comment=A PIN is needed ++Comment[bs]=Potreban je PIN + Comment[ca]=Es necessita un PIN + Comment[cs]=Je potřeba PIN + Comment[de]=Eine PIN wird benötigt ++Comment[el]=Απαιτείται PIN + Comment[en_GB]=A PIN is needed + Comment[es]=Se necesita un PIN + Comment[fi]=PIN vaaditaan + Comment[fr]=Un code « PIN » est nécessaire + Comment[it]=Un PIN è richiesto ++Comment[ja]=PIN が必要です ++Comment[kk]=PIN -коды керек ++Comment[km]=ត្រូវការ PIN ++Comment[ko]=PIN이 필요함 ++Comment[lt]=Reikia PIN ++Comment[mr]=PIN ची गरज आहे + Comment[nb]=En PIN kreves + Comment[nl]=Er is een PIN nodig ++Comment[pa]=ਪਿਨ ਦੀ ਲੋੜ ਹੈ + Comment[pl]=Potrzebny jest numer PIN + Comment[pt]=É necessário um PIN + Comment[pt_BR]=É necessário um PIN +@@ -249,16 +318,20 @@ Comment[sr@ijekavian]=Потребан је ПИН + Comment[sr@ijekavianlatin]=Potreban je PIN + Comment[sr@latin]=Potreban je PIN + Comment[sv]=En PIN-kod behövs ++Comment[tr]=PIN gerekiyor + Comment[uk]=Потрібен PIN-код + Comment[x-test]=xxA PIN is neededxx + Comment[zh_CN]=需要 PIN ++Comment[zh_TW]=需要 PIN 碼 + Action=Popup + + [Event/bluedevilIncomingFile] + Name=Incoming File ++Name[bs]=Dolazeća datoteka + Name[ca]=Fitxer entrant + Name[cs]=Příchozí soubor + Name[de]=Eingehende Datei ++Name[el]=Εισερχόμενο αρχείο + Name[en_GB]=Incoming File + Name[es]=Archivo entrante + Name[fi]=Saapuva tiedosto +@@ -266,6 +339,7 @@ Name[fr]=Fichier entrant + Name[it]=File in arrivo + Name[nb]=Innkommende fil + Name[nl]=Bestand aangeboden ++Name[pa]=ਆ ਰਹੀ ਫਾਇਲ + Name[pl]=Przychodzący plik + Name[pt]=Ficheiro Recebido + Name[pt_BR]=Arquivo recebido +@@ -276,20 +350,26 @@ Name[sr@ijekavian]=Долазни фајл + Name[sr@ijekavianlatin]=Dolazni fajl + Name[sr@latin]=Dolazni fajl + Name[sv]=Inkommande fil ++Name[tr]=Gelen Dosya + Name[uk]=Вхідний файл + Name[x-test]=xxIncoming Filexx + Name[zh_CN]=正在传入的文件 ++Name[zh_TW]=要傳進來的檔案 + Comment=Incoming file transfer ++Comment[bs]=Dolazni transfer datoteke + Comment[ca]=Transferència de fitxer entrant + Comment[cs]=Příchozí přenos souboru + Comment[de]=Eingehende Dateiübertragung ++Comment[el]=Μεταφορά εισερχόμενου αρχείου + Comment[en_GB]=Incoming file transfer + Comment[es]=Transferencia de archivo entrante ++Comment[et]=Sisenev failiedastus + Comment[fi]=Saapuva tiedostonsiirto + Comment[fr]=Transfert de fichier entrant + Comment[it]=Trasferimento di file in arrivo + Comment[nb]=Innkommende filoverføring + Comment[nl]=Inkomende bestandsoverdracht ++Comment[pa]=ਆ ਰਹੀ ਫਾਇਲ ਟਰਾਂਸਫਰ + Comment[pl]=Przychodzące przesyłanie pliku + Comment[pt]=Transferência de ficheiro recebida + Comment[pt_BR]=Transferência de arquivo recebida +@@ -300,7 +380,9 @@ Comment[sr@ijekavian]=Долазни пренос фајла + Comment[sr@ijekavianlatin]=Dolazni prenos fajla + Comment[sr@latin]=Dolazni prenos fajla + Comment[sv]=Inkommande filöverföring ++Comment[tr]=Gelen dosya aktarımı + Comment[uk]=Вхідне перенесення файла + Comment[x-test]=xxIncoming file transferxx + Comment[zh_CN]=收到文件传输 ++Comment[zh_TW]=進來的檔案傳輸 + Action=Popup +diff --git a/src/daemon/kded/BlueDevilDaemon.cpp b/src/daemon/kded/BlueDevilDaemon.cpp +index 1211103..458ce92 100644 +--- a/src/daemon/kded/BlueDevilDaemon.cpp ++++ b/src/daemon/kded/BlueDevilDaemon.cpp +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -64,7 +65,7 @@ struct BlueDevilDaemon::Private + Adapter *m_adapter; + QDBusServiceWatcher *m_monolithicWatcher; + FileReceiver *m_fileReceiver; +- QList m_discovered; ++ KSharedConfig::Ptr m_config; + QTimer m_timer; + }; + +@@ -81,8 +82,8 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList&) + d->m_fileReceiver = 0; + d->m_monolithicWatcher = new QDBusServiceWatcher(QStringLiteral("org.kde.bluedevilmonolithic") + , QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration, this); +- d->m_timer.setInterval(20000); + d->m_timer.setSingleShot(true); ++ d->m_config = KSharedConfig::openConfig("bluedevilglobalrc"); + + KAboutData aboutData( + QStringLiteral("bluedevildaemon"), +@@ -103,11 +104,27 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList&) + KAboutData::registerPluginData(aboutData); + + connect(d->m_monolithicWatcher, SIGNAL(serviceUnregistered(const QString &)), SLOT(monolithicFinished(const QString &))); ++ connect(&d->m_timer, SIGNAL(timeout()), SLOT(stopDiscovering())); + + connect(Manager::self(), SIGNAL(usableAdapterChanged(Adapter*)), + this, SLOT(usableAdapterChanged(Adapter*))); ++ connect(Manager::self(), SIGNAL(adapterAdded(Adapter*)), ++ this, SLOT(adapterAdded(Adapter*))); ++ connect(Manager::self(), SIGNAL(adapterRemoved(Adapter*)), ++ this, SLOT(adapterRemoved(Adapter*))); ++ ++ // Catch suspend/resume events ++ QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.login1"), ++ QStringLiteral("/org/freedesktop/login1"), ++ QStringLiteral("org.freedesktop.login1.Manager"), ++ QStringLiteral("PrepareForSleep"), ++ this, ++ SLOT(login1PrepareForSleep(bool)) ++ ); + + d->m_status = Private::Offline; ++ ++ restoreAdaptersState(); + usableAdapterChanged(Manager::self()->usableAdapter()); + + if (!Manager::self()->adapters().isEmpty()) { +@@ -117,6 +134,8 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList&) + + BlueDevilDaemon::~BlueDevilDaemon() + { ++ saveAdaptersState(); ++ + if (d->m_status == Private::Online) { + offlineMode(); + } +@@ -124,6 +143,27 @@ BlueDevilDaemon::~BlueDevilDaemon() + delete d; + } + ++static Adapter *adapterForAddress(const QString &address) ++{ ++ Q_FOREACH (Adapter *adapter, Manager::self()->adapters()) { ++ if (adapter->address() == address) { ++ return adapter; ++ } ++ } ++ return 0; ++} ++ ++void BlueDevilDaemon::login1PrepareForSleep(bool active) ++{ ++ if (active) { ++ qCDebug(BLUEDAEMON) << "About to suspend"; ++ saveAdaptersState(); ++ } else { ++ qCDebug(BLUEDAEMON) << "About to resume"; ++ restoreAdaptersState(); ++ } ++} ++ + bool BlueDevilDaemon::isOnline() + { + if (d->m_status == Private::Offline) { +@@ -132,41 +172,55 @@ bool BlueDevilDaemon::isOnline() + return true; + } + +-QMapDeviceInfo BlueDevilDaemon::knownDevices() ++QMapDeviceInfo BlueDevilDaemon::allDevices() + { + QMapDeviceInfo devices; ++ QList list = Manager::self()->usableAdapter()->devices(); + +- QList list = Manager::self()->usableAdapter()->devices(); +- qCDebug(BLUEDAEMON) << "List: " << list.length(); +- DeviceInfo info; +- Q_FOREACH(Device *const device, list) { +- info[QStringLiteral("name")] = device->friendlyName(); +- info[QStringLiteral("icon")] = device->icon(); +- info[QStringLiteral("address")] = device->address(); +- info[QStringLiteral("UUIDs")] = device->UUIDs().join(QStringLiteral(",")); +- devices[device->address()] = info; ++ Q_FOREACH (Device *const device, list) { ++ devices[device->address()] = deviceToInfo(device); + } + +- if (!d->m_timer.isActive()) { +- qCDebug(BLUEDAEMON) << "Start Discovery"; +- Manager::self()->usableAdapter()->startStableDiscovery(); +- d->m_discovered.clear(); +- d->m_timer.start(); +- } ++ return devices; ++} + +- Q_FOREACH(const DeviceInfo& info, d->m_discovered) { +- if (!devices.contains(info[QStringLiteral("address")])) { +- devices[info[QStringLiteral("address")]] = info; ++DeviceInfo BlueDevilDaemon::device(const QString &address) ++{ ++ Q_FOREACH (Device *const device, Manager::self()->devices()) { ++ if (device->address() == address) { ++ return deviceToInfo(device); + } + } +- return devices; ++ ++ return DeviceInfo(); ++} ++ ++void BlueDevilDaemon::startDiscovering(quint32 timeout) ++{ ++ if (!d->m_adapter) { ++ return; ++ } ++ ++ qCDebug(BLUEDAEMON) << "Start discovering for" << timeout << "ms"; ++ ++ d->m_adapter->startDiscovery(); ++ ++ if (timeout > 0) { ++ d->m_timer.start(timeout); ++ } + } + + void BlueDevilDaemon::stopDiscovering() + { +- qCDebug(BLUEDAEMON) << "Stopping discovering"; +- d->m_timer.stop(); +- Manager::self()->usableAdapter()->stopDiscovery(); ++ if (!d->m_adapter) { ++ return; ++ } ++ ++ qCDebug(BLUEDAEMON) << "Stop discovering"; ++ ++ if (d->m_adapter->isDiscovering()) { ++ d->m_adapter->stopDiscovery(); ++ } + } + + void BlueDevilDaemon::executeMonolithic() +@@ -203,9 +257,7 @@ void BlueDevilDaemon::onlineMode() + + d->m_bluezAgent = new BluezAgent(new QObject()); + connect(d->m_bluezAgent, SIGNAL(agentReleased()), this, SLOT(agentReleased())); +- + connect(d->m_adapter, SIGNAL(deviceFound(Device*)), this, SLOT(deviceFound(Device*))); +- connect(&d->m_timer, SIGNAL(timeout()), d->m_adapter, SLOT(stopDiscovery())); + + FileReceiverSettings::self()->load(); + if (!d->m_fileReceiver && FileReceiverSettings::self()->enabled()) { +@@ -271,9 +323,6 @@ void BlueDevilDaemon::offlineMode() + d->m_placesModel->removePlace(index); + } + +- if (BlueDevil::Manager::self()->adapters().isEmpty()) { +- killMonolithic(); +- } + d->m_status = Private::Offline; + } + +@@ -301,10 +350,23 @@ void BlueDevilDaemon::usableAdapterChanged(Adapter *adapter) + } + } + ++void BlueDevilDaemon::adapterAdded(Adapter *adapter) ++{ ++ restoreAdapterState(adapter); ++} ++ ++void BlueDevilDaemon::adapterRemoved(Adapter *adapter) ++{ ++ Q_UNUSED(adapter) ++ ++ if (BlueDevil::Manager::self()->adapters().isEmpty()) { ++ killMonolithic(); ++ } ++} ++ + void BlueDevilDaemon::deviceFound(Device *device) + { + qCDebug(BLUEDAEMON) << "DeviceFound: " << device->name(); +- d->m_discovered.append(deviceToInfo(device)); + org::kde::KDirNotify::emitFilesAdded(QUrl(QStringLiteral("bluetooth:/"))); + } + +@@ -314,18 +376,59 @@ void BlueDevilDaemon::monolithicQuit(QDBusPendingCallWatcher* watcher) + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + qDebug() << "Error response: " << reply.error().message(); +- killMonolithic(); + } + } + ++void BlueDevilDaemon::saveAdaptersState() ++{ ++ Manager *manager = Manager::self(); ++ if (!manager) { ++ return; ++ } ++ ++ KConfigGroup adaptersGroup = d->m_config->group("Adapters"); ++ ++ Q_FOREACH (Adapter *adapter, manager->adapters()) { ++ const QString key = QString("%1_powered").arg(adapter->address()); ++ adaptersGroup.writeEntry(key, adapter->isPowered()); ++ } ++ ++ d->m_config->sync(); ++} ++ ++// New adapters are automatically powered on ++void BlueDevilDaemon::restoreAdaptersState() ++{ ++ Manager *manager = Manager::self(); ++ if (!manager) { ++ return; ++ } ++ ++ KConfigGroup adaptersGroup = d->m_config->group("Adapters"); ++ ++ Q_FOREACH (Adapter *adapter, manager->adapters()) { ++ const QString key = QString("%1_powered").arg(adapter->address()); ++ adapter->setPowered(adaptersGroup.readEntry(key, true)); ++ } ++} ++ ++void BlueDevilDaemon::restoreAdapterState(Adapter *adapter) ++{ ++ KConfigGroup adaptersGroup = d->m_config->group("Adapters"); ++ ++ const QString key = QString("%1_powered").arg(adapter->address()); ++ adapter->setPowered(adaptersGroup.readEntry(key, true)); ++} ++ + DeviceInfo BlueDevilDaemon::deviceToInfo(Device *const device) const + { + DeviceInfo info; ++ + info[QStringLiteral("name")] = device->friendlyName(); + info[QStringLiteral("icon")] = device->icon(); + info[QStringLiteral("address")] = device->address(); +- info[QStringLiteral("discovered")] = QStringLiteral("true"); +- info[QStringLiteral("UUIDs")] = device->UUIDs().join(QStringLiteral(",")); ++ info[QStringLiteral("UBI")] = device->UBI(); ++ info[QStringLiteral("UUIDs")] = device->UUIDs().join(QLatin1Char(',')); + + return info; + } +diff --git a/src/daemon/kded/BlueDevilDaemon.h b/src/daemon/kded/BlueDevilDaemon.h +index a8688ae..5115f1b 100644 +--- a/src/daemon/kded/BlueDevilDaemon.h ++++ b/src/daemon/kded/BlueDevilDaemon.h +@@ -49,16 +49,30 @@ public: + virtual ~BlueDevilDaemon(); + + public Q_SLOTS: ++ /** ++ * Returns whether the daemon is in online mode (eg. Bluez services are ++ * running and we have usable adapter) ++ */ + Q_SCRIPTABLE bool isOnline(); + + /** +- * This slot will return a list of devices made of: configured and discovered devices. +- * Going deeper, the first time that this slot is called a discovery of X seconds will start +- * Then if this slot is consulted again it will return configured and discovered device. Once +- * the discovery ends it won't start a new discovery until N seconds pass. ++ * Returns QMap with all known devices + */ +- Q_SCRIPTABLE QMapDeviceInfo knownDevices(); ++ Q_SCRIPTABLE QMapDeviceInfo allDevices(); + ++ /** ++ * Returns DeviceInfo for one device. ++ */ ++ Q_SCRIPTABLE DeviceInfo device(const QString &address); ++ ++ /** ++ * Starts discovery for timeout miliseconds (0 = forever) ++ */ ++ Q_SCRIPTABLE void startDiscovering(quint32 timeout); ++ ++ /** ++ * Stops discovery (if it was previously started) ++ */ + Q_SCRIPTABLE void stopDiscovering(); + + private: +@@ -81,11 +95,16 @@ private Q_SLOTS: + */ + void usableAdapterChanged(Adapter *adapter); + ++ void adapterAdded(Adapter *adapter); ++ void adapterRemoved(Adapter *adapter); ++ + /** + * When the agent is released this is called to unload it + */ + void agentReleased(); + ++ void login1PrepareForSleep(bool active); ++ + void deviceFound(Device*); + void monolithicQuit(QDBusPendingCallWatcher* watcher); + void monolithicFinished(const QString &); +@@ -94,7 +113,11 @@ private: + void executeMonolithic(); + void killMonolithic(); + +- DeviceInfo deviceToInfo (Device *const device) const; ++ void saveAdaptersState(); ++ void restoreAdaptersState(); ++ void restoreAdapterState(Adapter *adapter); ++ ++ DeviceInfo deviceToInfo(Device *const device) const; + + private: + struct Private; +diff --git a/src/daemon/kded/CMakeLists.txt b/src/daemon/kded/CMakeLists.txt +index 3a8ddb7..651e68d 100644 +--- a/src/daemon/kded/CMakeLists.txt ++++ b/src/daemon/kded/CMakeLists.txt +@@ -26,7 +26,7 @@ kconfig_add_kcfg_files(kded_bluedevil_SRCS ../../settings/filereceiversettings.k + + add_library(kded_bluedevil MODULE ${kded_bluedevil_SRCS}) + +-kservice_desktop_to_json(kded_bluedevil bluedevil.desktop) ++kcoreaddons_desktop_to_json(kded_bluedevil bluedevil.desktop) + + target_link_libraries(kded_bluedevil + Qt5::Gui +diff --git a/src/daemon/kded/bluedevil.desktop b/src/daemon/kded/bluedevil.desktop +index 6799d91..b65cc5a 100644 +--- a/src/daemon/kded/bluedevil.desktop ++++ b/src/daemon/kded/bluedevil.desktop +@@ -9,16 +9,25 @@ X-KDE-Kded-load-on-demand=false + X-KDE-Kded-phase=1 + + Name=Bluetooth ++Name[bs]=Blutut + Name[ca]=Bluetooth + Name[cs]=Bluetooth + Name[de]=Bluetooth ++Name[el]=Bluetooth + Name[en_GB]=Bluetooth + Name[es]=Bluetooth ++Name[et]=Bluetooth + Name[fi]=Bluetooth + Name[fr]=Bluetooth + Name[it]=Bluetooth ++Name[ja]=Bluetooth ++Name[kk]=Bluetooth ++Name[ko]=블루투스 ++Name[lt]=Bluetooth ++Name[mr]=ब्लूटूथ + Name[nb]=Blåtann + Name[nl]=Bluetooth ++Name[pa]=ਬਲਿਊਟੁੱਥ + Name[pl]=Bluetooth + Name[pt]=Bluetooth + Name[pt_BR]=Bluetooth +@@ -29,21 +38,27 @@ Name[sr@ijekavian]=Блутут + Name[sr@ijekavianlatin]=Bluetooth + Name[sr@latin]=Bluetooth + Name[sv]=Blåtand ++Name[tr]=Bluetooth + Name[uk]=Bluetooth + Name[x-test]=xxBluetoothxx + Name[zh_CN]=蓝牙 ++Name[zh_TW]=藍牙 + + Comment=Handles Bluetooth events ++Comment[bs]=Obrađuje Bluetooth događaje + Comment[ca]=Gestiona els esdeveniments del Bluetooth + Comment[cs]=Ovládá události Bluetooth + Comment[de]=Verarbeitung von Bluetooth-Ereignissen ++Comment[el]=Χειρίζεται γεγονότα Bluetooth + Comment[en_GB]=Handles Bluetooth events +-Comment[es]=Gestiona los eventos de Bluetooth ++Comment[es]=Maneja eventos de Bluetooth ++Comment[et]=Bluetoothi sündmuste käitlemine + Comment[fi]=Käsittelee Bluetooth-tapahtumia + Comment[fr]=Gère les évènements Bluetooth + Comment[it]=Gestisce eventi Bluetooth + Comment[nb]=Håndterer Blåtann-hendelser + Comment[nl]=Behandelt bluetooth-gebeurtenissen ++Comment[pa]=ਬਲਿਊਟੁੱਥ ਘਟਨਾਵਾਂ ਕੰਟਰੋਲ ਕਰਨ ਲਈ + Comment[pl]=Obsługa zdarzeń Bluetooth + Comment[pt]=Lida com os eventos de Bluetooth + Comment[pt_BR]=Lida com os eventos de Bluetooth +@@ -54,6 +69,8 @@ Comment[sr@ijekavian]=Рукује блутут догађајима + Comment[sr@ijekavianlatin]=Rukuje bluetooth događajima + Comment[sr@latin]=Rukuje bluetooth događajima + Comment[sv]=Hanterar Blåtandhändelser ++Comment[tr]=Bluetooth olaylarını ele alır + Comment[uk]=Обробляє події Bluetooth + Comment[x-test]=xxHandles Bluetooth eventsxx + Comment[zh_CN]=处理蓝牙事件 ++Comment[zh_TW]=處理藍牙事件 +diff --git a/src/daemon/kded/filereceiver/filereceiver.cpp b/src/daemon/kded/filereceiver/filereceiver.cpp +index 00405b1..1c8570c 100644 +--- a/src/daemon/kded/filereceiver/filereceiver.cpp ++++ b/src/daemon/kded/filereceiver/filereceiver.cpp +@@ -19,11 +19,11 @@ + #include "filereceiver.h" + #include "../BlueDevilDaemon.h" + #include "obexagent.h" +-#include "obex_agent_manager.h" + + #include + #include + #include ++#include + + FileReceiver::FileReceiver(QObject* parent) + : QObject(parent) +@@ -32,14 +32,17 @@ FileReceiver::FileReceiver(QObject* parent) + qDBusRegisterMetaType(); + + new ObexAgent(this); +- org::bluez::obex::AgentManager1 *agent = new org::bluez::obex::AgentManager1(QStringLiteral("org.bluez.obex"), +- QStringLiteral("/org/bluez/obex"), +- QDBusConnection::sessionBus(), +- this); ++ m_agentManager = new org::bluez::obex::AgentManager1(QStringLiteral("org.bluez.obex"), ++ QStringLiteral("/org/bluez/obex"), ++ QDBusConnection::sessionBus(), ++ this); + +- QDBusPendingReply r = agent->RegisterAgent(QDBusObjectPath(QStringLiteral("/BlueDevil_receiveAgent"))); +- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(r, this); +- connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(agentRegistered(QDBusPendingCallWatcher*))); ++ registerAgent(); ++ ++ // obexd should be set to auto-start by D-Bus (D-Bus activation), so this should restart it in case of crash ++ QDBusServiceWatcher *serviceWatcher = new QDBusServiceWatcher(QStringLiteral("org.bluez.obex"), QDBusConnection::sessionBus(), ++ QDBusServiceWatcher::WatchForUnregistration, this); ++ connect(serviceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(registerAgent())); + } + + FileReceiver::~FileReceiver() +@@ -47,6 +50,13 @@ FileReceiver::~FileReceiver() + + } + ++void FileReceiver::registerAgent() ++{ ++ QDBusPendingReply r = m_agentManager->RegisterAgent(QDBusObjectPath(QStringLiteral("/BlueDevil_receiveAgent"))); ++ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(r, this); ++ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(agentRegistered(QDBusPendingCallWatcher*))); ++} ++ + void FileReceiver::agentRegistered(QDBusPendingCallWatcher* call) + { + QDBusPendingReply r = *call; +diff --git a/src/daemon/kded/filereceiver/filereceiver.h b/src/daemon/kded/filereceiver/filereceiver.h +index e6dc6fb..dbfa94b 100644 +--- a/src/daemon/kded/filereceiver/filereceiver.h ++++ b/src/daemon/kded/filereceiver/filereceiver.h +@@ -21,6 +21,8 @@ + + #include + ++#include "obex_agent_manager.h" ++ + class QDBusPendingCallWatcher; + class FileReceiver : public QObject + { +@@ -30,7 +32,11 @@ class FileReceiver : public QObject + virtual ~FileReceiver(); + + private Q_SLOTS: ++ void registerAgent(); + void agentRegistered(QDBusPendingCallWatcher* call); ++ ++ private: ++ org::bluez::obex::AgentManager1 *m_agentManager; + }; + + #endif //FILE_RECEIVER_H +diff --git a/src/daemon/kded/filereceiver/receivefilejob.cpp b/src/daemon/kded/filereceiver/receivefilejob.cpp +index 5b9a8f4..a3e6190 100644 +--- a/src/daemon/kded/filereceiver/receivefilejob.cpp ++++ b/src/daemon/kded/filereceiver/receivefilejob.cpp +@@ -95,18 +95,29 @@ void ReceiveFileJob::init() + this); + qCDebug(BLUEDAEMON) << m_session->destination(); + +- Device* device = Manager::self()->usableAdapter()->deviceForAddress(m_session->destination()); ++ Device *device = 0; ++ bool isDeviceTrusted = false; ++ ++ Q_FOREACH (Adapter *adapter, Manager::self()->adapters()) { ++ if (adapter->address() == m_session->source()) { ++ device = adapter->deviceForAddress(m_session->destination()); ++ break; ++ } ++ } ++ + qCDebug(BLUEDAEMON) << device; + + m_deviceName = m_session->destination(); ++ + if (device) { + qCDebug(BLUEDAEMON) << device->name(); + m_deviceName = device->name(); ++ isDeviceTrusted = device->isTrusted(); + } + + FileReceiverSettings::self()->load(); + qCDebug(BLUEDAEMON) << "Auto Accept: " << FileReceiverSettings::self()->autoAccept(); +- if (FileReceiverSettings::self()->autoAccept() == 1 && device->isTrusted()) { ++ if (FileReceiverSettings::self()->autoAccept() == 1 && isDeviceTrusted) { + slotAccept(); + return; + } else if (FileReceiverSettings::self()->autoAccept() == 2) { +diff --git a/src/fileitemactionplugin/CMakeLists.txt b/src/fileitemactionplugin/CMakeLists.txt +index 3737c68..39d6e33 100644 +--- a/src/fileitemactionplugin/CMakeLists.txt ++++ b/src/fileitemactionplugin/CMakeLists.txt +@@ -1,9 +1,17 @@ +-add_library(bluetoothfileitemaction MODULE sendfileitemaction.cpp) +-kservice_desktop_to_json(bluetoothfileitemaction bluedevilsendfile.desktop) ++set(fileitemactionplugin_SRCS ++ sendfileitemaction.cpp) ++ ++set(kded_bluedevil.xml ${CMAKE_CURRENT_SOURCE_DIR}/kded_bluedevil.xml) ++set_source_files_properties(${kded_bluedevil.xml} PROPERTIES INCLUDE "types.h") ++qt5_add_dbus_interface(fileitemactionplugin_SRCS ${kded_bluedevil.xml} kded_bluedevil) ++ ++add_library(bluetoothfileitemaction MODULE ${fileitemactionplugin_SRCS}) ++kcoreaddons_desktop_to_json(bluetoothfileitemaction bluedevilsendfile.desktop) + target_link_libraries(bluetoothfileitemaction + Qt5::Widgets + KF5::I18n + KF5::KIOFileWidgets + ${LibBlueDevil_LIBRARIES}) ++ + install(TARGETS bluetoothfileitemaction DESTINATION ${PLUGIN_INSTALL_DIR}) + install(FILES bluedevilsendfile.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +diff --git a/src/fileitemactionplugin/bluedevilsendfile.desktop b/src/fileitemactionplugin/bluedevilsendfile.desktop +index 1896d55..4ce580d 100644 +--- a/src/fileitemactionplugin/bluedevilsendfile.desktop ++++ b/src/fileitemactionplugin/bluedevilsendfile.desktop +@@ -1,16 +1,26 @@ + [Desktop Entry] + Type=Service + Name=Send file via Bluetooth ++Name[bs]=Šalji datoteku preko Bluetoots + Name[ca]=Envia un fitxer per Bluetooth + Name[cs]=Poslat soubor přes Bluetooth + Name[de]=Datei über Bluetooth versenden ++Name[el]=Αποστολή αρχείου μέσω Bluetooth + Name[en_GB]=Send file via Bluetooth +-Name[es]=Enviar archivo usando Bluetooth ++Name[es]=Enviar archivo por Bluetooth ++Name[et]=Faili saatmine Bluetoothi kaudu + Name[fi]=Lähetä tiedosto Bluetoothin kautta + Name[fr]=Envoi de fichiers via Bluetooth + Name[it]=Invia file via Bluetooth ++Name[ja]=Bluetooth を通してファイルを送信 ++Name[kk]=Bluetooth арқылы файлды жіберу ++Name[km]=ផ្ញើ​ឯកសារ​តាម​ប៊្លូធូស ++Name[ko]=블루투스로 파일 보내기 ++Name[lt]=Siųsti per Bluetooth ++Name[mr]=ब्लूटूथ द्वारे फाईल पाठवा + Name[nb]=Send fil over Blåtann + Name[nl]=Verzendt bestand over bluetooth ++Name[pa]=ਫਾਇਲ ਨੂੰ ਬਲਿਊਟੁੱਥ ਰਾਹੀਂ ਭੇਜੋ + Name[pl]=Wyślij plik przez Bluetooth + Name[pt]=Enviar o ficheiro por Bluetooth + Name[pt_BR]=Enviar arquivo por Bluetooth +@@ -21,21 +31,32 @@ Name[sr@ijekavian]=Слање фајлова преко блутута + Name[sr@ijekavianlatin]=Slanje fajlova preko Bluetootha + Name[sr@latin]=Slanje fajlova preko Bluetootha + Name[sv]=Skicka fil via Blåtand ++Name[tr]=Bluetooth üzerinden dosya gönder + Name[uk]=Надіслати файл за допомогою Bluetooth + Name[x-test]=xxSend file via Bluetoothxx + Name[zh_CN]=通过蓝牙发送文件 ++Name[zh_TW]=透過藍牙傳送檔案 + X-KDE-Library=bluetoothfileitemaction + X-KDE-Submenu=Bluetooth ++X-KDE-Submenu[bs]=Blutut + X-KDE-Submenu[ca]=Bluetooth + X-KDE-Submenu[cs]=Bluetooth + X-KDE-Submenu[de]=Bluetooth ++X-KDE-Submenu[el]=Bluetooth + X-KDE-Submenu[en_GB]=Bluetooth + X-KDE-Submenu[es]=Bluetooth + X-KDE-Submenu[fi]=Bluetooth + X-KDE-Submenu[fr]=Bluetooth + X-KDE-Submenu[it]=Bluetooth ++X-KDE-Submenu[ja]=Bluetooth ++X-KDE-Submenu[kk]=Bluetooth ++X-KDE-Submenu[km]=ប៊្លូធូស ++X-KDE-Submenu[ko]=블루투스 ++X-KDE-Submenu[lt]=Bluetooth ++X-KDE-Submenu[mr]=ब्लूटूथ + X-KDE-Submenu[nb]=Blåtann + X-KDE-Submenu[nl]=Bluetooth ++X-KDE-Submenu[pa]=ਬਲਿਊਟੁੱਥ + X-KDE-Submenu[pl]=Bluetooth + X-KDE-Submenu[pt]=Bluetooth + X-KDE-Submenu[pt_BR]=Bluetooth +@@ -46,9 +67,11 @@ X-KDE-Submenu[sr@ijekavian]=Блутут + X-KDE-Submenu[sr@ijekavianlatin]=Bluetooth + X-KDE-Submenu[sr@latin]=Bluetooth + X-KDE-Submenu[sv]=Blåtand ++X-KDE-Submenu[tr]=Bluetooth + X-KDE-Submenu[uk]=Bluetooth + X-KDE-Submenu[x-test]=xxBluetoothxx + X-KDE-Submenu[zh_CN]=蓝牙 ++X-KDE-Submenu[zh_TW]=藍牙 + Icon=preferences-system-bluetooth + ServiceTypes=KFileItemAction/Plugin + MimeType=application/octet-stream; +diff --git a/src/fileitemactionplugin/kded_bluedevil.xml b/src/fileitemactionplugin/kded_bluedevil.xml +new file mode 100644 +index 0000000..e447897 +--- /dev/null ++++ b/src/fileitemactionplugin/kded_bluedevil.xml +@@ -0,0 +1,23 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/fileitemactionplugin/sendfileitemaction.cpp b/src/fileitemactionplugin/sendfileitemaction.cpp +index c750bc4..b240470 100644 +--- a/src/fileitemactionplugin/sendfileitemaction.cpp ++++ b/src/fileitemactionplugin/sendfileitemaction.cpp +@@ -33,10 +33,6 @@ + #include + #include + +-#include +- +-using namespace BlueDevil; +- + K_PLUGIN_FACTORY_WITH_JSON(SendFileItemActionFactory, + "bluedevilsendfile.json", + registerPlugin();) +@@ -45,34 +41,37 @@ SendFileItemAction::SendFileItemAction(QObject* parent, const QVariantList& args + : KAbstractFileItemActionPlugin(parent) + { + Q_UNUSED(args) ++ ++ qDBusRegisterMetaType(); ++ qDBusRegisterMetaType(); ++ ++ m_kded = new org::kde::BlueDevil(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/bluedevil"), ++ QDBusConnection::sessionBus(), this); + } + + QList< QAction* > SendFileItemAction::actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) + { + Q_UNUSED(parentWidget) +- QList< QAction* > list; + +- m_fileItemInfos = fileItemInfos; ++ QList list; + +- //If there is no adaptor, there is no bluetooth +- if (!Manager::self()->usableAdapter()) { ++ // Don't show the action for files that we can't send or when Bluetooth is offline. ++ if (!fileItemInfos.isLocal() || !m_kded->isOnline()) { + return list; + } +- Adapter *adapter = Manager::self()->usableAdapter(); ++ ++ m_fileItemInfos = fileItemInfos; + + QAction *menuAction = new QAction(QIcon::fromTheme(QStringLiteral("preferences-system-bluetooth")), i18n("Send via Bluetooth"), this); + QMenu *menu = new QMenu(); + +- //If we have configured devices, put them first +- QList< Device * > devices = adapter->devices(); +- if (!devices.isEmpty()) { +- Q_FOREACH(Device *device, devices) { +- if (device->UUIDs().contains(QLatin1String("00001105-0000-1000-8000-00805F9B34FB"), Qt::CaseInsensitive)) { +- QAction *action = new QAction(QIcon::fromTheme(device->icon()), device->name(), this); +- connect(action, SIGNAL(triggered(bool)), this, SLOT(deviceTriggered())); +- action->setData(device->UBI()); +- menu->addAction(action); +- } ++ const QMapDeviceInfo &devices = m_kded->allDevices().value(); ++ Q_FOREACH (const DeviceInfo &device, devices) { ++ if (device[QStringLiteral("UUIDs")].contains(QLatin1String("00001105-0000-1000-8000-00805F9B34FB"))) { ++ QAction *action = new QAction(QIcon::fromTheme(device[QStringLiteral("icon")]), device[QStringLiteral("name")], this); ++ connect(action, SIGNAL(triggered(bool)), this, SLOT(deviceTriggered())); ++ action->setData(device["UBI"]); ++ menu->addAction(action); + } + } + +diff --git a/src/fileitemactionplugin/sendfileitemaction.h b/src/fileitemactionplugin/sendfileitemaction.h +index f9eecc3..389fb64 100644 +--- a/src/fileitemactionplugin/sendfileitemaction.h ++++ b/src/fileitemactionplugin/sendfileitemaction.h +@@ -24,12 +24,14 @@ + #include + #include + ++#include "kded_bluedevil.h" ++ + class QAction; + class QWidget; + + class SendFileItemAction : public KAbstractFileItemActionPlugin + { +-Q_OBJECT ++ Q_OBJECT + public: + SendFileItemAction(QObject* parent, const QVariantList &args); + virtual QList< QAction* > actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget); +@@ -39,6 +41,7 @@ private Q_SLOTS: + void otherTriggered(); + + private: ++ org::kde::BlueDevil *m_kded; + KFileItemListProperties m_fileItemInfos; + }; + +diff --git a/src/fileitemactionplugin/types.h b/src/fileitemactionplugin/types.h +new file mode 100644 +index 0000000..53f2e4a +--- /dev/null ++++ b/src/fileitemactionplugin/types.h +@@ -0,0 +1,11 @@ ++#ifndef FILEITEMACTIONPLUGINTYPES ++#define FILEITEMACTIONPLUGINTYPES ++ ++#include ++ ++typedef QMap DeviceInfo; ++typedef QMap QMapDeviceInfo; ++Q_DECLARE_METATYPE(DeviceInfo) ++Q_DECLARE_METATYPE(QMapDeviceInfo) ++ ++#endif +diff --git a/src/kcmodule/CMakeLists.txt b/src/kcmodule/CMakeLists.txt +index 64e6050..4145c1b 100644 +--- a/src/kcmodule/CMakeLists.txt ++++ b/src/kcmodule/CMakeLists.txt +@@ -24,9 +24,9 @@ add_library(kcm_bluedevildevices MODULE ${kcm_bluedevildevices_PART_SRCS}) + add_library(kcm_bluedeviladapters MODULE ${kcm_bluedeviladapters_PART_SRCS}) + add_library(kcm_bluedeviltransfer MODULE ${kcm_bluedeviltransfer_PART_SRCS} ${kcm_bluedeviltransfer_PART_SRCS_UI}) + +-kservice_desktop_to_json(kcm_bluedevildevices bluedevildevices.desktop) +-kservice_desktop_to_json(kcm_bluedeviladapters bluedeviladapters.desktop) +-kservice_desktop_to_json(kcm_bluedeviltransfer bluedeviltransfer.desktop) ++kcoreaddons_desktop_to_json(kcm_bluedevildevices bluedevildevices.desktop) ++kcoreaddons_desktop_to_json(kcm_bluedeviladapters bluedeviladapters.desktop) ++kcoreaddons_desktop_to_json(kcm_bluedeviltransfer bluedeviltransfer.desktop) + + target_link_libraries(kcm_bluedevildevices + Qt5::Widgets +diff --git a/src/kcmodule/bluedeviladapters.cpp b/src/kcmodule/bluedeviladapters.cpp +index 9185552..64dfce2 100644 +--- a/src/kcmodule/bluedeviladapters.cpp ++++ b/src/kcmodule/bluedeviladapters.cpp +@@ -62,8 +62,8 @@ AdapterSettings::AdapterSettings(Adapter *adapter, KCModule *parent) + buttonGroup->addButton(m_alwaysVisible); + buttonGroup->addButton(m_temporaryVisible); + +- m_name->setText(adapter->alias()); +- m_nameOrig = adapter->alias(); ++ m_name->setText(adapter->name()); ++ m_nameOrig = adapter->name(); + m_hiddenOrig = false; + m_alwaysVisibleOrig = false; + m_temporaryVisibleOrig = false; +@@ -119,9 +119,9 @@ AdapterSettings::AdapterSettings(Adapter *adapter, KCModule *parent) + connect(m_powered, SIGNAL(stateChanged(int)), this, SLOT(slotSettingsChanged())); + + if (BlueDevil::Manager::self()->usableAdapter() == adapter) { +- setTitle(i18n("Default adapter: %1 (%2)", adapter->alias(), adapter->address())); ++ setTitle(i18n("Default adapter: %1 (%2)", adapter->name(), adapter->address())); + } else { +- setTitle(i18n("Adapter: %1 (%2)", adapter->alias(), adapter->address())); ++ setTitle(i18n("Adapter: %1 (%2)", adapter->name(), adapter->address())); + } + } + +@@ -188,7 +188,7 @@ void AdapterSettings::readChanges() + { + blockSignals(true); + +- m_nameOrig = m_adapter->alias(); ++ m_nameOrig = m_adapter->name(); + m_hiddenOrig = !m_adapter->isDiscoverable(); + m_alwaysVisibleOrig = m_adapter->isDiscoverable() && !m_adapter->discoverableTimeout(); + m_temporaryVisibleOrig = m_adapter->isDiscoverable() && m_adapter->discoverableTimeout(); +@@ -204,9 +204,9 @@ void AdapterSettings::readChanges() + + m_discoverTimeLabel->setText(i18np("1 minute", "%1 minutes", m_discoverTime->value())); + if (BlueDevil::Manager::self()->usableAdapter() == m_adapter) { +- setTitle(i18n("Default adapter: %1 (%2)", m_adapter->alias(), m_adapter->address())); ++ setTitle(i18n("Default adapter: %1 (%2)", m_adapter->name(), m_adapter->address())); + } else { +- setTitle(i18n("Adapter: %1 (%2)", m_adapter->alias(), m_adapter->address())); ++ setTitle(i18n("Adapter: %1 (%2)", m_adapter->name(), m_adapter->address())); + } + + blockSignals(false); +diff --git a/src/kcmodule/bluedeviladapters.desktop b/src/kcmodule/bluedeviladapters.desktop +index f1f5e50..7a32916 100644 +--- a/src/kcmodule/bluedeviladapters.desktop ++++ b/src/kcmodule/bluedeviladapters.desktop +@@ -12,16 +12,25 @@ X-KDE-System-Settings-Parent-Category=bluetooth + X-KDE-Weight=100 + + Name=Adapters ++Name[bs]=Adapteri + Name[ca]=Adaptadors + Name[cs]=Adaptéry + Name[de]=Adapter ++Name[el]=Προσαρμογείς + Name[en_GB]=Adapters + Name[es]=Adaptadores + Name[fi]=Sovittimet + Name[fr]=Adaptateurs + Name[it]=Adattatori ++Name[ja]=アダプタ ++Name[kk]=Адаптерлері ++Name[km]=អាដាប់ទ័រ ++Name[ko]=어댑터 ++Name[lt]=Adapteriai ++Name[mr]=एडाप्टर्स + Name[nb]=Adaptere + Name[nl]=Adapters ++Name[pa]=ਅਡੈਪਟਰ + Name[pl]=Adaptery + Name[pt]=Adaptadores + Name[pt_BR]=Adaptadores +@@ -32,21 +41,27 @@ Name[sr@ijekavian]=Адаптери + Name[sr@ijekavianlatin]=Adapteri + Name[sr@latin]=Adapteri + Name[sv]=Anslutningar ++Name[tr]=Bağdaştırıcılar + Name[uk]=Адаптери + Name[x-test]=xxAdaptersxx + Name[zh_CN]=适配器 ++Name[zh_TW]=轉接器 + + Comment=Configure Bluetooth adapters ++Comment[bs]=Konfigurisanje Blutut adaptera + Comment[ca]=Configura els adaptadors Bluetooth + Comment[cs]=Nastavte adaptéry Bluetooth + Comment[de]=Bluetooth-Adapter einrichten ++Comment[el]=Διαμόρφωση προσαρμογέων Bluetooth + Comment[en_GB]=Configure Bluetooth adapters + Comment[es]=Configurar adaptadores Bluetooth ++Comment[et]=Bluetoothi adapterite seadistamine + Comment[fi]=Bluetooth-sovittimien asetukset + Comment[fr]=Configure les adaptateurs Bluetooth + Comment[it]=Configura gli adattatori Bluetooth + Comment[nb]=Sett opp Blåtann-adaptere + Comment[nl]=Bluetooth-adapters instellen ++Comment[pa]=ਬਲਿਊਟੁੱਥ ਐਡਪਟਰ ਸੰਰਚਨਾ + Comment[pl]=Ustawienia adapterów Bluetooth + Comment[pt]=Configurar os adaptadores de Bluetooth + Comment[pt_BR]=Configura os adaptadores Bluetooth +@@ -57,14 +72,18 @@ Comment[sr@ijekavian]=Подесите блутут адаптере + Comment[sr@ijekavianlatin]=Podesite bluetooth adaptere + Comment[sr@latin]=Podesite bluetooth adaptere + Comment[sv]=Anpassa Blåtandanslutningar ++Comment[tr]=Bluetooth bağdaştırıcılarını yapılandır + Comment[uk]=Налаштування адаптерів Bluetooth + Comment[x-test]=xxConfigure Bluetooth adaptersxx + Comment[zh_CN]=配置蓝牙适配器 ++Comment[zh_TW]=設定藍牙轉接器 + + X-KDE-Keywords=Network,Connectivity,Bluetooth ++X-KDE-Keywords[bs]=Network,Connectivity,Bluetooth + X-KDE-Keywords[ca]=Xarxa,Connectivitat,Bluetooth + X-KDE-Keywords[cs]=Síť,Konektivita,Bluetooth + X-KDE-Keywords[de]=Netzwerk,Verbindungen,Bluetooth ++X-KDE-Keywords[el]=Δίκτυο,Συνδεσιμότητα,Bluetooth + X-KDE-Keywords[en_GB]=Network,Connectivity,Bluetooth + X-KDE-Keywords[es]=Red,Conectividad,Bluetooth + X-KDE-Keywords[fi]=Verkko,Yhteydet,Bluetooth +@@ -72,6 +91,7 @@ X-KDE-Keywords[fr]=Réseau, connectivité, Bluetooth + X-KDE-Keywords[it]=Rete,Connettività,Bluetooth + X-KDE-Keywords[nb]=Nettverk,sammenkobling,blåtann + X-KDE-Keywords[nl]=Netwerkverbinding,connectiviteit,bluetooth ++X-KDE-Keywords[pa]=ਨੈਟਵਰਕ,ਕਨੈਕਟਵਿਟੀ,ਬਲਿਊਟੁੱਥ + X-KDE-Keywords[pl]=Sieć,Łączność,Bluetooth + X-KDE-Keywords[pt]=Rede,Conectividade,Bluetooth + X-KDE-Keywords[pt_BR]=Rede,Conectividade,Bluetooth +@@ -82,8 +102,10 @@ X-KDE-Keywords[sr@ijekavian]=Network,Connectivity,Bluetooth,мрежа,пове + X-KDE-Keywords[sr@ijekavianlatin]=Network,Connectivity,Bluetooth,mreža,povezivanje,Bluetooth + X-KDE-Keywords[sr@latin]=Network,Connectivity,Bluetooth,mreža,povezivanje,Bluetooth + X-KDE-Keywords[sv]=Nätverk,Anslutningar,Blåtand ++X-KDE-Keywords[tr]=Ağ, Bağlanılabilirlik, Bluetooth + X-KDE-Keywords[uk]=Network,Connectivity,Bluetooth,мережа,з’єднання,з'єднання + X-KDE-Keywords[x-test]=xxNetworkxx,xxConnectivityxx,xxBluetoothxx + X-KDE-Keywords[zh_CN]=Network,Connectivity,Bluetooth,网络,连接,蓝牙 ++X-KDE-Keywords[zh_TW]=Network,Connectivity,Bluetooth + + Categories=Qt;KDE;X-KDE-settings-bluetooth; +diff --git a/src/kcmodule/bluedevildevices.cpp b/src/kcmodule/bluedevildevices.cpp +index 1135d6f..50a92d0 100644 +--- a/src/kcmodule/bluedevildevices.cpp ++++ b/src/kcmodule/bluedevildevices.cpp +@@ -518,7 +518,11 @@ void KCMBlueDevilDevices::usableAdapterChanged(Adapter *adapter) + if (adapter) { + connect(adapter, SIGNAL(discoverableChanged(bool)), + this, SLOT(adapterDiscoverableChanged())); +- connect(adapter, SIGNAL(devicesChanged(QList)), ++ connect(adapter, SIGNAL(deviceChanged(Device*)), ++ this, SLOT(adapterDevicesChanged())); ++ connect(adapter, SIGNAL(deviceRemoved(Device*)), ++ this, SLOT(adapterDevicesChanged())); ++ connect(adapter, SIGNAL(deviceFound(Device*)), + this, SLOT(adapterDevicesChanged())); + } + fillRemoteDevicesModelInformation(); +diff --git a/src/kcmodule/bluedevildevices.desktop b/src/kcmodule/bluedevildevices.desktop +index ecf6b45..38b83f9 100644 +--- a/src/kcmodule/bluedevildevices.desktop ++++ b/src/kcmodule/bluedevildevices.desktop +@@ -12,16 +12,27 @@ X-KDE-System-Settings-Parent-Category=bluetooth + X-KDE-Weight=50 + + Name=Devices ++Name[bs]=uređaji + Name[ca]=Dispositius + Name[cs]=Zařízení + Name[de]=Geräte ++Name[el]=Συσκευές + Name[en_GB]=Devices + Name[es]=Dispositivos + Name[fi]=Laitteet + Name[fr]=Périphériques + Name[it]=Dispositivi ++Name[ja]=デバイス ++Name[kk]=Құрылғылар ++Name[km]=ឧបករណ៍​ ++Name[ko]=장치 ++Name[lt]=Įrenginiai ++Name[mai]=डिवाइस ++Name[mr]=साधने ++Name[ms]=Peranti + Name[nb]=Enheter + Name[nl]=Apparaten ++Name[pa]=ਯੰਤਰ + Name[pl]=Urządzenia + Name[pt]=Dispositivos + Name[pt_BR]=Dispositivos +@@ -32,19 +43,29 @@ Name[sr@ijekavian]=Уређаји + Name[sr@ijekavianlatin]=Uređaji + Name[sr@latin]=Uređaji + Name[sv]=Enheter ++Name[tr]=Aygıtlar + Name[uk]=Пристрої + Name[x-test]=xxDevicesxx + Name[zh_CN]=设备 ++Name[zh_TW]=裝置 + + Comment=Manage Bluetooth devices ++Comment[bs]=Upravljanje Blutut uređaje + Comment[ca]=Gestiona els dispositius Bluetooth + Comment[cs]=Spravovat zařízení Bluetooth + Comment[de]=Bluetooth-Geräte verwalten ++Comment[el]=Διαχείριση συσκευών Bluetooth + Comment[en_GB]=Manage Bluetooth devices +-Comment[es]=Gestionar los dispositivos Bluetooth ++Comment[es]=Gestión de dispositivos Bluetooth ++Comment[et]=Bluetoothi seadmete haldamine + Comment[fi]=Bluetooth-laitteiden asetukset + Comment[fr]=Gère les périphériques Bluetooth + Comment[it]=Gestisci i dispositivi Bluetooth ++Comment[ja]=Bluetooth デバイスを管理 ++Comment[kk]=Bluetooth құрылығыларын басқару ++Comment[ko]=블루투스 장치 관리 ++Comment[lt]=Konfigūruoti Bluetooth failų gavimą ++Comment[mr]=ब्लूटूथ साधने व्यवस्थापीत करा + Comment[nb]=Håndter Blåtann-enheter + Comment[nl]=Bluetooth-apparaten beheren + Comment[pl]=Zarządzaj urządzeniami Bluetooth +@@ -57,14 +78,18 @@ Comment[sr@ijekavian]=Управљајте блутут уређајима + Comment[sr@ijekavianlatin]=Upravljajte bluetooth uređajima + Comment[sr@latin]=Upravljajte bluetooth uređajima + Comment[sv]=Hantera Blåtandenheter ++Comment[tr]=Bluetooth aygıtlarını yönet + Comment[uk]=Керування пристроями Bluetooth + Comment[x-test]=xxManage Bluetooth devicesxx + Comment[zh_CN]=管理蓝牙设备 ++Comment[zh_TW]=管理藍牙裝置 + + X-KDE-Keywords=Network,Connectivity,Bluetooth ++X-KDE-Keywords[bs]=Network,Connectivity,Bluetooth + X-KDE-Keywords[ca]=Xarxa,Connectivitat,Bluetooth + X-KDE-Keywords[cs]=Síť,Konektivita,Bluetooth + X-KDE-Keywords[de]=Netzwerk,Verbindungen,Bluetooth ++X-KDE-Keywords[el]=Δίκτυο,Συνδεσιμότητα,Bluetooth + X-KDE-Keywords[en_GB]=Network,Connectivity,Bluetooth + X-KDE-Keywords[es]=Red,Conectividad,Bluetooth + X-KDE-Keywords[fi]=Verkko,Yhteydet,Bluetooth +@@ -72,6 +97,7 @@ X-KDE-Keywords[fr]=Réseau, connectivité, Bluetooth + X-KDE-Keywords[it]=Rete,Connettività,Bluetooth + X-KDE-Keywords[nb]=Nettverk,sammenkobling,blåtann + X-KDE-Keywords[nl]=Netwerkverbinding,connectiviteit,bluetooth ++X-KDE-Keywords[pa]=ਨੈਟਵਰਕ,ਕਨੈਕਟਵਿਟੀ,ਬਲਿਊਟੁੱਥ + X-KDE-Keywords[pl]=Sieć,Łączność,Bluetooth + X-KDE-Keywords[pt]=Rede,Conectividade,Bluetooth + X-KDE-Keywords[pt_BR]=Rede,Conectividade,Bluetooth +@@ -82,8 +108,10 @@ X-KDE-Keywords[sr@ijekavian]=Network,Connectivity,Bluetooth,мрежа,пове + X-KDE-Keywords[sr@ijekavianlatin]=Network,Connectivity,Bluetooth,mreža,povezivanje,Bluetooth + X-KDE-Keywords[sr@latin]=Network,Connectivity,Bluetooth,mreža,povezivanje,Bluetooth + X-KDE-Keywords[sv]=Nätverk,Anslutningar,Blåtand ++X-KDE-Keywords[tr]=Ağ, Bağlanılabilirlik, Bluetooth + X-KDE-Keywords[uk]=Network,Connectivity,Bluetooth,мережа,з’єднання,з'єднання + X-KDE-Keywords[x-test]=xxNetworkxx,xxConnectivityxx,xxBluetoothxx + X-KDE-Keywords[zh_CN]=Network,Connectivity,Bluetooth,网络,连接,蓝牙 ++X-KDE-Keywords[zh_TW]=Network,Connectivity,Bluetooth + + Categories=Qt;KDE;X-KDE-settings-bluetooth; +diff --git a/src/kcmodule/bluedeviltransfer.desktop b/src/kcmodule/bluedeviltransfer.desktop +index 804b118..5bea142 100644 +--- a/src/kcmodule/bluedeviltransfer.desktop ++++ b/src/kcmodule/bluedeviltransfer.desktop +@@ -12,16 +12,20 @@ X-KDE-System-Settings-Parent-Category=bluetooth + X-KDE-Weight=60 + + Name=File Transfers ++Name[bs]=Transfer datoteke + Name[ca]=Transferències de fitxers + Name[cs]=Přenosy souborů + Name[de]=Dateiübertragungen ++Name[el]=Μεταφορές αρχείων + Name[en_GB]=File Transfers +-Name[es]=Transferencias de archivos ++Name[es]=Transferencias de archivo ++Name[et]=Failiedastused + Name[fi]=Tiedostonsiirto + Name[fr]=Transferts de fichiers + Name[it]=Trasferimenti di file + Name[nb]=Filoverføringer + Name[nl]=Bestandsoverdrachten ++Name[pa]=ਫਾਇਲ ਟਰਾਂਸਫਰ + Name[pl]=Przesyłanie plików + Name[pt]=Transferência de Ficheiros + Name[pt_BR]=Transferência de arquivos +@@ -32,21 +36,27 @@ Name[sr@ijekavian]=Преноси фајлова + Name[sr@ijekavianlatin]=Prenosi fajlova + Name[sr@latin]=Prenosi fajlova + Name[sv]=Filöverföringar ++Name[tr]=Dosya Aktarımı + Name[uk]=Перенесення файла + Name[x-test]=xxFile Transfersxx + Name[zh_CN]=文件传送 ++Name[zh_TW]=檔案傳輸 + + Comment=Configure Bluetooth file sharing and transfers ++Comment[bs]=Konfiguriranje Blutut dijeljenje datoteka i prijenos + Comment[ca]=Configura la compartició i transferència de fitxers per Bluetooth + Comment[cs]=Nastavte sdílení souborů přes Bluetooth + Comment[de]=Dateifreigaben und Dateiübertragung für Bluetooth einrichten ++Comment[el]=Διαμόρφωση διαμοιρασμού και μεταφοράς αρχείων με Bluetooth + Comment[en_GB]=Configure Bluetooth file sharing and transfers +-Comment[es]=Configurar la función de compartir archivos y las transferencias por Bluetooth ++Comment[es]=Configurar compartición y transferencias de archivos por Bluetooth ++Comment[et]=Bluetoothi failide jagamise ja edastamine seadistamine + Comment[fi]=Bluetooth-tiedostonjaon ja -siirron asetukset + Comment[fr]=Configure le partage et les transferts de fichiers par Bluetooth + Comment[it]=Configura la condivisione e il trasferimento di file via Bluetooth + Comment[nb]=Sett opp deling og overføring av filer over Blåtann + Comment[nl]=Bestandsdeling en -overdracht via bluetooth instellen ++Comment[pa]=ਬਲਿਊਟੁੱਥ ਫਾਇਲ ਸਾਂਝ ਤੇ ਟਰਾਂਸਫਰ ਸੰਰਚਨਾ + Comment[pl]=Ustawienia udostępniania i przesyłanie plików przez Bluetooth + Comment[pt]=Configura a partilha e as transferências de ficheiros por Bluetooth + Comment[pt_BR]=Configura o compartilhamento e a transferência de arquivos por Bluetooth +@@ -57,14 +67,18 @@ Comment[sr@ijekavian]=Подесите преносе и дељење фајло + Comment[sr@ijekavianlatin]=Podesite prenose i deljenje fajlova preko Bluetoothom + Comment[sr@latin]=Podesite prenose i deljenje fajlova preko Bluetoothom + Comment[sv]=Anpassa fildelning och överföringar med Blåtand ++Comment[tr]=Bluetooth dosya paylaşımı ve transferlerini yapılandır + Comment[uk]=Налаштування надсилання та отримання файлів Bluetooth + Comment[x-test]=xxConfigure Bluetooth file sharing and transfersxx + Comment[zh_CN]=配置蓝牙文件共享和传输 ++Comment[zh_TW]=設定藍牙檔案共用與傳輸 + + X-KDE-Keywords=Network,Connectivity,Bluetooth ++X-KDE-Keywords[bs]=Network,Connectivity,Bluetooth + X-KDE-Keywords[ca]=Xarxa,Connectivitat,Bluetooth + X-KDE-Keywords[cs]=Síť,Konektivita,Bluetooth + X-KDE-Keywords[de]=Netzwerk,Verbindungen,Bluetooth ++X-KDE-Keywords[el]=Δίκτυο,Συνδεσιμότητα,Bluetooth + X-KDE-Keywords[en_GB]=Network,Connectivity,Bluetooth + X-KDE-Keywords[es]=Red,Conectividad,Bluetooth + X-KDE-Keywords[fi]=Verkko,Yhteydet,Bluetooth +@@ -72,6 +86,7 @@ X-KDE-Keywords[fr]=Réseau, connectivité, Bluetooth + X-KDE-Keywords[it]=Rete,Connettività,Bluetooth + X-KDE-Keywords[nb]=Nettverk,sammenkobling,blåtann + X-KDE-Keywords[nl]=Netwerkverbinding,connectiviteit,bluetooth ++X-KDE-Keywords[pa]=ਨੈਟਵਰਕ,ਕਨੈਕਟਵਿਟੀ,ਬਲਿਊਟੁੱਥ + X-KDE-Keywords[pl]=Sieć,Łączność,Bluetooth + X-KDE-Keywords[pt]=Rede,Conectividade,Bluetooth + X-KDE-Keywords[pt_BR]=Rede,Conectividade,Bluetooth +@@ -82,8 +97,10 @@ X-KDE-Keywords[sr@ijekavian]=Network,Connectivity,Bluetooth,мрежа,пове + X-KDE-Keywords[sr@ijekavianlatin]=Network,Connectivity,Bluetooth,mreža,povezivanje,Bluetooth + X-KDE-Keywords[sr@latin]=Network,Connectivity,Bluetooth,mreža,povezivanje,Bluetooth + X-KDE-Keywords[sv]=Nätverk,Anslutningar,Blåtand ++X-KDE-Keywords[tr]=Ağ, Bağlanılabilirlik, Bluetooth + X-KDE-Keywords[uk]=Network,Connectivity,Bluetooth,мережа,з’єднання,з'єднання + X-KDE-Keywords[x-test]=xxNetworkxx,xxConnectivityxx,xxBluetoothxx + X-KDE-Keywords[zh_CN]=Network,Connectivity,Bluetooth,网络,连接,蓝牙 ++X-KDE-Keywords[zh_TW]=Network,Connectivity,Bluetooth + + Categories=Qt;KDE;X-KDE-settings-bluetooth; +diff --git a/src/kcmodule/systemcheck.cpp b/src/kcmodule/systemcheck.cpp +index 122021b..43cd864 100644 +--- a/src/kcmodule/systemcheck.cpp ++++ b/src/kcmodule/systemcheck.cpp +@@ -41,6 +41,7 @@ SystemCheck::SystemCheck(QWidget *parent) + , m_kded(new KDED(QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QDBusConnection::sessionBus())) + , m_parent(parent) + , m_noAdaptersError(0) ++ , m_noUsableAdapterError(0) + , m_notDiscoverableAdapterError(0) + , m_disabledNotificationsError(0) + { +@@ -48,9 +49,6 @@ SystemCheck::SystemCheck(QWidget *parent) + + SystemCheck::~SystemCheck() + { +- m_noAdaptersError = 0; +- m_notDiscoverableAdapterError = 0; +- m_disabledNotificationsError = 0; + delete m_kded; + } + +@@ -66,6 +64,16 @@ void SystemCheck::createWarnings(QVBoxLayout *layout) + m_noAdaptersError->setText(i18n("No Bluetooth adapters have been found.")); + layout->addWidget(m_noAdaptersError); + ++ m_noUsableAdapterError = new KMessageWidget(m_parent); ++ m_noUsableAdapterError->setMessageType(KMessageWidget::Warning); ++ m_noUsableAdapterError->setCloseButtonVisible(false); ++ m_noUsableAdapterError->setText(i18n("Your Bluetooth adapter is powered off.")); ++ ++ QAction *fixNoUsableAdapter = new QAction(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")), i18nc("Action to fix a problem", "Fix it"), m_noUsableAdapterError); ++ connect(fixNoUsableAdapter, SIGNAL(triggered(bool)), this, SLOT(fixNoUsableAdapterError())); ++ m_noUsableAdapterError->addAction(fixNoUsableAdapter); ++ layout->addWidget(m_noUsableAdapterError); ++ + m_notDiscoverableAdapterError = new KMessageWidget(m_parent); + m_notDiscoverableAdapterError->setMessageType(KMessageWidget::Warning); + m_notDiscoverableAdapterError->setCloseButtonVisible(false); +@@ -142,6 +150,7 @@ void SystemCheck::updateInformationState() + { + m_noAdaptersError->setEnabled(true); + m_noAdaptersError->setVisible(false); ++ m_noUsableAdapterError->setVisible(false); + m_notDiscoverableAdapterError->setVisible(false); + m_disabledNotificationsError->setVisible(false); + m_noKDEDRunning->setVisible(false); +@@ -151,9 +160,14 @@ void SystemCheck::updateInformationState() + return; + } + ++ if (BlueDevil::Manager::self()->adapters().isEmpty()) { ++ m_noAdaptersError->setVisible(true); ++ return; ++ } ++ + BlueDevil::Adapter *const usableAdapter = BlueDevil::Manager::self()->usableAdapter(); + if (!usableAdapter) { +- m_noAdaptersError->setVisible(true); ++ m_noUsableAdapterError->setVisible(true); + return; + } + if (!usableAdapter->isDiscoverable()) { +@@ -176,6 +190,12 @@ void SystemCheck::fixNoKDEDRunning() + m_kded->loadModule(QStringLiteral("bluedevil")); + } + ++void SystemCheck::fixNoUsableAdapterError() ++{ ++ m_noUsableAdapterError->setVisible(false); ++ BlueDevil::Manager::self()->adapters().first()->setPowered(true); ++} ++ + void SystemCheck::fixNotDiscoverableAdapterError() + { + m_notDiscoverableAdapterError->setVisible(false); +diff --git a/src/kcmodule/systemcheck.h b/src/kcmodule/systemcheck.h +index 74f9128..cccf899 100644 +--- a/src/kcmodule/systemcheck.h ++++ b/src/kcmodule/systemcheck.h +@@ -36,17 +36,6 @@ public: + SystemCheck(QWidget *parent); + virtual ~SystemCheck(); + +- struct SystemCheckResult { +- enum Result { +- NoWarnings = 0, +- BluetoothDisabled, +- NoAdapters, +- NotificationsDisabled, +- DefaultAdapterHidden +- } result; +- QWidget *warningWidget; +- }; +- + void createWarnings(QVBoxLayout *layout); + + bool checkKDEDModuleLoaded(); +@@ -61,6 +50,7 @@ public Q_SLOTS: + + private Q_SLOTS: + void fixNoKDEDRunning(); ++ void fixNoUsableAdapterError(); + void fixNotDiscoverableAdapterError(); + void fixDisabledNotificationsError(); + +@@ -68,6 +58,7 @@ private: + KDED *m_kded; + QWidget *m_parent; + KMessageWidget *m_noAdaptersError; ++ KMessageWidget *m_noUsableAdapterError; + KMessageWidget *m_noKDEDRunning; + KMessageWidget *m_notDiscoverableAdapterError; + KMessageWidget *m_disabledNotificationsError; +diff --git a/src/kio/bluetooth/kded_bluedevil.xml b/src/kio/bluetooth/kded_bluedevil.xml +index cb4d6fd..e447897 100644 +--- a/src/kio/bluetooth/kded_bluedevil.xml ++++ b/src/kio/bluetooth/kded_bluedevil.xml +@@ -5,11 +5,19 @@ + + + +- ++ + + + ++ ++ ++ ++ ++ ++ ++ ++ + + + +- +\ No newline at end of file ++ +diff --git a/src/kio/bluetooth/kiobluetooth.cpp b/src/kio/bluetooth/kiobluetooth.cpp +index e7b1289..6f9c700 100644 +--- a/src/kio/bluetooth/kiobluetooth.cpp ++++ b/src/kio/bluetooth/kiobluetooth.cpp +@@ -30,10 +30,6 @@ + #include + #include + +-#include +- +-using namespace BlueDevil; +- + extern "C" int Q_DECL_EXPORT kdemain(int argc, char **argv) + { + QCoreApplication app(argc, argv); +@@ -62,21 +58,22 @@ KioBluetooth::KioBluetooth(const QByteArray &pool, const QByteArray &app) + s.mimetype = QStringLiteral("application/vnd.kde.bluedevil-sendfile"); + s.uuid = QStringLiteral("00001105-0000-1000-8000-00805F9B34FB"); + m_supportedServices.insert(QStringLiteral("00001105-0000-1000-8000-00805F9B34FB"), s); ++ + s.name = i18n("Browse Files"); + s.icon = QStringLiteral("edit-find"); + s.mimetype = QString(); + s.uuid = QStringLiteral("00001106-0000-1000-8000-00805F9B34FB"); + m_supportedServices.insert(QStringLiteral("00001106-0000-1000-8000-00805F9B34FB"), s); + +- if (!Manager::self()->usableAdapter()) { +- qCDebug(BLUETOOTH) << "No available interface"; +- infoMessage(i18n("No Bluetooth adapters have been found.")); +- return; +- } +- + qCDebug(BLUETOOTH) << "Kio Bluetooth instanced!"; + m_kded = new org::kde::BlueDevil(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/bluedevil"), + QDBusConnection::sessionBus(), 0); ++ ++ if (!m_kded->isOnline()) { ++ qCDebug(BLUETOOTH) << "Bluetooth is offline"; ++ infoMessage(i18n("No Bluetooth adapters have been found.")); ++ return; ++ } + } + + QList KioBluetooth::getSupportedServices(const QStringList &uuids) +@@ -93,14 +90,22 @@ QList KioBluetooth::getSupportedServices(const QStringLis + + void KioBluetooth::listRemoteDeviceServices() + { +- m_kded->stopDiscovering(); + infoMessage(i18n("Retrieving services...")); + + qCDebug(BLUETOOTH) << "Listing remote devices"; +- m_currentHost = Manager::self()->usableAdapter()->deviceForAddress(m_currentHostname.replace('-', ':').toUpper()); +- m_currentHostServices = getSupportedServices(m_currentHost->UUIDs()); ++ ++ const DeviceInfo &info = m_kded->device(m_currentHostAddress).value(); ++ if (info.isEmpty()) { ++ qCDebug(BLUETOOTH) << "Invalid hostname!"; ++ infoMessage(i18n("This address is unavailable.")); ++ finished(); ++ return; ++ } ++ ++ m_currentHostServices = getSupportedServices(info.value(QStringLiteral("UUIDs")).split(QLatin1Char(','))); + + qCDebug(BLUETOOTH) << "Num of supported services: " << m_currentHostServices.size(); ++ + totalSize(m_currentHostServices.count()); + int i = 1; + Q_FOREACH (const Service &service, m_currentHostServices) { +@@ -137,11 +142,15 @@ void KioBluetooth::listRemoteDeviceServices() + void KioBluetooth::listDevices() + { + qCDebug(BLUETOOTH) << "Asking kded for devices"; +- QMapDeviceInfo devices = m_kded->knownDevices().value(); ++ const QMapDeviceInfo &devices = m_kded->allDevices().value(); + qCDebug(BLUETOOTH) << devices.keys(); ++ + Q_FOREACH(const DeviceInfo device, devices) { + listDevice(device); + } ++ ++ m_kded->startDiscovering(10 * 1000); ++ + infoMessage(i18n("Scanning for new devices...")); + finished(); + } +@@ -207,24 +216,25 @@ void KioBluetooth::get(const QUrl &url) + finished(); + } + +-void KioBluetooth::setHost(const QString &constHostname, quint16 port, const QString &user, ++void KioBluetooth::setHost(const QString &hostname, quint16 port, const QString &user, + const QString &pass) + { +- qCDebug(BLUETOOTH) << "Setting host: " << constHostname; ++ qCDebug(BLUETOOTH) << "Setting host: " << hostname; + + // In this kio only the hostname (constHostname) is used + Q_UNUSED(port) + Q_UNUSED(user) + Q_UNUSED(pass) + +- QString hostname = constHostname; +- hostname = hostname.replace(QLatin1Char('-'), QLatin1Char(':')).toUpper(); + if (hostname.isEmpty()) { + m_hasCurrentHost = false; + } else { + m_hasCurrentHost = true; +- m_currentHostname = constHostname; + m_currentHostServices.clear(); ++ ++ m_currentHostname = hostname; ++ m_currentHostAddress = hostname.toUpper(); ++ m_currentHostAddress.replace(QLatin1Char('-'), QLatin1Char(':')); + } + } + +diff --git a/src/kio/bluetooth/kiobluetooth.h b/src/kio/bluetooth/kiobluetooth.h +index a353ca9..294835a 100644 +--- a/src/kio/bluetooth/kiobluetooth.h ++++ b/src/kio/bluetooth/kiobluetooth.h +@@ -36,13 +36,6 @@ + */ + class KioBluetoothPrivate; + +-namespace BlueDevil { +- class Device; +- class Adapter; +-} +- +-using namespace BlueDevil; +- + class KioBluetooth : public QObject, public KIO::SlaveBase + { + Q_OBJECT +@@ -81,7 +74,7 @@ public: + * difference with @p listDir + * + */ +- void setHost(const QString &constHostname, quint16 port, const QString &user, const QString &pass); ++ void setHost(const QString &hostname, quint16 port, const QString &user, const QString &pass); + + /** + * Returns a list of supported service names corresponding to the given uuids list. If an uuid is +@@ -120,10 +113,9 @@ private: + QString m_currentHostname; + + /** +- * Represents the current host when @p hasCurrentHost is set to true. This is set in +- * @p listRemoteDeviceServices function. ++ * Uppercase colon separated address (ex. 00:2A:5E:8E:6E:F5) + */ +- Device *m_currentHost; ++ QString m_currentHostAddress; + + /** + * When @p hasCurrentHost to true, this list holds the list of service names provided by the +@@ -133,12 +125,6 @@ private: + + /** + * This is an array containing as key the uuid and as value the name of the service that the +- * given uuid represents. +- */ +- QMap m_serviceNames; +- +- /** +- * This is an array containing as key the uuid and as value the name of the service that the + * given uuid represents, and a representative icon. It only contains the supported service names. + */ + QMap m_supportedServices; +diff --git a/src/kio/obexftp/daemon/CMakeLists.txt b/src/kio/obexftp/daemon/CMakeLists.txt +index b7ad5d2..8a4ff87 100644 +--- a/src/kio/obexftp/daemon/CMakeLists.txt ++++ b/src/kio/obexftp/daemon/CMakeLists.txt +@@ -12,7 +12,7 @@ qt5_add_dbus_interface(kded_obexftp_SRCS org.freedesktop.DBus.ObjectManager.xml + + add_library(kded_obexftpdaemon MODULE ${kded_obexftp_SRCS}) + +-kservice_desktop_to_json(kded_obexftpdaemon obexftpdaemon.desktop) ++kcoreaddons_desktop_to_json(kded_obexftpdaemon obexftpdaemon.desktop) + + target_link_libraries(kded_obexftpdaemon + Qt5::Core +diff --git a/src/kio/obexftp/daemon/ObexFtpDaemon.cpp b/src/kio/obexftp/daemon/ObexFtpDaemon.cpp +index af66c7c..4170193 100644 +--- a/src/kio/obexftp/daemon/ObexFtpDaemon.cpp ++++ b/src/kio/obexftp/daemon/ObexFtpDaemon.cpp +@@ -29,10 +29,6 @@ + #include + #include + +-#include +-#include +- +-using namespace BlueDevil; + K_PLUGIN_FACTORY_WITH_JSON(ObexFtpFactory, + "obexftpdaemon.json", + registerPlugin();) +@@ -58,8 +54,6 @@ ObexFtpDaemon::ObexFtpDaemon(QObject *parent, const QList&) + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + +- d->m_status = Private::Offline; +- + KAboutData aboutData(QStringLiteral("obexftpdaemon"), + i18n("ObexFtp Daemon"), + bluedevil_version, +@@ -70,13 +64,10 @@ ObexFtpDaemon::ObexFtpDaemon(QObject *parent, const QList&) + aboutData.addAuthor(i18n("Alejandro Fiestas Olivares"), i18n("Maintainer"), + QStringLiteral("afiestas@kde.org"), QStringLiteral("http://www.afiestas.org")); + +- connect(Manager::self(), SIGNAL(usableAdapterChanged(Adapter*)), +- SLOT(usableAdapterChanged(Adapter*))); +- ++ d->m_status = Private::Offline; + d->m_interface = new OrgFreedesktopDBusObjectManagerInterface(QStringLiteral("org.bluez.obex"), + QStringLiteral("/"), + QDBusConnection::sessionBus(), this); +- + connect(d->m_interface, SIGNAL(InterfacesRemoved(QDBusObjectPath,QStringList)), + SLOT(interfaceRemoved(QDBusObjectPath,QStringList))); + +@@ -84,11 +75,13 @@ ObexFtpDaemon::ObexFtpDaemon(QObject *parent, const QList&) + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForUnregistration, this); + +- connect(d->m_serviceWatcher, SIGNAL(serviceUnregistered(QString)), SLOT(serviceUnregistered(QString))); ++ connect(d->m_serviceWatcher, SIGNAL(serviceRegistered(QString)), SLOT(serviceRegistered())); ++ connect(d->m_serviceWatcher, SIGNAL(serviceUnregistered(QString)), SLOT(serviceUnregistered())); + +- //WARNING this blocks if org.bluez in system bus is dead +- if (Manager::self()->usableAdapter()) { ++ if (QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.bluez.obex"))) { + onlineMode(); ++ } else { ++ offlineMode(); + } + } + +@@ -114,6 +107,7 @@ void ObexFtpDaemon::onlineMode() + void ObexFtpDaemon::offlineMode() + { + qCDebug(OBEXDAEMON) << "Offline mode"; ++ + if (d->m_status == Private::Offline) { + qCDebug(OBEXDAEMON) << "Already in offlineMode"; + return; +@@ -125,33 +119,28 @@ void ObexFtpDaemon::offlineMode() + d->m_status = Private::Offline; + } + +-void ObexFtpDaemon::usableAdapterChanged(Adapter *adapter) ++bool ObexFtpDaemon::isOnline() + { +- if (!adapter) { +- offlineMode(); +- return; +- } +- +- onlineMode(); ++ return d->m_status == Private::Online; + } + +-QString ObexFtpDaemon::session(QString address, const QDBusMessage& msg) ++QString ObexFtpDaemon::session(const QString &address, const QString &target, const QDBusMessage& msg) + { +- qCDebug(OBEXDAEMON) << address; +- address.replace(QLatin1Char('-'), QLatin1Char(':')); +- + if (d->m_sessionMap.contains(address)) { + return d->m_sessionMap[address]; + } + +- //At this point we always want delayed reply ++ qCDebug(OBEXDAEMON) << "Creating session for" << address << "target" << target; ++ ++ // At this point we always want delayed reply + msg.setDelayedReply(true); ++ + if (d->m_wipSessions.contains(address)) { + d->m_wipSessions[address]->addMessage(msg); + return QString(); + } + +- CreateSessionJob *job = new CreateSessionJob(address, msg); ++ CreateSessionJob *job = new CreateSessionJob(address, target, msg); + connect(job, SIGNAL(finished(KJob*)), SLOT(sessionCreated(KJob*))); + job->start(); + +@@ -159,30 +148,46 @@ QString ObexFtpDaemon::session(QString address, const QDBusMessage& msg) + return QString(); + } + ++bool ObexFtpDaemon::cancelTransfer(const QString &transfer) ++{ ++ // We need this function because kio_obexftp is not owner of the transfer, ++ // and thus cannot cancel it. ++ ++ QDBusMessage call = QDBusMessage::createMethodCall(QStringLiteral("org.bluez.obex"), ++ transfer, ++ QStringLiteral("org.bluez.obex.Transfer1"), ++ QStringLiteral("Cancel")); ++ ++ QDBusReply reply = QDBusConnection::sessionBus().call(call); ++ return reply.isValid(); ++} ++ + void ObexFtpDaemon::sessionCreated(KJob* job) + { + CreateSessionJob* cJob = qobject_cast(job); + qCDebug(OBEXDAEMON) << cJob->path(); + + d->m_wipSessions.remove(cJob->address()); +- d->m_sessionMap.insert(cJob->address(), cJob->path()); +- d->m_reverseSessionMap.insert(cJob->path(), cJob->address()); + +- const QList messages = cJob->messages(); +- Q_FOREACH(const QDBusMessage &msg, messages) { ++ Q_FOREACH (const QDBusMessage &msg, cJob->messages()) { + QDBusMessage reply = msg.createReply(cJob->path()); +- QDBusConnection::sessionBus().asyncCall(reply); ++ QDBusConnection::sessionBus().send(reply); ++ } ++ ++ if (!cJob->error()) { ++ d->m_sessionMap.insert(cJob->address(), cJob->path()); ++ d->m_reverseSessionMap.insert(cJob->path(), cJob->address()); + } + } + +-void ObexFtpDaemon::serviceUnregistered(const QString& service) ++void ObexFtpDaemon::serviceRegistered() + { +- if (service != QLatin1String("org.bluez.obex")) { +- return; +- } ++ onlineMode(); ++} + +- d->m_sessionMap.clear(); +- d->m_reverseSessionMap.clear(); ++void ObexFtpDaemon::serviceUnregistered() ++{ ++ offlineMode(); + } + + void ObexFtpDaemon::interfaceRemoved(const QDBusObjectPath &dbusPath, const QStringList& interfaces) +diff --git a/src/kio/obexftp/daemon/ObexFtpDaemon.h b/src/kio/obexftp/daemon/ObexFtpDaemon.h +index d56b73d..28c34ab 100644 +--- a/src/kio/obexftp/daemon/ObexFtpDaemon.h ++++ b/src/kio/obexftp/daemon/ObexFtpDaemon.h +@@ -30,44 +30,28 @@ class QDBusMessage; + class QDBusObjectPath; + class QDBusPendingCallWatcher; + +-namespace BlueDevil { +- class Adapter; +-}; +-using namespace BlueDevil; +- +-class Q_DECL_EXPORT ObexFtpDaemon +- : public KDEDModule ++class Q_DECL_EXPORT ObexFtpDaemon : public KDEDModule + { + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.ObexFtp") + + public: +- /** +- * Connects to usableAdapterChanged +- */ + ObexFtpDaemon(QObject *parent, const QList&); + virtual ~ObexFtpDaemon(); + + public Q_SLOTS: +- Q_SCRIPTABLE QString session(QString address, const QDBusMessage &msg); ++ Q_SCRIPTABLE bool isOnline(); ++ Q_SCRIPTABLE QString session(const QString &address, const QString &target, const QDBusMessage &msg); ++ Q_SCRIPTABLE bool cancelTransfer(const QString &transfer); + + private Q_SLOTS: +- void usableAdapterChanged(Adapter* adapter); + void sessionCreated(KJob* job); +- void serviceUnregistered(const QString &service); ++ void serviceRegistered(); ++ void serviceUnregistered(); + void interfaceRemoved(const QDBusObjectPath &path, const QStringList &interfaces); + + private: +- /** +- * Called by constructor or eventually by adapterAdded initialize all the helpers +- * @see helpers +- */ +- void onlineMode(); +- +- /** +- * Called eventually adapterRemoved shutdown all the helpers +- * @see helpers +- */ ++ void onlineMode(); + void offlineMode(); + + struct Private; +diff --git a/src/kio/obexftp/daemon/createsessionjob.cpp b/src/kio/obexftp/daemon/createsessionjob.cpp +index 2eba356..c019156 100644 +--- a/src/kio/obexftp/daemon/createsessionjob.cpp ++++ b/src/kio/obexftp/daemon/createsessionjob.cpp +@@ -24,9 +24,10 @@ + #include + + // class +-CreateSessionJob::CreateSessionJob(const QString& address, const QDBusMessage& msg, QObject* parent) ++CreateSessionJob::CreateSessionJob(const QString &address, const QString &target, const QDBusMessage &msg, QObject *parent) + : KJob(parent) + , m_address(address) ++ , m_target(target) + , m_client(0) + { + m_messages.append(msg); +@@ -52,7 +53,7 @@ void CreateSessionJob::addMessage(const QDBusMessage& msg) + m_messages.append(msg); + } + +-const QList< QDBusMessage > CreateSessionJob::messages() const ++const QList CreateSessionJob::messages() const + { + return m_messages; + } +@@ -61,8 +62,7 @@ void CreateSessionJob::createSession() + { + qCDebug(OBEXDAEMON); + QVariantMap args; +- args[QStringLiteral("Target")] = QStringLiteral("ftp"); +-// args["Source"] = "00:02:72:D6:8F:2C"; ++ args[QStringLiteral("Target")] = m_target; + m_client = new OrgBluezObexClient1Interface(QStringLiteral("org.bluez.obex"), + QStringLiteral("/org/bluez/obex"), + QDBusConnection::sessionBus(), this); +@@ -70,7 +70,6 @@ void CreateSessionJob::createSession() + QDBusPendingReply reply = m_client->CreateSession(m_address, args); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply); + +- qCDebug(OBEXDAEMON) << "DROGUES"; + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(sessionCreated(QDBusPendingCallWatcher*))); + } + +@@ -83,12 +82,7 @@ void CreateSessionJob::sessionCreated(QDBusPendingCallWatcher* watcher) + qCDebug(OBEXDAEMON) << "Error:"; + qCDebug(OBEXDAEMON) << reply.error().name(); + qCDebug(OBEXDAEMON) << reply.error().message(); +-// Q_FOREACH(const QDBusMessage &msg, m_msgs) { +-// qCDebug(OBEXDAEMON) << msg.service() << msg.path(); +-// QDBusMessage errorMsg = msg.createErrorReply("org.kde.kded.Error", i18n("Can't stablish connection")); +-// QDBusConnection::sessionBus().send(errorMsg); +-// }C +-// m_status = Error; ++ + setError(reply.error().type()); + setErrorText(reply.error().message()); + emitResult(); +diff --git a/src/kio/obexftp/daemon/createsessionjob.h b/src/kio/obexftp/daemon/createsessionjob.h +index a457b02..667384b 100644 +--- a/src/kio/obexftp/daemon/createsessionjob.h ++++ b/src/kio/obexftp/daemon/createsessionjob.h +@@ -29,7 +29,7 @@ class CreateSessionJob : public KJob + { + Q_OBJECT + public: +- explicit CreateSessionJob(const QString &address, const QDBusMessage &msg, QObject* parent = 0); ++ explicit CreateSessionJob(const QString &address, const QString &target, const QDBusMessage &msg, QObject *parent = 0); + + virtual void start(); + QString path(); +@@ -44,9 +44,10 @@ private Q_SLOTS: + private: + QString m_path; + QString m_address; ++ QString m_target; + QList m_messages; + + OrgBluezObexClient1Interface* m_client; + }; + +-#endif //CREATE_SESSION_JOB_H +\ No newline at end of file ++#endif //CREATE_SESSION_JOB_H +diff --git a/src/kio/obexftp/daemon/obexftpdaemon.desktop b/src/kio/obexftp/daemon/obexftpdaemon.desktop +index 07b7b2e..b23a6d1 100644 +--- a/src/kio/obexftp/daemon/obexftpdaemon.desktop ++++ b/src/kio/obexftp/daemon/obexftpdaemon.desktop +@@ -9,16 +9,20 @@ X-KDE-Kded-load-on-demand=true + X-KDE-Kded-phase=1 + + Name=Bluetooth File Transfer ++Name[bs]=Transfer Bluetooth Daoteke + Name[ca]=Transferència de fitxer per Bluetooth + Name[cs]=Přenos souborů Bluetooth + Name[de]=Bluetooth-Dateiübertragung ++Name[el]=Μεταφορά αρχείων με Bluetooth + Name[en_GB]=Bluetooth File Transfer +-Name[es]=Transferencia de archivos por Bluetooth ++Name[es]=Transferencia de archivo por Bluetooth ++Name[et]=Bluetoothi failiedastus + Name[fi]=Bluetooth-tiedostonsiirto + Name[fr]=Transfert de fichiers Bluetooth + Name[it]=Trasferimento file via Bluetooth + Name[nb]=Blåtann filoverføring + Name[nl]=Bestandsoverdracht via bluetooth ++Name[pa]=ਬਲਿਊਟੁੱਥ ਫਾਇਲ ਟਰਾਂਸਫਰ + Name[pl]=Przesyłanie plików Bluetooth + Name[pt]=Transferência de Ficheiros por Bluetooth + Name[pt_BR]=Transferência de arquivos por Bluetooth +@@ -29,16 +33,21 @@ Name[sr@ijekavian]=Блутут пренос фајла + Name[sr@ijekavianlatin]=Bluetooth prenos fajla + Name[sr@latin]=Bluetooth prenos fajla + Name[sv]=Filöverföring med Blåtand ++Name[tr]=Bluetooth Dosya Aktarımı + Name[uk]=Перенесення файла за допомогою Bluetooth + Name[x-test]=xxBluetooth File Transferxx + Name[zh_CN]=蓝牙文件传输 ++Name[zh_TW]=藍牙檔案傳輸 + + Comment=Supports Bluetooth file transfer using ObexFTP ++Comment[bs]=Podržava Blutut prijenos datoteka koristeći ObexFTP + Comment[ca]=Accepta transferència de fitxer per Bluetooth usant ObexFTP + Comment[cs]=Podporuje přenos souborů Bluetooth použitím ObexFTP + Comment[de]=Unterstützt Bluetooth-Datenübertragung mittels ObexFTP ++Comment[el]=Υποστηρίζει μεταφορά αρχείων με Bluetooth με χρήση ObexFTP + Comment[en_GB]=Supports Bluetooth file transfer using ObexFTP +-Comment[es]=Permite la transferencia de archivos por Bluetooth usando ObexFTP ++Comment[es]=Permite transferencias de archivos por Bluetooth usando ObexFTP ++Comment[et]=Bluetoothi failiedastuse toetamine ObexFTP vahendusel + Comment[fi]=Tukee Bluetooth-tiedostonsiirtoa ObexFTP:tä käyttäen + Comment[fr]=Prend en charge le transfert de fichiers Bluetooth à l'aide de « ObexFTP » + Comment[it]=Supporta i trasferimenti di file Bluetooth usando ObexFTP +@@ -54,6 +63,8 @@ Comment[sr@ijekavian]=Подршка за блутут преносе фајло + Comment[sr@ijekavianlatin]=Podrška za bluetooth prenose fajlova pomoću ObexFTP‑a + Comment[sr@latin]=Podrška za bluetooth prenose fajlova pomoću ObexFTP‑a + Comment[sv]=Stöder filöverföringar för Blåtand med ObexFTP ++Comment[tr]=ObexFTP kullanarak Bluetooth dosya transferlerini destekler + Comment[uk]=Підтримує перенесення файлів Bluetooth за допомогою ObexFTP + Comment[x-test]=xxSupports Bluetooth file transfer using ObexFTPxx + Comment[zh_CN]=支持使用 ObexFTP 进行蓝牙文件传输 ++Comment[zh_TW]=使用 ObexFTP 支援藍牙檔案傳輸 +diff --git a/src/kio/obexftp/kded_obexftp.xml b/src/kio/obexftp/kded_obexftp.xml +index 24c6c5c..06e3b14 100644 +--- a/src/kio/obexftp/kded_obexftp.xml ++++ b/src/kio/obexftp/kded_obexftp.xml +@@ -3,9 +3,17 @@ + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + + ++ ++ ++ + + ++ + + ++ ++ ++ ++ + +- +\ No newline at end of file ++ +diff --git a/src/kio/obexftp/kio_obexftp.cpp b/src/kio/obexftp/kio_obexftp.cpp +index b5b93d8..17eefec 100644 +--- a/src/kio/obexftp/kio_obexftp.cpp ++++ b/src/kio/obexftp/kio_obexftp.cpp +@@ -61,16 +61,21 @@ static QString urlFileName(const QUrl &url) + return u.fileName(); + } + ++static bool urlIsRoot(const QUrl &url) ++{ ++ const QString &directory = urlDirectory(url); ++ return (directory.isEmpty() || directory == QLatin1String("/")) && urlFileName(url).isEmpty(); ++} ++ + KioFtp::KioFtp(const QByteArray &pool, const QByteArray &app) + : SlaveBase(QByteArrayLiteral("obexftp"), pool, app) +- , m_settingHost(false) + , m_transfer(0) + { +- qDBusRegisterMetaType(); +- + m_timer = new QTimer(); + m_timer->setInterval(100); + ++ qDBusRegisterMetaType(); ++ qDBusRegisterMetaType(); + m_kded = new org::kde::ObexFtp(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/obexftpdaemon"), + QDBusConnection::sessionBus(), 0); + } +@@ -88,6 +93,63 @@ void KioFtp::launchProgressBar() + m_timer->start(); + } + ++void KioFtp::connectToHost() ++{ ++ // Prefer pcsuite target on S60 devices ++ if (m_uuids.contains(QLatin1String("00005005-0000-1000-8000-0002EE000001"))) { ++ if (createSession("pcsuite")) { ++ return; ++ } ++ // Fallback to ftp ++ } ++ ++ createSession("ftp"); ++} ++ ++bool KioFtp::testConnection() ++{ ++ if (!m_kded->isOnline().value()) { ++ error(KIO::ERR_SLAVE_DEFINED, i18n("Obexd service is not running.")); ++ return false; ++ } ++ ++ connectToHost(); ++ ++ if (!m_transfer) { ++ error(KIO::ERR_COULD_NOT_CONNECT, m_host); ++ return false; ++ } ++ return true; ++} ++ ++bool KioFtp::createSession(const QString &target) ++{ ++ QDBusPendingReply reply = m_kded->session(m_host, target); ++ reply.waitForFinished(); ++ ++ const QString &sessionPath = reply.value(); ++ ++ if (reply.isError() || sessionPath.isEmpty()) { ++ qCDebug(OBEXFTP) << reply.error().message(); ++ qCDebug(OBEXFTP) << reply.error().name(); ++ ++ delete m_transfer; ++ m_transfer = 0; ++ m_sessionPath.clear(); ++ return false; ++ } ++ ++ if (m_sessionPath != sessionPath) { ++ m_statMap.clear(); ++ delete m_transfer; ++ m_transfer = new org::bluez::obex::FileTransfer1(QStringLiteral("org.bluez.obex"), sessionPath, QDBusConnection::sessionBus()); ++ m_sessionPath = sessionPath; ++ } ++ ++ return true; ++} ++ ++ + void KioFtp::updateProcess() + { + if (m_counter == 49) { +@@ -102,34 +164,27 @@ void KioFtp::updateProcess() + + void KioFtp::listDir(const QUrl &url) + { ++ if (!testConnection()) { ++ return; ++ } ++ + qCDebug(OBEXFTP) << "listdir: " << url; + + infoMessage(i18n("Retrieving information from remote device...")); + +- qCDebug(OBEXFTP) << "Asking for listFolder"; +- +- //TODO: Check if changeFolder fails +- m_transfer->ChangeFolder(url.path()).waitForFinished(); ++ qCDebug(OBEXFTP) << "Asking for listFolder" << url.path(); + +- QDBusPendingReply reply = m_transfer->ListFolder(); +- reply.waitForFinished(); +- +- if (reply.isError()) { +- qCDebug(OBEXFTP) << reply.error().message(); +- error(KIO::ERR_SLAVE_DEFINED, i18n("Bluetooth is not enabled")); ++ if (!changeFolder(url.path())) { + return; + } +- QVariantMapList folderList = reply.value(); +- Q_FOREACH(const QVariantMap folder, folderList) { +- KIO::UDSEntry entry = entryFromInfo(folder); + +- QUrl statUrl = url.adjusted(QUrl::RemoveFilename); +- statUrl.setPath(statUrl.path() + folder[QStringLiteral("Name")].toString()); +- if (!m_statMap.contains(statUrl.toDisplayString())) { +- qCDebug(OBEXFTP) << "Stat: " << statUrl.toDisplayString() << entry.numberValue(KIO::UDSEntry::UDS_SIZE); +- m_statMap.insert(statUrl.toDisplayString(), entry); +- } ++ bool ok; ++ const QList &list = listFolder(url, &ok); ++ if (!ok) { ++ return; ++ } + ++ Q_FOREACH (const KIO::UDSEntry &entry, list) { + listEntry(entry); + } + +@@ -141,10 +196,13 @@ void KioFtp::copy(const QUrl &src, const QUrl &dest, int permissions, KIO::JobFl + Q_UNUSED(permissions) + Q_UNUSED(flags) + ++ if (!testConnection()) { ++ return; ++ } ++ + qCDebug(OBEXFTP) << "copy: " << src.url() << " to " << dest.url(); + + copyHelper(src, dest); +- + finished(); + } + +@@ -154,11 +212,15 @@ void KioFtp::rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags) + Q_UNUSED(dest) + Q_UNUSED(flags) + +- error(KIO::ERR_UNSUPPORTED_ACTION, src.toDisplayString()); ++ error(KIO::ERR_UNSUPPORTED_ACTION, QString()); + } + + void KioFtp::get(const QUrl& url) + { ++ if (!testConnection()) { ++ return; ++ } ++ + QTemporaryFile tempFile(QString(QStringLiteral("%1/kioftp_XXXXXX.%2")).arg(QDir::tempPath(), urlFileName(url))); + tempFile.open();//Create the file + qCDebug(OBEXFTP) << tempFile.fileName(); +@@ -180,6 +242,10 @@ void KioFtp::get(const QUrl& url) + finished(); + } + ++bool KioFtp::cancelTransfer(const QString &transfer) ++{ ++ return m_kded->cancelTransfer(transfer); ++} + + void KioFtp::setHost(const QString &host, quint16 port, const QString &user, const QString &pass) + { +@@ -187,35 +253,38 @@ void KioFtp::setHost(const QString &host, quint16 port, const QString &user, con + Q_UNUSED(user) + Q_UNUSED(pass) + +- infoMessage(i18n("Connecting to the device")); ++ m_host = host; ++ m_host = m_host.replace(QLatin1Char('-'), QLatin1Char(':')).toUpper(); + +- qCDebug(OBEXFTP) << "setHost: " << host; ++ QDBusMessage call = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"), ++ QStringLiteral("/modules/bluedevil"), ++ QStringLiteral("org.kde.BlueDevil"), ++ QStringLiteral("device")); ++ call << m_host; ++ QDBusReply reply = QDBusConnection::sessionBus().call(call); ++ DeviceInfo info = reply.value(); + +- qCDebug(OBEXFTP) << "Waiting to stablish the connection 2"; +- QDBusPendingReply reply = m_kded->session(host); +- reply.waitForFinished(); ++ m_uuids = info[QStringLiteral("UUIDs")]; + +- qCDebug(OBEXFTP) << "AFTER" << reply.isError(); +- if (reply.isError()) { +- qCDebug(OBEXFTP) << reply.error().message(); +- qCDebug(OBEXFTP) << reply.error().name(); +- } +- +- qCDebug(OBEXFTP) << "Got a path" << reply.value(); ++ infoMessage(i18n("Connecting to the device")); + +- m_address = host; +- m_sessionPath = reply.value(); +- m_transfer = new org::bluez::obex::FileTransfer1("org.bluez.obex", m_sessionPath, QDBusConnection::sessionBus()); +- m_statMap.clear(); ++ connectToHost(); + } + + void KioFtp::del(const QUrl& url, bool isfile) + { + Q_UNUSED(isfile) + +- qCDebug(OBEXFTP) << "Del: " << url.url(); +- m_transfer->ChangeFolder(urlDirectory(url)).waitForFinished(); +- m_transfer->Delete(urlFileName(url)).waitForFinished(); ++ if (!testConnection()) { ++ return; ++ } ++ if (!changeFolder(urlDirectory(url))) { ++ return; ++ } ++ if (!deleteFile(urlFileName(url))) { ++ return; ++ } ++ + finished(); + } + +@@ -223,14 +292,28 @@ void KioFtp::mkdir(const QUrl& url, int permissions) + { + Q_UNUSED(permissions) + ++ if (!testConnection()) { ++ return; ++ } ++ + qCDebug(OBEXFTP) << "MkDir: " << url.url(); +- m_transfer->ChangeFolder(urlDirectory(url)).waitForFinished(); +- m_transfer->CreateFolder(urlFileName(url)).waitForFinished(); ++ ++ if (!changeFolder(urlDirectory(url))) { ++ return; ++ } ++ if (!createFolder(urlFileName(url))) { ++ return; ++ } ++ + finished(); + } + + void KioFtp::stat(const QUrl &url) + { ++ if (!testConnection()) { ++ return; ++ } ++ + qCDebug(OBEXFTP) << "Stat: " << url.url(); + qCDebug(OBEXFTP) << "Stat Dir: " << urlDirectory(url); + qCDebug(OBEXFTP) << "Stat File: " << urlFileName(url); +@@ -245,8 +328,7 @@ void KioFtp::stat(const QUrl &url) + void KioFtp::copyHelper(const QUrl& src, const QUrl& dest) + { + if (src.scheme() == QLatin1String("obexftp") && dest.scheme() == QLatin1String("obexftp")) { +- error(KIO::ERR_UNSUPPORTED_ACTION, src.toDisplayString()); +- //TODO: with obexd this seems possible, we should at least try ++ copyWithinObexftp(src, dest); + return; + } + +@@ -261,55 +343,49 @@ void KioFtp::copyHelper(const QUrl& src, const QUrl& dest) + } + + qCDebug(OBEXFTP) << "This shouldn't happen..."; +- finished(); + } + +-void KioFtp::copyFromObexftp(const QUrl& src, const QUrl& dest) ++void KioFtp::copyWithinObexftp(const QUrl &src, const QUrl &dest) + { + qCDebug(OBEXFTP) << "Source: " << src << "Dest:" << dest; + +- //Just in case the url is not in the stat, some times happens... +- if (!m_statMap.contains(src.toDisplayString())) { +- qCDebug(OBEXFTP) << "The url is not in the cache, stating it"; +- statHelper(src); +- } ++ copyFile(src.path(), dest.path()); ++} ++ ++void KioFtp::copyFromObexftp(const QUrl& src, const QUrl& dest) ++{ ++ qCDebug(OBEXFTP) << "Source: " << src << "Dest:" << dest; + +- if (m_statMap.value(src.toDisplayString()).isDir()) { +- qCDebug(OBEXFTP) << "Skipping to copy: " << src.toDisplayString(); +- //TODO: Check if dir copying works with obexd +- error(KIO::ERR_IS_DIRECTORY, src.toDisplayString()); ++ if (!changeFolder(urlDirectory(src))) { + return; + } + +- qCDebug(OBEXFTP) << "Changing dir:" << urlDirectory(src); +- m_transfer->ChangeFolder(urlDirectory(src)).waitForFinished(); +- +- QString dbusPath = m_transfer->GetFile(dest.path(), urlFileName(src)).value().path(); ++ const QString &dbusPath = m_transfer->GetFile(dest.path(), urlFileName(src)).value().path(); + qCDebug(OBEXFTP) << "Path from GetFile:" << dbusPath; + + int size = m_statMap[src.toDisplayString()].numberValue(KIO::UDSEntry::UDS_SIZE); ++ totalSize(size); ++ + TransferFileJob *getFile = new TransferFileJob(dbusPath, this); +- getFile->setSize(size); + getFile->exec(); +- +- finished(); + } + + void KioFtp::copyToObexftp(const QUrl& src, const QUrl& dest) + { + qCDebug(OBEXFTP) << "Source:" << src << "Dest:" << dest; + +- qCDebug(OBEXFTP) << "Changing folder: " << urlDirectory(dest); +- m_transfer->ChangeFolder(urlDirectory(dest)); +- QString dbusPath = m_transfer->PutFile(src.path(), urlFileName(dest)).value().path(); ++ if (!changeFolder(urlDirectory(dest))) { ++ return; ++ } ++ ++ const QString &dbusPath = m_transfer->PutFile(src.path(), urlFileName(dest)).value().path(); + qCDebug(OBEXFTP) << "Path from PutFile: " << dbusPath; + +- QFile file(src.path()); ++ int size = QFile(src.path()).size(); ++ totalSize(size); ++ + TransferFileJob *putFile = new TransferFileJob(dbusPath, this); +- putFile->setSize(file.size()); + putFile->exec(); +- +- finished(); + } + + void KioFtp::statHelper(const QUrl& url) +@@ -322,10 +398,10 @@ void KioFtp::statHelper(const QUrl& url) + return; + } + +- if ((urlDirectory(url) == QLatin1String("/") || urlDirectory(url).isEmpty()) && urlFileName(url).isEmpty()) { ++ if (urlIsRoot(url)) { + qCDebug(OBEXFTP) << "Url is root"; + KIO::UDSEntry entry; +- entry.insert(KIO::UDSEntry::UDS_NAME, QString::fromLatin1("/")); ++ entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("/")); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); + entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); +@@ -333,53 +409,145 @@ void KioFtp::statHelper(const QUrl& url) + qCDebug(OBEXFTP) << "Adding stat cached: " << url.toDisplayString(); + m_statMap[url.toDisplayString()] = entry; + statEntry(entry); +- + return; + } + + qCDebug(OBEXFTP) << "statMap does NOT contains the url"; +- //TODO: Check if changeFolder fails +- m_transfer->ChangeFolder(urlDirectory(url)).waitForFinished(); +- QVariantMapList folderList = m_transfer->ListFolder().value(); +- qCDebug(OBEXFTP) << urlDirectory(url) << folderList.count(); +- Q_FOREACH(const QVariantMap folder, folderList) { +- KIO::UDSEntry entry = entryFromInfo(folder); +- +- QString fileName = folder[QStringLiteral("Name")].toString(); +- if (urlFileName(url) == fileName) { +- statEntry(entry); ++ ++ if (!changeFolder(urlDirectory(url))) { ++ return; ++ } ++ ++ bool ok; ++ const QList &list = listFolder(url, &ok); ++ if (!ok) { ++ return; ++ } ++ ++ Q_FOREACH (const KIO::UDSEntry &entry, list) { ++ statEntry(entry); ++ } ++ ++ qCDebug(OBEXFTP) << "Finished"; ++} ++ ++QList KioFtp::listFolder(const QUrl &url, bool *ok) ++{ ++ QList list; ++ ++ QDBusPendingReply reply = m_transfer->ListFolder(); ++ reply.waitForFinished(); ++ ++ if (reply.isError()) { ++ error(KIO::ERR_CANNOT_OPEN_FOR_READING, urlDirectory(url)); ++ *ok = false; ++ return list; ++ } ++ ++ Q_FOREACH (const QVariantMap &item, reply.value()) { ++ KIO::UDSEntry entry; ++ entry.insert(KIO::UDSEntry::UDS_NAME, item[QStringLiteral("Name")].toString()); ++ entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, item[QStringLiteral("Label")].toString()); ++ entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700); ++ entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, QDateTime::fromString(item[QStringLiteral("Modified")].toString(), "yyyyMMddThhmmssZ").toTime_t()); ++ entry.insert(KIO::UDSEntry::UDS_SIZE, item[QStringLiteral("Size")].toLongLong()); ++ if (item[QStringLiteral("Type")] == QLatin1String("folder")) { ++ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); ++ entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); ++ } else { ++ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); ++ } ++ if (urlIsRoot(url)) { ++ updateRootEntryIcon(entry, item[QStringLiteral("Mem-type")].toString()); + } ++ list.append(entry); + + //Most probably the client of the kio will stat each file + //so since we are on it, let's cache all of them. + QUrl statUrl = url.adjusted(QUrl::RemoveFilename); +- statUrl.setPath(statUrl.path() + fileName); ++ statUrl.setPath(statUrl.path() + item[QStringLiteral("Name")].toString()); + if (!m_statMap.contains(statUrl.toDisplayString())) { + qCDebug(OBEXFTP) << "Stat: " << statUrl.toDisplayString() << entry.stringValue(KIO::UDSEntry::UDS_NAME) << entry.numberValue(KIO::UDSEntry::UDS_SIZE); + m_statMap.insert(statUrl.toDisplayString(), entry); + } + } + +- qCDebug(OBEXFTP) << "Finished"; ++ *ok = true; ++ return list; + } + +-KIO::UDSEntry KioFtp::entryFromInfo(const QVariantMap& info) ++bool KioFtp::changeFolder(const QString &folder) + { +- qCDebug(OBEXFTP) << info; ++ QDBusPendingReply<> reply = m_transfer->ChangeFolder(folder); ++ reply.waitForFinished(); ++ ++ if (reply.isError()) { ++ error(KIO::ERR_CANNOT_ENTER_DIRECTORY, folder); ++ return false; ++ } ++ return true; ++} + +- KIO::UDSEntry entry; +- entry.insert(KIO::UDSEntry::UDS_NAME, info[QStringLiteral("Name")].toString()); +- entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, info[QStringLiteral("Created")].toString()); +- entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700); +- entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, info[QStringLiteral("Modified")].toString()); ++bool KioFtp::createFolder(const QString &folder) ++{ ++ QDBusPendingReply<> reply = m_transfer->CreateFolder(folder); ++ reply.waitForFinished(); + +- if (info[QStringLiteral("Type")].toString() == QLatin1String("folder")) { +- entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); +- entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); +- } else { +- entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); +- entry.insert(KIO::UDSEntry::UDS_SIZE, info[QStringLiteral("Size")].toLongLong()); ++ if (reply.isError()) { ++ error(KIO::ERR_COULD_NOT_MKDIR, folder); ++ return false; + } ++ return true; ++} + +- return entry; ++bool KioFtp::copyFile(const QString &src, const QString &dest) ++{ ++ QDBusPendingReply<> reply = m_transfer->CopyFile(src, dest); ++ reply.waitForFinished(); ++ ++ if (reply.isError()) { ++ qCDebug(OBEXFTP) << reply.error().message(); ++ // Copying files within obexftp is currently not implemented in obexd ++ if (reply.error().message() == QLatin1String("Not Implemented")) { ++ error(KIO::ERR_UNSUPPORTED_ACTION, src); ++ } else { ++ error(KIO::ERR_COULD_NOT_WRITE, src); ++ } ++ return false; ++ } ++ return true; ++} ++ ++bool KioFtp::deleteFile(const QString &file) ++{ ++ QDBusPendingReply<> reply = m_transfer->Delete(file); ++ reply.waitForFinished(); ++ ++ if (reply.isError()) { ++ error(KIO::ERR_CANNOT_DELETE, file); ++ return false; ++ } ++ return true; ++} ++ ++void KioFtp::updateRootEntryIcon(KIO::UDSEntry &entry, const QString &memoryType) ++{ ++ const QString &path = entry.stringValue(KIO::UDSEntry::UDS_NAME); ++ ++ // Nokia (mount-points are C: D: E: ...) ++ if (path.size() == 2 && path.at(1) == QLatin1Char(':')) { ++ if (memoryType.startsWith(QLatin1String("DEV"))) { ++ entry.insert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("drive-removable-media")); ++ } else if (memoryType == QLatin1String("MMC")) { ++ entry.insert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("media-flash-sd-mmc")); ++ } ++ } ++ // Android ++ if (entry.stringValue(KIO::UDSEntry::UDS_NAME) == QLatin1String("PHONE_MEMORY")) { ++ entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, i18n("Phone memory")); ++ entry.insert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("smartphone")); ++ } else if (entry.stringValue(KIO::UDSEntry::UDS_NAME) == QLatin1String("EXTERNAL_MEMORY")) { ++ entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, i18n("External memory")); ++ entry.insert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("media-flash-sd-mmc")); ++ } + } +diff --git a/src/kio/obexftp/kio_obexftp.h b/src/kio/obexftp/kio_obexftp.h +index 3215fda..eefda10 100644 +--- a/src/kio/obexftp/kio_obexftp.h ++++ b/src/kio/obexftp/kio_obexftp.h +@@ -29,6 +29,8 @@ + + #include + ++typedef QMap DeviceInfo; ++ + class OrgBluezObexFileTransfer1Interface; + class KioFtp + : public QObject +@@ -49,26 +51,39 @@ public: + virtual void rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags); + virtual void get(const QUrl& url); + ++ bool cancelTransfer(const QString &transfer); ++ + private Q_SLOTS: + void updateProcess(); + +- KIO::UDSEntry entryFromInfo(const QVariantMap &info); ++private: + void copyHelper(const QUrl &src, const QUrl &dest); ++ void copyWithinObexftp(const QUrl &src, const QUrl &dest); + void copyFromObexftp(const QUrl &src, const QUrl &dest); + void copyToObexftp(const QUrl &src, const QUrl &dest); + void statHelper(const QUrl &url); ++ ++ QList listFolder(const QUrl &url, bool *ok); ++ bool changeFolder(const QString &folder); ++ bool createFolder(const QString &folder); ++ bool copyFile(const QString &src, const QString &dest); ++ bool deleteFile(const QString &file); ++ ++ void updateRootEntryIcon(KIO::UDSEntry &entry, const QString &memoryType); + void launchProgressBar(); ++ void connectToHost(); ++ bool testConnection(); ++ bool createSession(const QString &target); + + private: +- int m_counter; +- bool m_settingHost; ++ int m_counter; + QMap m_statMap; +- QString m_address; +- QString m_sessionPath; +- QTimer *m_timer; +- org::kde::ObexFtp *m_kded; ++ QString m_host; ++ QString m_uuids; ++ QString m_sessionPath; ++ QTimer *m_timer; ++ org::kde::ObexFtp *m_kded; + OrgBluezObexFileTransfer1Interface *m_transfer; +- + }; + + #endif // KIO_OBEXFTP_H +diff --git a/src/kio/obexftp/transferfilejob.cpp b/src/kio/obexftp/transferfilejob.cpp +index b6267e3..9a06534 100644 +--- a/src/kio/obexftp/transferfilejob.cpp ++++ b/src/kio/obexftp/transferfilejob.cpp +@@ -35,7 +35,6 @@ TransferFileJob::TransferFileJob(const QString& path, KioFtp* parent) + , m_speedBytes(0) + , m_parent(parent) + { +- + } + + TransferFileJob::~TransferFileJob() +@@ -51,16 +50,7 @@ void TransferFileJob::start() + + bool TransferFileJob::doKill() + { +- QDBusPendingReply reply = m_transfer->Cancel(); +- reply.waitForFinished(); +- +- return !reply.isError(); +-} +- +-void TransferFileJob::setSize(int size) +-{ +- qCDebug(OBEXFTP) << size; +- m_parent->totalSize(size); ++ return m_parent->cancelTransfer(m_path); + } + + void TransferFileJob::createObjects() +@@ -98,7 +88,6 @@ void TransferFileJob::statusChanged(const QVariant& value) + m_time = QTime::currentTime(); + return; + } else if (status == QLatin1String("complete")) { +- m_parent->finished(); + emitResult(); + return; + } else if (status == QLatin1String("error")) { +@@ -115,7 +104,7 @@ void TransferFileJob::transferChanged(const QVariant& value) + qCDebug(OBEXFTP) << "Transferred: " << value; + if (m_parent->wasKilled()) { + qCDebug(OBEXFTP) << "Kio was killed, aborting task"; +- m_transfer->Cancel().waitForFinished(); ++ doKill(); + emitResult(); + return; + } +diff --git a/src/kio/obexftp/transferfilejob.h b/src/kio/obexftp/transferfilejob.h +index d82cd30..d594359 100644 +--- a/src/kio/obexftp/transferfilejob.h ++++ b/src/kio/obexftp/transferfilejob.h +@@ -39,7 +39,6 @@ public: + + virtual ~TransferFileJob(); + +- void setSize(int size); + private Q_SLOTS: + void createObjects(); + void propertiesChanged(const QString &interface , const QVariantMap &properties , const QStringList &invalidProps); +@@ -56,4 +55,4 @@ private: + + }; + +-#endif //KIO_GET_FILE_JOB_H +\ No newline at end of file ++#endif //KIO_GET_FILE_JOB_H +diff --git a/src/monolithic/bluedevil-monolithic.desktop b/src/monolithic/bluedevil-monolithic.desktop +index 3911e87..f69c51d 100644 +--- a/src/monolithic/bluedevil-monolithic.desktop ++++ b/src/monolithic/bluedevil-monolithic.desktop +@@ -2,14 +2,22 @@ + Type=Application + Version=1.0 + Name=BlueDevil ++Name[bs]=BlueDevil + Name[ca]=BlueDevil + Name[cs]=BlueDevil + Name[de]=BlueDevil ++Name[el]=BlueDevil + Name[en_GB]=BlueDevil + Name[es]=BlueDevil + Name[fi]=BlueDevil + Name[fr]=BlueDevil + Name[it]=BlueDevil ++Name[ja]=BlueDevil ++Name[kk]=BlueDevil ++Name[km]=BlueDevil ++Name[ko]=BlueDevil ++Name[lt]=BlueDevil ++Name[mr]=ब्लु-डेव्हिल + Name[nb]=BlueDevil + Name[nl]=BlueDevil + Name[pl]=BlueDevil +@@ -22,20 +30,31 @@ Name[sr@ijekavian]=Блудевил + Name[sr@ijekavianlatin]=BlueDevil + Name[sr@latin]=BlueDevil + Name[sv]=Blådjävul ++Name[tr]=BlueDevil + Name[uk]=BlueDevil + Name[x-test]=xxBlueDevilxx + Name[zh_CN]=BlueDevil ++Name[zh_TW]=BlueDevil + GenericName=BlueDevil ++GenericName[bs]=BlueDevil + GenericName[ca]=BlueDevil + GenericName[cs]=BlueDevil + GenericName[de]=BlueDevil ++GenericName[el]=BlueDevil + GenericName[en_GB]=BlueDevil + GenericName[es]=BlueDevil + GenericName[fi]=BlueDevil + GenericName[fr]=BlueDevil + GenericName[it]=BlueDevil ++GenericName[ja]=BlueDevil ++GenericName[kk]=BlueDevil ++GenericName[km]=BlueDevil ++GenericName[ko]=BlueDevil ++GenericName[lt]=BlueDevil ++GenericName[mr]=ब्लु-डेव्हिल + GenericName[nb]=BlueDevil + GenericName[nl]=BlueDevil ++GenericName[pa]=BlueDevil + GenericName[pl]=BlueDevil + GenericName[pt]=BlueDevil + GenericName[pt_BR]=BlueDevil +@@ -46,21 +65,32 @@ GenericName[sr@ijekavian]=Блудевил + GenericName[sr@ijekavianlatin]=BlueDevil + GenericName[sr@latin]=BlueDevil + GenericName[sv]=Blådjävul ++GenericName[tr]=BlueDevil + GenericName[uk]=BlueDevil + GenericName[x-test]=xxBlueDevilxx + GenericName[zh_CN]=BlueDevil ++GenericName[zh_TW]=BlueDevil + Exec=bluedevil-monolithic + Comment=KDE Bluetooth support ++Comment[bs]=Podrška blututa u KDE‑u + Comment[ca]=Implementació Bluetooth del KDE + Comment[cs]=Podpora Bluetooth v KDE + Comment[de]=KDE-Bluetooth-Unterstützung ++Comment[el]=Υποστήριξη Bluetooth στο KDE + Comment[en_GB]=KDE Bluetooth support + Comment[es]=Implementación Bluetooth para KDE + Comment[fi]=KDE:n Bluetooth-tuki + Comment[fr]=Prise en charge de Bluetooth pour KDE + Comment[it]=Supporto Bluetooth per KDE ++Comment[ja]=KDE Bluetooth サポート ++Comment[kk]=KDE Bluetooth қолдауы ++Comment[km]=គាំទ្រ​ប៊្លូធូស​របស់​ KDE ++Comment[ko]=KDE 블루투스 지원 ++Comment[lt]=KDE Bluetooth palaikymas ++Comment[mr]=केडीई ब्लूटूथ समर्थन + Comment[nb]=KDE Blåtann-støtte + Comment[nl]=KDE Bluetooth ondersteuning ++Comment[pa]=KDE ਬਲਿਊਟੁੱਥ ਸਹਿਯੋਗ + Comment[pl]=Obsługa Bluetooth w KDE + Comment[pt]=Suporte para Bluetooth no KDE + Comment[pt_BR]=Suporte para Bluetooth do KDE +@@ -71,9 +101,11 @@ Comment[sr@ijekavian]=Подршка блутута у КДЕ‑у + Comment[sr@ijekavianlatin]=Podrška Bluetootha u KDE‑u + Comment[sr@latin]=Podrška Bluetootha u KDE‑u + Comment[sv]=KDE:s Blåtandstöd ++Comment[tr]=KDE Bluetooth desteği + Comment[uk]=Підтримка Bluetooth у KDE + Comment[x-test]=xxKDE Bluetooth supportxx + Comment[zh_CN]=KDE 蓝牙支持 ++Comment[zh_TW]=KDE 藍牙支援 + Icon=preferences-system-bluetooth + Terminal=false + Categories=Qt;KDE;X-Bluetooth;Network; +diff --git a/src/monolithic/monolithic.cpp b/src/monolithic/monolithic.cpp +index 5480752..fb6a23c 100644 +--- a/src/monolithic/monolithic.cpp ++++ b/src/monolithic/monolithic.cpp +@@ -47,7 +47,7 @@ Monolithic::Monolithic(QObject* parent) + + offlineMode(); + +- if (!Manager::self()->adapters().isEmpty()) { ++ if (Manager::self()->usableAdapter()) { + onlineMode(); + } + +@@ -58,7 +58,6 @@ Monolithic::Monolithic(QObject* parent) + setStandardActionsEnabled(false); + setAssociatedWidget(contextMenu()); + +- setStatus(KStatusNotifierItem::Active); + poweredChanged(); + } + +@@ -175,9 +174,11 @@ void Monolithic::regenerateDeviceEntries() + //Shortcut configuration actions, mainly checkables for discovering and powering + menu->addSeparator(); + ++ Adapter *usableAdapter = Manager::self()->usableAdapter(); ++ + QAction *discoverable = new QAction(i18n("Discoverable"), menu); + discoverable->setCheckable(true); +- discoverable->setChecked(Manager::self()->usableAdapter()->isDiscoverable()); ++ discoverable->setChecked(usableAdapter && usableAdapter->isDiscoverable()); + connect(discoverable, SIGNAL(toggled(bool)), this, SLOT(activeDiscoverable(bool))); + menu->addAction(discoverable); + +@@ -219,6 +220,8 @@ void Monolithic::setupDevice(Device *device) + + void Monolithic::onlineMode() + { ++ setStatus(Active); ++ + QList adapters = Manager::self()->adapters(); + Q_FOREACH(Adapter *adapter, adapters) { + connect(adapter, SIGNAL(deviceFound(Device*)), SLOT(deviceCreated(Device*))); +@@ -350,6 +353,7 @@ void Monolithic::deviceCreated(Device *device) + + void Monolithic::offlineMode() + { ++ setStatus(Passive); + setTooltipTitleStatus(false); + + QMenu *const menu = contextMenu(); +diff --git a/src/sendfile/bluedevil-sendfile.desktop b/src/sendfile/bluedevil-sendfile.desktop +index 4e7169e..d1cbd29 100644 +--- a/src/sendfile/bluedevil-sendfile.desktop ++++ b/src/sendfile/bluedevil-sendfile.desktop +@@ -2,9 +2,11 @@ + Type=Application + Version=1.0 + Name=BlueDevil Send File ++Name[bs]=Bludevilovo slanje datoteke + Name[ca]=Envia fitxer amb BlueDevil + Name[cs]=Posílání souborů BlueDevil + Name[de]=BlueDevil-Dateiversand ++Name[el]=Αποστολή αρχείου μέσω BlueDevil + Name[en_GB]=BlueDevil Send File + Name[es]=Enviar archivo con BlueDevil + Name[fi]=BlueDevil-tiedostonlähetys +@@ -22,13 +24,17 @@ Name[sr@ijekavian]=Блудевилово слање фајла + Name[sr@ijekavianlatin]=BlueDevilovo slanje fajla + Name[sr@latin]=BlueDevilovo slanje fajla + Name[sv]=Blådjävul skicka fil ++Name[tr]=BlueDevil Dosya Gönder + Name[uk]=Надсилання файла BlueDevil + Name[x-test]=xxBlueDevil Send Filexx + Name[zh_CN]=BlueDevil 发送文件 ++Name[zh_TW]=BlueDevil 傳送檔案 + GenericName=BlueDevil Send File ++GenericName[bs]=Bludevilovo slanje datoteke + GenericName[ca]=Envia fitxers amb BlueDevil + GenericName[cs]=Posílání souborů BlueDevil + GenericName[de]=BlueDevil-Dateiversand ++GenericName[el]=Αποστολή αρχείου μέσω BlueDevil + GenericName[en_GB]=BlueDevil Send File + GenericName[es]=Enviar archivo con BlueDevil + GenericName[fi]=BlueDevil-tiedostonlähetys +@@ -46,15 +52,19 @@ GenericName[sr@ijekavian]=Блудевилово слање фајла + GenericName[sr@ijekavianlatin]=BlueDevilovo slanje fajla + GenericName[sr@latin]=BlueDevilovo slanje fajla + GenericName[sv]=Blådjävul skicka fil ++GenericName[tr]=BlueDevil Dosya Gönder + GenericName[uk]=Надсилання файла BlueDevil + GenericName[x-test]=xxBlueDevil Send Filexx + GenericName[zh_CN]=BlueDevil 发送文件 ++GenericName[zh_TW]=BlueDevil 傳送檔案 + MimeType=application/vnd.kde.bluedevil-sendfile; + Exec=bluedevil-sendfile -k%U + Comment=BlueDevil Send File ++Comment[bs]=Bludevilovo slanje datoteke + Comment[ca]=Envia fitxers amb BlueDevil + Comment[cs]=Posílání souborů BlueDevil + Comment[de]=BlueDevil-Dateiversand ++Comment[el]=Αποστολή αρχείου μέσω BlueDevil + Comment[en_GB]=BlueDevil Send File + Comment[es]=Enviar archivo con BlueDevil + Comment[fi]=BlueDevil-tiedostonlähetys +@@ -72,9 +82,11 @@ Comment[sr@ijekavian]=Блудевилово слање фајла + Comment[sr@ijekavianlatin]=BlueDevilovo slanje fajla + Comment[sr@latin]=BlueDevilovo slanje fajla + Comment[sv]=Blådjävul skicka fil ++Comment[tr]=BlueDevil Dosya Gönder + Comment[uk]=Надсилання файла BlueDevil + Comment[x-test]=xxBlueDevil Send Filexx + Comment[zh_CN]=BlueDevil 发送文件 ++Comment[zh_TW]=BlueDevil 傳送檔案 + Icon=preferences-system-bluetooth + Terminal=false + Categories=Qt;KDE;X-Bluetooth;Network; +diff --git a/src/settings/filereceiver.kcfg b/src/settings/filereceiver.kcfg +index 5740f9a..a2e6521 100644 +--- a/src/settings/filereceiver.kcfg ++++ b/src/settings/filereceiver.kcfg +@@ -3,14 +3,9 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > +- + +- QFile +- QDir +- QStandardPaths +- KIO/Global + +- ++ + + + +@@ -18,7 +13,7 @@ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + + + +- QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)) ++ QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) + + + +diff --git a/src/wizard/CMakeLists.txt b/src/wizard/CMakeLists.txt +index d615f3d..491612e 100644 +--- a/src/wizard/CMakeLists.txt ++++ b/src/wizard/CMakeLists.txt +@@ -11,6 +11,7 @@ set(wizard_SRCS + pages/keyboardpairing.cpp + pages/ssppairing.cpp + pages/fail.cpp ++ pages/success.cpp + ) + + ki18n_wrap_ui(wizard_SRCS +@@ -20,6 +21,7 @@ ki18n_wrap_ui(wizard_SRCS + pages/keyboardpairing.ui + pages/ssppairing.ui + pages/fail.ui ++ pages/success.ui + ) + + add_executable(bluedevil-wizard ${wizard_SRCS}) +diff --git a/src/wizard/bluedevil-wizard.desktop b/src/wizard/bluedevil-wizard.desktop +index c349f89..0779901 100644 +--- a/src/wizard/bluedevil-wizard.desktop ++++ b/src/wizard/bluedevil-wizard.desktop +@@ -2,16 +2,25 @@ + Type=Application + Version=1.0 + Name=BlueDevil Wizard ++Name[bs]=Bludevilov čarobnjak + Name[ca]=Assistent del BlueDevil + Name[cs]=Průvodce Bluedevil + Name[de]=BlueDevil-Assistent ++Name[el]=Οδηγός BlueDevil + Name[en_GB]=BlueDevil Wizard + Name[es]=Asistente de BlueDevil + Name[fi]=Opastettu BlueDevil-toiminto + Name[fr]=Assistant pour BlueDevil + Name[it]=Procedura guidata di BlueDevil ++Name[ja]=BlueDevil ウィザード ++Name[kk]=BlueDevil шебері ++Name[km]=អ្នក​ជំនួយការ BlueDevil ++Name[ko]=BlueDevil 마법사 ++Name[lt]=BlueDevil vedlys ++Name[mr]=ब्लु-डेव्हिल विझार्ड + Name[nb]=BlueDevil veiviser + Name[nl]=BlueDevil assistent ++Name[pa]=BlueDevil ਸਹਾਇਕ + Name[pl]=Pomocnik BlueDevil + Name[pt]=Assistente BlueDevil + Name[pt_BR]=Assistente BlueDevil +@@ -22,20 +31,31 @@ Name[sr@ijekavian]=Блудевилов чаробњак + Name[sr@ijekavianlatin]=BlueDevilov čarobnjak + Name[sr@latin]=BlueDevilov čarobnjak + Name[sv]=Blådjävul guide ++Name[tr]=BlueDevil Sihirbazı + Name[uk]=Майстер BlueDevil + Name[x-test]=xxBlueDevil Wizardxx + Name[zh_CN]=BlueDevil 向导 ++Name[zh_TW]=BlueDevil 精靈 + GenericName=BlueDevil Wizard ++GenericName[bs]=Bludevilov čarobnjak + GenericName[ca]=Assistent del BlueDevil + GenericName[cs]=Průvodce Bluedevil + GenericName[de]=BlueDevil-Assistent ++GenericName[el]=Οδηγός BlueDevil + GenericName[en_GB]=BlueDevil Wizard + GenericName[es]=Asistente de BlueDevil + GenericName[fi]=Opastettu BlueDevil-toiminto + GenericName[fr]=Assistant pour BlueDevil + GenericName[it]=Procedura guidata di BlueDevil ++GenericName[ja]=BlueDevil ウィザード ++GenericName[kk]=BlueDevil шебері ++GenericName[km]=អ្នកជំនួយការ​ BlueDevil ++GenericName[ko]=BlueDevil 마법사 ++GenericName[lt]=BlueDevil vedlys ++GenericName[mr]=ब्लु-डेव्हिल विझार्ड + GenericName[nb]=BlueDevil veiviser + GenericName[nl]=BlueDevil assistent ++GenericName[pa]=BlueDevil ਸਹਾਇਕ + GenericName[pl]=Pomocnik BlueDevil + GenericName[pt]=Assistente BlueDevil + GenericName[pt_BR]=Assistente BlueDevil +@@ -46,21 +66,32 @@ GenericName[sr@ijekavian]=Блудевилов чаробњак + GenericName[sr@ijekavianlatin]=BlueDevilov čarobnjak + GenericName[sr@latin]=BlueDevilov čarobnjak + GenericName[sv]=Blådjävul guide ++GenericName[tr]=BlueDevil Sihirbazı + GenericName[uk]=Майстер BlueDevil + GenericName[x-test]=xxBlueDevil Wizardxx + GenericName[zh_CN]=BlueDevil 向导 ++GenericName[zh_TW]=BlueDevil 精靈 + Exec=bluedevil-wizard %U + Comment=BlueDevil Wizard ++Comment[bs]=Bludevilov čarobnjak + Comment[ca]=Assistent del BlueDevil + Comment[cs]=BlueDevil + Comment[de]=BlueDevil-Assistent ++Comment[el]=Οδηγός BlueDevil + Comment[en_GB]=BlueDevil Wizard + Comment[es]=Asistente de BlueDevil + Comment[fi]=Opastettu BlueDevil-toiminto + Comment[fr]=Assistant pour BlueDevil + Comment[it]=Procedura guidata di BlueDevil ++Comment[ja]=BlueDevil ウィザード ++Comment[kk]=BlueDevil шебері ++Comment[km]=អ្នក​ជំនួយការ​ BlueDevil ++Comment[ko]=BlueDevil 마법사 ++Comment[lt]=BlueDevil vedlys ++Comment[mr]=ब्लु-डेव्हिल विझार्ड + Comment[nb]=BlueDevil veiviser + Comment[nl]=BlueDevil assistent ++Comment[pa]=BlueDevil ਸਹਾਇਕ + Comment[pl]=Pomocnik BlueDevil + Comment[pt]=Assistente BlueDevil + Comment[pt_BR]=Assistente BlueDevil +@@ -71,9 +102,11 @@ Comment[sr@ijekavian]=Блудевилов чаробњак + Comment[sr@ijekavianlatin]=BlueDevilov čarobnjak + Comment[sr@latin]=BlueDevilov čarobnjak + Comment[sv]=Blådjävul guide ++Comment[tr]=BlueDevil Sihirbazı + Comment[uk]=Майстер BlueDevil + Comment[x-test]=xxBlueDevil Wizardxx + Comment[zh_CN]=BlueDevil 向导 ++Comment[zh_TW]=BlueDevil 精靈 + Icon=preferences-system-bluetooth + Terminal=false + Categories=Qt;KDE;X-Bluetooth;Network; +diff --git a/src/wizard/bluewizard.cpp b/src/wizard/bluewizard.cpp +index 02f54b7..cd1fe3d 100644 +--- a/src/wizard/bluewizard.cpp ++++ b/src/wizard/bluewizard.cpp +@@ -23,6 +23,7 @@ + #include "pages/legacypairingdatabase.h" + #include "pages/keyboardpairing.h" + #include "pages/ssppairing.h" ++#include "pages/success.h" + #include "pages/fail.h" + #include "debug_p.h" + +@@ -61,6 +62,7 @@ BlueWizard::BlueWizard(const QUrl &url) + setPage(LegacyPairingDatabase, new LegacyPairingPageDatabase(this)); + setPage(KeyboardPairing, new KeyboardPairingPage(this)); + setPage(SSPPairing, new SSPPairingPage(this)); ++ setPage(Success, new SuccessPage(this)); + setPage(Fail, new FailPage(this)); + + QPushButton *backButton = new QPushButton(this); +diff --git a/src/wizard/bluewizard.h b/src/wizard/bluewizard.h +index ce817d1..d995fb8 100644 +--- a/src/wizard/bluewizard.h ++++ b/src/wizard/bluewizard.h +@@ -51,7 +51,7 @@ public: + + WizardAgent* agent() const; + +- enum {Discover, NoPairing, LegacyPairing, LegacyPairingDatabase, KeyboardPairing, SSPPairing, Fail, Connect}; ++ enum {Discover, NoPairing, LegacyPairing, LegacyPairingDatabase, KeyboardPairing, SSPPairing, Success, Fail, Connect}; + + public Q_SLOTS: + void restartWizard(); +diff --git a/src/wizard/pages/discover.ui b/src/wizard/pages/discover.ui +index c43f080..aec410d 100644 +--- a/src/wizard/pages/discover.ui ++++ b/src/wizard/pages/discover.ui +@@ -114,9 +114,6 @@ + 40 + + +- +- 999999999; +- + + false + +diff --git a/src/wizard/pages/discoverpage.cpp b/src/wizard/pages/discoverpage.cpp +index de3f10e..35cc186 100644 +--- a/src/wizard/pages/discoverpage.cpp ++++ b/src/wizard/pages/discoverpage.cpp +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -64,6 +65,10 @@ void DiscoverPage::initializePage() + list << QWizard::CancelButton; + m_wizard->setButtonLayout(list); + ++ QRegExp rx("[0-9]{0,9}"); ++ QRegExpValidator *validator = new QRegExpValidator(rx); ++ pinText->setValidator(validator); ++ + connect(Manager::self()->usableAdapter(), SIGNAL(unpairedDeviceFound(Device*)), this, + SLOT(deviceFound(Device*))); + connect(manualPin, SIGNAL(toggled(bool)), pinText, SLOT(setEnabled(bool))); +@@ -76,7 +81,7 @@ void DiscoverPage::initializePage() + + bool DiscoverPage::isComplete() const + { +- if (m_wizard->deviceAddress().isEmpty()) { ++ if (m_wizard->deviceAddress().isEmpty() || !m_wizard->device()) { + return false; + } + if (manualPin->isChecked() && pinText->text().isEmpty()) { +@@ -193,7 +198,7 @@ int DiscoverPage::nextId() const + return BlueWizard::Discover; + } + +- if (m_wizard->deviceAddress().isEmpty()) { ++ if (m_wizard->deviceAddress().isEmpty() || !m_wizard->device()) { + return BlueWizard::Discover; + } + +diff --git a/src/wizard/pages/fail.cpp b/src/wizard/pages/fail.cpp +index 422920f..b9a6119 100644 +--- a/src/wizard/pages/fail.cpp ++++ b/src/wizard/pages/fail.cpp +@@ -40,6 +40,8 @@ FailPage::FailPage(BlueWizard* parent) + , m_wizard(parent) + { + setupUi(this); ++ ++ failIcon->setPixmap(QIcon::fromTheme(QStringLiteral("task-reject")).pixmap(48)); + } + + void FailPage::initializePage() +diff --git a/src/wizard/pages/fail.ui b/src/wizard/pages/fail.ui +index 0470e8f..375a4fb 100644 +--- a/src/wizard/pages/fail.ui ++++ b/src/wizard/pages/fail.ui +@@ -30,6 +30,16 @@ + + + ++ ++ ++ ++ 48 ++ 48 ++ ++ ++ ++ ++ + + + +diff --git a/src/wizard/pages/nopairing.cpp b/src/wizard/pages/nopairing.cpp +index c0410e1..522cae9 100644 +--- a/src/wizard/pages/nopairing.cpp ++++ b/src/wizard/pages/nopairing.cpp +@@ -35,9 +35,10 @@ + + using namespace BlueDevil; + +-NoPairingPage::NoPairingPage(BlueWizard* parent) : QWizardPage(parent) +-, m_validPage(false) +-, m_wizard(parent) ++NoPairingPage::NoPairingPage(BlueWizard *parent) ++ : QWizardPage(parent) ++ , m_success(false) ++ , m_wizard(parent) + { + setupUi(this); + m_working = new KPixmapSequenceOverlayPainter(this); +@@ -46,6 +47,14 @@ NoPairingPage::NoPairingPage(BlueWizard* parent) : QWizardPage(parent) + m_working->start(); + } + ++int NoPairingPage::nextId() const ++{ ++ if (m_success) { ++ return BlueWizard::Success; ++ } ++ return BlueWizard::Fail; ++} ++ + void NoPairingPage::initializePage() + { + qCDebug(WIZARD); +@@ -53,10 +62,6 @@ void NoPairingPage::initializePage() + + connecting->setText(connecting->text().append(m_wizard->device()->name())); + +- //It can happen that the device is technically connected and trusted but we are not connected +- //to the profile. We have no way to know if the profile was activated or not so we have to relay +- //on a timeout (10s) +- QTimer::singleShot(10000, this, SLOT(timeout())); + connect(m_wizard->device(), SIGNAL(connectedChanged(bool)), SLOT(connectedChanged(bool))); + connect(m_wizard->device(), SIGNAL(trustedChanged(bool)), SLOT(connectedChanged(bool))); + +@@ -64,30 +69,14 @@ void NoPairingPage::initializePage() + m_wizard->device()->setTrusted(true); + } + +-void NoPairingPage::timeout() +-{ +- connectedChanged(true); +-} +- + void NoPairingPage::connectedChanged(bool connected) + { +- qCDebug(WIZARD); +- +- m_validPage = connected; +- if (m_validPage) { +- qCDebug(WIZARD) << "Done"; +- m_wizard->done(0); +- } +-} +- +-bool NoPairingPage::validatePage() +-{ +- return m_validPage; +-} ++ qCDebug(WIZARD) << "Connect finished" << connected; + +-int NoPairingPage::nextId() const +-{ +- return -1; ++ // Connect may fail but that doesn't really mean the device was setup incorrectly ++ // Device::connectDevice will fail eg. when A2DP profile could not be connected due to missing pulseaudio plugin ++ m_success = true; ++ QTimer::singleShot(500, m_wizard, SLOT(next())); + } + + QList NoPairingPage::wizardButtonsLayout() const +@@ -95,6 +84,5 @@ QList NoPairingPage::wizardButtonsLayout() const + QList list; + list << QWizard::Stretch; + list << QWizard::CancelButton; +- + return list; + } +diff --git a/src/wizard/pages/nopairing.h b/src/wizard/pages/nopairing.h +index 26f1441..9fd167d 100644 +--- a/src/wizard/pages/nopairing.h ++++ b/src/wizard/pages/nopairing.h +@@ -44,20 +44,18 @@ Q_OBJECT + public: + NoPairingPage(BlueWizard* parent = 0); + +- virtual void initializePage(); +- virtual bool validatePage(); + virtual int nextId() const; ++ virtual void initializePage(); + + protected: + QList wizardButtonsLayout() const; + + private Q_SLOTS: +- void timeout(); + void connectedChanged(bool connected); + + private: +- bool m_validPage; +- BlueWizard *m_wizard; ++ bool m_success; ++ BlueWizard *m_wizard; + KPixmapSequenceOverlayPainter *m_working; + }; + +diff --git a/src/wizard/pages/ssppairing.cpp b/src/wizard/pages/ssppairing.cpp +index 963bdaa..14f5e09 100644 +--- a/src/wizard/pages/ssppairing.cpp ++++ b/src/wizard/pages/ssppairing.cpp +@@ -77,6 +77,7 @@ void SSPPairingPage::initializePage() + void SSPPairingPage::confirmationRequested(quint32 passkey, const QDBusMessage& msg) + { + m_msg = msg; ++ m_msg.setDelayedReply(true); + + QPushButton *matches = new QPushButton(this); + KGuiItem::assign(matches, KStandardGuiItem::apply()); +@@ -129,6 +130,7 @@ void SSPPairingPage::matchesClicked() + void SSPPairingPage::notMatchClicked() + { + m_buttonClicked = QWizard::CustomButton2; ++ QDBusConnection::systemBus().send(m_msg.createErrorReply("org.bluez.Rejected", "Rejected")); + + wizard()->next(); + } +diff --git a/src/wizard/pages/success.cpp b/src/wizard/pages/success.cpp +new file mode 100644 +index 0000000..f49bb7f +--- /dev/null ++++ b/src/wizard/pages/success.cpp +@@ -0,0 +1,66 @@ ++/***************************************************************************** ++ * This file is part of the KDE project * ++ * * ++ * Copyright (C) 2010 Alejandro Fiestas Olivares * ++ * Copyright (C) 2010-2011 UFO Coders * ++ * Copyright (C) 2014 David Rosca * ++ * * ++ * This library is free software; you can redistribute it and/or * ++ * modify it under the terms of the GNU Library General Public * ++ * License as published by the Free Software Foundation; either * ++ * version 2 of the License, or (at your option) any later version. * ++ * * ++ * This library 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 * ++ * Library General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU Library General Public License * ++ * along with this library; see the file COPYING.LIB. If not, write to * ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * ++ * Boston, MA 02110-1301, USA. * ++ *****************************************************************************/ ++ ++#include "success.h" ++#include "bluewizard.h" ++#include "debug_p.h" ++ ++#include ++ ++#include ++ ++#include ++ ++SuccessPage::SuccessPage(BlueWizard *parent) ++ : QWizardPage(parent) ++ , m_wizard(parent) ++{ ++ setupUi(this); ++ ++ successIcon->setPixmap(QIcon::fromTheme(QStringLiteral("task-complete")).pixmap(48)); ++} ++ ++void SuccessPage::initializePage() ++{ ++ qCDebug(WIZARD) << "Initialize Success Page"; ++ ++ QList list; ++ list << QWizard::Stretch; ++ list << QWizard::FinishButton; ++ ++ m_wizard->setButtonLayout(list); ++ ++ setFinalPage(true); ++ ++ QString deviceName = m_wizard->device()->name(); ++ if (deviceName.isEmpty()) { ++ successLbl->setText(i18nc("This string is shown when the wizard succeeds", "The setup of the device has succeeded")); ++ } else { ++ successLbl->setText(i18n("The setup of %1 has succeeded", deviceName)); ++ } ++} ++ ++int SuccessPage::nextId() const ++{ ++ return -1; ++} +diff --git a/src/wizard/pages/success.h b/src/wizard/pages/success.h +new file mode 100644 +index 0000000..a41f73e +--- /dev/null ++++ b/src/wizard/pages/success.h +@@ -0,0 +1,46 @@ ++/***************************************************************************** ++ * This file is part of the KDE project * ++ * * ++ * Copyright (C) 2010 Alejandro Fiestas Olivares * ++ * Copyright (C) 2010-2011 UFO Coders * ++ * Copyright (C) 2014 David Rosca * ++ * * ++ * This library is free software; you can redistribute it and/or * ++ * modify it under the terms of the GNU Library General Public * ++ * License as published by the Free Software Foundation; either * ++ * version 2 of the License, or (at your option) any later version. * ++ * * ++ * This library 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 * ++ * Library General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU Library General Public License * ++ * along with this library; see the file COPYING.LIB. If not, write to * ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * ++ * Boston, MA 02110-1301, USA. * ++ *****************************************************************************/ ++ ++#ifndef SUCCESS_H ++#define SUCCESS_H ++ ++#include "ui_success.h" ++#include ++ ++class BlueWizard; ++ ++class SuccessPage : public QWizardPage, Ui::Success ++{ ++ Q_OBJECT ++ ++public: ++ SuccessPage(BlueWizard *parent = 0); ++ ++ virtual void initializePage(); ++ virtual int nextId() const; ++ ++private: ++ BlueWizard *m_wizard; ++}; ++ ++#endif // SUCCESS_H +diff --git a/src/wizard/pages/success.ui b/src/wizard/pages/success.ui +new file mode 100644 +index 0000000..3630db3 +--- /dev/null ++++ b/src/wizard/pages/success.ui +@@ -0,0 +1,68 @@ ++ ++ ++ Success ++ ++ ++ ++ 0 ++ 0 ++ 400 ++ 300 ++ ++ ++ ++ ++ ++ ++ ++ ++ Qt::Horizontal ++ ++ ++ QSizePolicy::Fixed ++ ++ ++ ++ 10 ++ 20 ++ ++ ++ ++ ++ ++ ++ ++ ++ 48 ++ 48 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Qt::Vertical ++ ++ ++ ++ 20 ++ 40 ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/wizard/pin-code-database.xml b/src/wizard/pin-code-database.xml +index 8239aa9..5e99392 100644 +--- a/src/wizard/pin-code-database.xml ++++ b/src/wizard/pin-code-database.xml +@@ -52,9 +52,9 @@ + + + +- +- +- ++ ++ ++ + +