mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-23 18:32:53 +00:00
bluedevil: pull upstream changes
This commit is contained in:
parent
18b3256542
commit
7e830bdd87
21 changed files with 585 additions and 480 deletions
|
@ -3,7 +3,7 @@ project(bluedevil)
|
|||
find_package(KDE4 REQUIRED)
|
||||
|
||||
set(CMAKE_BLUEDEVIL_VERSION_MAJOR 2)
|
||||
set(CMAKE_BLUEDEVIL_VERSION_MINOR 0)
|
||||
set(CMAKE_BLUEDEVIL_VERSION_MINOR 1)
|
||||
set(CMAKE_BLUEDEVIL_VERSION_PATCH 0)
|
||||
set(CMAKE_BLUEDEVIL_VERSION_STRING "${CMAKE_BLUEDEVIL_VERSION_MAJOR}.${CMAKE_BLUEDEVIL_VERSION_MINOR}.${CMAKE_BLUEDEVIL_VERSION_PATCH}")
|
||||
configure_file(version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <KPluginFactory>
|
||||
#include <kfileplacesmodel.h>
|
||||
#include <kdirnotify.h>
|
||||
#include <ksharedconfig.h>
|
||||
|
||||
#include <bluedevil/bluedevilmanager.h>
|
||||
#include <bluedevil/bluedeviladapter.h>
|
||||
|
@ -62,10 +63,9 @@ struct BlueDevilDaemon::Private
|
|||
Adapter *m_adapter;
|
||||
QDBusServiceWatcher *m_monolithicWatcher;
|
||||
FileReceiver *m_fileReceiver;
|
||||
QList <DeviceInfo> m_discovered;
|
||||
QTimer m_timer;
|
||||
QTimer m_timer;
|
||||
KComponentData m_componentData;
|
||||
QHash<QString, bool> m_adapterPoweredHash;
|
||||
KSharedConfig::Ptr m_config;
|
||||
};
|
||||
|
||||
BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList<QVariant>&)
|
||||
|
@ -81,8 +81,8 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList<QVariant>&)
|
|||
d->m_fileReceiver = 0;
|
||||
d->m_monolithicWatcher = new QDBusServiceWatcher("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(
|
||||
"bluedevildaemon",
|
||||
|
@ -102,10 +102,15 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList<QVariant>&)
|
|||
|
||||
aboutData.setProgramIconName("preferences-system-bluetooth");
|
||||
d->m_componentData = KComponentData(aboutData);
|
||||
connect(d->m_monolithicWatcher, SIGNAL(serviceUnregistered(const QString &)), SLOT(monolithicFinished(const QString &)));
|
||||
connect(d->m_monolithicWatcher, SIGNAL(serviceUnregistered(QString)), SLOT(monolithicFinished(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("org.freedesktop.login1",
|
||||
|
@ -117,6 +122,8 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList<QVariant>&)
|
|||
);
|
||||
|
||||
d->m_status = Private::Offline;
|
||||
|
||||
restoreAdaptersState();
|
||||
usableAdapterChanged(Manager::self()->usableAdapter());
|
||||
|
||||
if (!Manager::self()->adapters().isEmpty()) {
|
||||
|
@ -126,6 +133,8 @@ BlueDevilDaemon::BlueDevilDaemon(QObject *parent, const QList<QVariant>&)
|
|||
|
||||
BlueDevilDaemon::~BlueDevilDaemon()
|
||||
{
|
||||
saveAdaptersState();
|
||||
|
||||
if (d->m_status == Private::Online) {
|
||||
offlineMode();
|
||||
}
|
||||
|
@ -147,23 +156,10 @@ void BlueDevilDaemon::login1PrepareForSleep(bool active)
|
|||
{
|
||||
if (active) {
|
||||
kDebug(dblue()) << "About to suspend";
|
||||
d->m_adapterPoweredHash.clear();
|
||||
Q_FOREACH (Adapter *adapter, Manager::self()->adapters()) {
|
||||
kDebug(dblue()) << "Saving" << adapter->address() << adapter->isPowered();
|
||||
d->m_adapterPoweredHash.insert(adapter->address(), adapter->isPowered());
|
||||
}
|
||||
saveAdaptersState();
|
||||
} else {
|
||||
kDebug(dblue()) << "About to resume";
|
||||
QHashIterator<QString, bool> it(d->m_adapterPoweredHash);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
Adapter *adapter = adapterForAddress(it.key());
|
||||
if (adapter) {
|
||||
kDebug(dblue()) << "Restoring" << adapter->address() << it.value();
|
||||
adapter->setPowered(it.value());
|
||||
}
|
||||
}
|
||||
d->m_adapterPoweredHash.clear();
|
||||
restoreAdaptersState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,41 +171,55 @@ bool BlueDevilDaemon::isOnline()
|
|||
return true;
|
||||
}
|
||||
|
||||
QMapDeviceInfo BlueDevilDaemon::knownDevices()
|
||||
QMapDeviceInfo BlueDevilDaemon::allDevices()
|
||||
{
|
||||
QMapDeviceInfo devices;
|
||||
QList<Device*> list = Manager::self()->usableAdapter()->devices();
|
||||
|
||||
QList <Device* > list = Manager::self()->usableAdapter()->devices();
|
||||
kDebug(dblue()) << "List: " << list.length();
|
||||
DeviceInfo info;
|
||||
Q_FOREACH(Device *const device, list) {
|
||||
info["name"] = device->friendlyName();
|
||||
info["icon"] = device->icon();
|
||||
info["address"] = device->address();
|
||||
info["UUIDs"] = device->UUIDs().join(",");
|
||||
devices[device->address()] = info;
|
||||
Q_FOREACH (Device *const device, list) {
|
||||
devices[device->address()] = deviceToInfo(device);
|
||||
}
|
||||
|
||||
if (!d->m_timer.isActive()) {
|
||||
kDebug(dblue()) << "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["address"])) {
|
||||
devices[info["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;
|
||||
}
|
||||
|
||||
kDebug(dblue()) << "Start discovering for" << timeout << "ms";
|
||||
|
||||
d->m_adapter->startDiscovery();
|
||||
|
||||
if (timeout > 0) {
|
||||
d->m_timer.start(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void BlueDevilDaemon::stopDiscovering()
|
||||
{
|
||||
kDebug(dblue()) << "Stopping discovering";
|
||||
d->m_timer.stop();
|
||||
Manager::self()->usableAdapter()->stopDiscovery();
|
||||
if (!d->m_adapter) {
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug(dblue()) << "Stop discovering";
|
||||
|
||||
if (d->m_adapter->isDiscovering()) {
|
||||
d->m_adapter->stopDiscovery();
|
||||
}
|
||||
}
|
||||
|
||||
void BlueDevilDaemon::executeMonolithic()
|
||||
|
@ -246,9 +256,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()->readConfig();
|
||||
if (!d->m_fileReceiver && FileReceiverSettings::self()->enabled()) {
|
||||
|
@ -314,9 +322,6 @@ void BlueDevilDaemon::offlineMode()
|
|||
d->m_placesModel->removePlace(index);
|
||||
}
|
||||
|
||||
if (BlueDevil::Manager::self()->adapters().isEmpty()) {
|
||||
killMonolithic();
|
||||
}
|
||||
d->m_status = Private::Offline;
|
||||
}
|
||||
|
||||
|
@ -344,10 +349,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)
|
||||
{
|
||||
kDebug(dblue()) << "DeviceFound: " << device->name();
|
||||
d->m_discovered.append(deviceToInfo(device));
|
||||
org::kde::KDirNotify::emitFilesAdded("bluetooth:/");
|
||||
}
|
||||
|
||||
|
@ -361,15 +379,55 @@ void BlueDevilDaemon::monolithicQuit(QDBusPendingCallWatcher* watcher)
|
|||
}
|
||||
}
|
||||
|
||||
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<bool>(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<bool>(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<bool>(key, true));
|
||||
}
|
||||
|
||||
DeviceInfo BlueDevilDaemon::deviceToInfo(Device *const device) const
|
||||
{
|
||||
DeviceInfo info;
|
||||
info["name"] = device->friendlyName();
|
||||
info["icon"] = device->icon();
|
||||
info["address"] = device->address();
|
||||
info["discovered"] = "true";
|
||||
info["UBI"] = device->UBI();
|
||||
info["UUIDs"] = device->UUIDs().join(",");
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,16 +50,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<Address, DeviceInfo> 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:
|
||||
|
@ -82,6 +96,9 @@ 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
|
||||
*/
|
||||
|
@ -97,7 +114,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;
|
||||
|
|
|
@ -34,44 +34,45 @@
|
|||
#include <KProcess>
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <bluedevil/bluedevil.h>
|
||||
|
||||
using namespace BlueDevil;
|
||||
K_PLUGIN_FACTORY(SendFileItemActionFactory, registerPlugin<SendFileItemAction>();)
|
||||
K_EXPORT_PLUGIN(SendFileItemActionFactory("SendFileItemAction", "bluedevil"))
|
||||
|
||||
SendFileItemAction::SendFileItemAction(QObject* parent, const QVariantList& args): KFileItemActionPlugin(parent)
|
||||
SendFileItemAction::SendFileItemAction(QObject *parent, const QVariantList &args)
|
||||
: KFileItemActionPlugin(parent)
|
||||
{
|
||||
Q_UNUSED(args)
|
||||
|
||||
qDBusRegisterMetaType<DeviceInfo>();
|
||||
qDBusRegisterMetaType<QMapDeviceInfo>();
|
||||
|
||||
m_kded = new org::kde::BlueDevil("org.kde.kded", "/modules/bluedevil",
|
||||
QDBusConnection::sessionBus(), this);
|
||||
}
|
||||
|
||||
QList< QAction* > SendFileItemAction::actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) const
|
||||
QList<QAction*> SendFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) const
|
||||
{
|
||||
Q_UNUSED(parentWidget)
|
||||
QList< QAction* > list;
|
||||
|
||||
QList<QAction*> list;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
SendFileItemAction *hack = const_cast<SendFileItemAction*>(this);
|
||||
hack->m_fileItemInfos = fileItemInfos;
|
||||
|
||||
//If there is no adaptor, there is no bluetooth
|
||||
if (!Manager::self()->usableAdapter()) {
|
||||
return list;
|
||||
}
|
||||
Adapter *adapter = Manager::self()->usableAdapter();
|
||||
|
||||
QAction *menuAction = new QAction(KIcon("preferences-system-bluetooth"), i18n("Send via Bluetooth"), hack);
|
||||
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("00001105-0000-1000-8000-00805F9B34FB", Qt::CaseInsensitive)) {
|
||||
QAction *action = new QAction(KIcon(device->icon()), device->name(), hack);
|
||||
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["UUIDs"].contains("00001105-0000-1000-8000-00805F9B34FB")) {
|
||||
QAction *action = new QAction(KIcon(device["icon"]), device["name"], hack);
|
||||
connect(action, SIGNAL(triggered(bool)), this, SLOT(deviceTriggered()));
|
||||
action->setData(device["UBI"]);
|
||||
menu->addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,23 +24,26 @@
|
|||
#include <kfileitemactionplugin.h>
|
||||
#include <KFileItemListProperties>
|
||||
|
||||
#include "kded_bluedevil.h"
|
||||
|
||||
class QAction;
|
||||
class KFileItemListProperties;
|
||||
class QWidget;
|
||||
|
||||
class SendFileItemAction : public KFileItemActionPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
SendFileItemAction(QObject* parent, const QVariantList &args);
|
||||
virtual QList< QAction* > actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) const;
|
||||
virtual QList<QAction*> actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void deviceTriggered();
|
||||
void otherTriggered();
|
||||
|
||||
private:
|
||||
org::kde::BlueDevil *m_kded;
|
||||
KFileItemListProperties m_fileItemInfos;
|
||||
};
|
||||
|
||||
#endif // SENDFILEITEMACTION_H
|
||||
#endif // SENDFILEITEMACTION_H
|
||||
|
|
|
@ -61,8 +61,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;
|
||||
|
@ -118,9 +118,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->systemName(), adapter->address()));
|
||||
} else {
|
||||
setTitle(i18n("Adapter: %1 (%2)", adapter->alias(), adapter->address()));
|
||||
setTitle(i18n("Adapter: %1 (%2)", adapter->systemName(), adapter->address()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,13 +135,12 @@ bool AdapterSettings::isModified() const
|
|||
m_temporaryVisible->isChecked() != m_temporaryVisibleOrig ||
|
||||
m_discoverTime->value() != m_discoverTimeOrig || m_powered->isChecked() != m_poweredOrig;
|
||||
}
|
||||
#include <QDebug>
|
||||
|
||||
void AdapterSettings::applyChanges()
|
||||
{
|
||||
if (m_name->text() != m_nameOrig) {
|
||||
qDebug() << "Setting alias";
|
||||
m_adapter->setAlias(m_name->text());
|
||||
}
|
||||
m_adapter->setName(m_name->text());
|
||||
}
|
||||
|
||||
if (m_hidden->isChecked()) {
|
||||
m_adapter->setDiscoverable(false);
|
||||
|
@ -188,7 +187,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 +203,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->systemName(), m_adapter->address()));
|
||||
} else {
|
||||
setTitle(i18n("Adapter: %1 (%2)", m_adapter->alias(), m_adapter->address()));
|
||||
setTitle(i18n("Adapter: %1 (%2)", m_adapter->systemName(), m_adapter->address()));
|
||||
}
|
||||
|
||||
blockSignals(false);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <kcolorscheme.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <klocalizedstring.h>
|
||||
#include <kmessagewidget.h>
|
||||
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QWidget>
|
||||
|
@ -39,93 +40,12 @@
|
|||
#include <QtGui/QBoxLayout>
|
||||
#include <QtGui/QPaintEvent>
|
||||
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
#include <kmessagewidget.h>
|
||||
#else
|
||||
|
||||
class ErrorWidget
|
||||
: public QWidget
|
||||
{
|
||||
public:
|
||||
ErrorWidget(QWidget *parent = 0);
|
||||
virtual ~ErrorWidget();
|
||||
|
||||
void setIcon(const QString &icon);
|
||||
void setText(const QString &reason);
|
||||
void addAction(KPushButton *action);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
QLabel *m_icon;
|
||||
QLabel *m_reason;
|
||||
QHBoxLayout *m_actions;
|
||||
};
|
||||
|
||||
ErrorWidget::ErrorWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_icon(new QLabel(this))
|
||||
, m_reason(new QLabel(this))
|
||||
, m_actions(new QHBoxLayout)
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
|
||||
m_actions->addStretch();
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
layout->addWidget(m_icon);
|
||||
layout->addWidget(m_reason, 1);
|
||||
|
||||
QVBoxLayout *outter = new QVBoxLayout;
|
||||
outter->addLayout(layout);
|
||||
outter->addLayout(m_actions);
|
||||
|
||||
setLayout(outter);
|
||||
}
|
||||
|
||||
ErrorWidget::~ErrorWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void ErrorWidget::setIcon(const QString &icon)
|
||||
{
|
||||
m_icon->setPixmap(KIconLoader::global()->loadIcon(icon, KIconLoader::Dialog));
|
||||
}
|
||||
|
||||
void ErrorWidget::setText(const QString &reason)
|
||||
{
|
||||
m_reason->setText(reason);
|
||||
}
|
||||
|
||||
void ErrorWidget::addAction(KPushButton *action)
|
||||
{
|
||||
action->setAutoFillBackground(false);
|
||||
m_actions->addWidget(action);
|
||||
}
|
||||
|
||||
void ErrorWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
const QRect r = event->rect();
|
||||
const KColorScheme colorScheme(QPalette::Active, KColorScheme::Window);
|
||||
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(0, 0, r.width(), r.height(), 10, 10);
|
||||
p.fillPath(path, colorScheme.background(KColorScheme::NegativeBackground));
|
||||
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SystemCheck::SystemCheck(QWidget *parent)
|
||||
: QObject(parent)
|
||||
, m_kded(new KDED("org.kde.kded", "/kded", QDBusConnection::sessionBus()))
|
||||
, m_parent(parent)
|
||||
, m_noAdaptersError(0)
|
||||
, m_noUsableAdapterError(0)
|
||||
, m_notDiscoverableAdapterError(0)
|
||||
, m_disabledNotificationsError(0)
|
||||
{
|
||||
|
@ -133,9 +53,6 @@ SystemCheck::SystemCheck(QWidget *parent)
|
|||
|
||||
SystemCheck::~SystemCheck()
|
||||
{
|
||||
m_noAdaptersError = 0;
|
||||
m_notDiscoverableAdapterError = 0;
|
||||
m_disabledNotificationsError = 0;
|
||||
delete m_kded;
|
||||
}
|
||||
|
||||
|
@ -145,18 +62,22 @@ void SystemCheck::createWarnings(QVBoxLayout *layout)
|
|||
return;
|
||||
}
|
||||
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
m_noAdaptersError = new KMessageWidget(m_parent);
|
||||
m_noAdaptersError->setMessageType(KMessageWidget::Error);
|
||||
m_noAdaptersError->setCloseButtonVisible(false);
|
||||
#else
|
||||
m_noAdaptersError = new ErrorWidget(m_parent);
|
||||
m_noAdaptersError->setIcon("window-close");
|
||||
#endif
|
||||
m_noAdaptersError->setText(i18n("No Bluetooth adapters have been found."));
|
||||
layout->addWidget(m_noAdaptersError);
|
||||
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
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."));
|
||||
|
||||
KAction *fixNoUsableAdapter = new KAction(KIcon("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);
|
||||
|
@ -164,19 +85,10 @@ void SystemCheck::createWarnings(QVBoxLayout *layout)
|
|||
KAction *fixNotDiscoverableAdapter = new KAction(KIcon("dialog-ok-apply"), i18nc("Action to fix a problem", "Fix it"), m_notDiscoverableAdapterError);
|
||||
connect(fixNotDiscoverableAdapter, SIGNAL(triggered(bool)), this, SLOT(fixNotDiscoverableAdapterError()));
|
||||
m_notDiscoverableAdapterError->addAction(fixNotDiscoverableAdapter);
|
||||
#else
|
||||
m_notDiscoverableAdapterError = new ErrorWidget(m_parent);
|
||||
m_notDiscoverableAdapterError->setIcon("edit-find");
|
||||
|
||||
KPushButton *fixNotDiscoverableAdapter = new KPushButton(KIcon("dialog-ok-apply"), i18nc("Action to fix a problem", "Fix it"), m_notDiscoverableAdapterError);
|
||||
connect(fixNotDiscoverableAdapter, SIGNAL(clicked()), this, SLOT(fixNotDiscoverableAdapterError()));
|
||||
m_notDiscoverableAdapterError->addAction(fixNotDiscoverableAdapter);
|
||||
#endif
|
||||
m_notDiscoverableAdapterError->setText(i18n("Your default Bluetooth adapter is not visible for remote devices."));
|
||||
|
||||
layout->addWidget(m_notDiscoverableAdapterError);
|
||||
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
m_disabledNotificationsError = new KMessageWidget(m_parent);
|
||||
m_disabledNotificationsError->setMessageType(KMessageWidget::Warning);
|
||||
m_disabledNotificationsError->setCloseButtonVisible(false);
|
||||
|
@ -184,19 +96,10 @@ void SystemCheck::createWarnings(QVBoxLayout *layout)
|
|||
KAction *fixDisabledNotifications = new KAction(KIcon("dialog-ok-apply"), i18nc("Action to fix a problem", "Fix it"), m_disabledNotificationsError);
|
||||
connect(fixDisabledNotifications, SIGNAL(triggered(bool)), this, SLOT(fixDisabledNotificationsError()));
|
||||
m_disabledNotificationsError->addAction(fixDisabledNotifications);
|
||||
#else
|
||||
m_disabledNotificationsError = new ErrorWidget(m_parent);
|
||||
m_disabledNotificationsError->setIcon("preferences-desktop-notification");
|
||||
|
||||
KPushButton *fixDisabledNotifications = new KPushButton(KIcon("dialog-ok-apply"), i18nc("Action to fix a problem", "Fix it"), m_disabledNotificationsError);
|
||||
connect(fixDisabledNotifications, SIGNAL(clicked()), this, SLOT(fixDisabledNotificationsError()));
|
||||
m_disabledNotificationsError->addAction(fixDisabledNotifications);
|
||||
#endif
|
||||
m_disabledNotificationsError->setText(i18n("Interaction with Bluetooth system is not optimal."));
|
||||
|
||||
layout->addWidget(m_disabledNotificationsError);
|
||||
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
m_noKDEDRunning = new KMessageWidget(m_parent);
|
||||
m_noKDEDRunning ->setMessageType(KMessageWidget::Warning);
|
||||
m_noKDEDRunning->setCloseButtonVisible(false);
|
||||
|
@ -204,14 +107,6 @@ void SystemCheck::createWarnings(QVBoxLayout *layout)
|
|||
KAction *fixNoKDEDRunning = new KAction(KIcon("dialog-ok-apply"), i18nc("Action to fix a problem", "Fix it"), m_noKDEDRunning);
|
||||
connect(fixNoKDEDRunning, SIGNAL(triggered(bool)), this, SLOT(fixNoKDEDRunning()));
|
||||
m_noKDEDRunning->addAction(fixNoKDEDRunning);
|
||||
#else
|
||||
m_noKDEDRunning = new ErrorWidget(m_parent);
|
||||
m_noKDEDRunning->setIcon("dialog-warning");
|
||||
|
||||
KPushButton *fixNoKDEDRunning = new KPushButton(KIcon("dialog-ok-apply"), i18nc("Action to fix a problem", "Fix it"), m_noKDEDRunning);
|
||||
connect(fixNoKDEDRunning, SIGNAL(clicked()), this, SLOT(fixNoKDEDRunning()));
|
||||
m_noKDEDRunning->addAction(fixNoKDEDRunning);
|
||||
#endif
|
||||
m_noKDEDRunning->setText(i18n("Bluetooth is not completely enabled."));
|
||||
|
||||
layout->addWidget(m_noKDEDRunning);
|
||||
|
@ -259,6 +154,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);
|
||||
|
@ -268,9 +164,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()) {
|
||||
|
@ -293,6 +194,12 @@ void SystemCheck::fixNoKDEDRunning()
|
|||
m_kded->loadModule("bluedevil");
|
||||
}
|
||||
|
||||
void SystemCheck::fixNoUsableAdapterError()
|
||||
{
|
||||
m_noUsableAdapterError->setVisible(false);
|
||||
BlueDevil::Manager::self()->adapters().first()->setPowered(true);
|
||||
}
|
||||
|
||||
void SystemCheck::fixNotDiscoverableAdapterError()
|
||||
{
|
||||
m_notDiscoverableAdapterError->setVisible(false);
|
||||
|
|
|
@ -22,19 +22,12 @@
|
|||
#define BLUEDEVIL_SYSTEM_CHECK_H
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <kdeversion.h>
|
||||
|
||||
class QVBoxLayout;
|
||||
|
||||
class KDED;
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
class KMessageWidget;
|
||||
#else
|
||||
class ErrorWidget;
|
||||
#endif
|
||||
|
||||
class SystemCheck
|
||||
: public QObject
|
||||
class SystemCheck : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -42,17 +35,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();
|
||||
|
@ -67,23 +49,18 @@ public Q_SLOTS:
|
|||
|
||||
private Q_SLOTS:
|
||||
void fixNoKDEDRunning();
|
||||
void fixNoUsableAdapterError();
|
||||
void fixNotDiscoverableAdapterError();
|
||||
void fixDisabledNotificationsError();
|
||||
|
||||
private:
|
||||
KDED *m_kded;
|
||||
QWidget *m_parent;
|
||||
#if KDE_IS_VERSION(4,6,41)
|
||||
KMessageWidget *m_noAdaptersError;
|
||||
KMessageWidget *m_noUsableAdapterError;
|
||||
KMessageWidget *m_noKDEDRunning;
|
||||
KMessageWidget *m_notDiscoverableAdapterError;
|
||||
KMessageWidget *m_disabledNotificationsError;
|
||||
#else
|
||||
ErrorWidget *m_noAdaptersError;
|
||||
ErrorWidget *m_noKDEDRunning;
|
||||
ErrorWidget *m_notDiscoverableAdapterError;
|
||||
ErrorWidget *m_disabledNotificationsError;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //BLUEDEVIL_SYSTEM_CHECK_H
|
||||
#endif //BLUEDEVIL_SYSTEM_CHECK_H
|
||||
|
|
|
@ -5,11 +5,19 @@
|
|||
<method name="isOnline">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="knownDevices">
|
||||
<method name="allDevices">
|
||||
<arg type="aa{ss}" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QMapDeviceInfo"/>
|
||||
</method>
|
||||
<method name="device">
|
||||
<arg name="address" type="s" direction="in"/>
|
||||
<arg type="a{ss}" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="DeviceInfo"/>
|
||||
</method>
|
||||
<method name="startDiscovering">
|
||||
<arg name="timeout" type="u" direction="in"/>
|
||||
</method>
|
||||
<method name="stopDiscovering">
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
#include <KApplication>
|
||||
#include <KLocale>
|
||||
|
||||
#include <bluedevil/bluedevil.h>
|
||||
|
||||
using namespace BlueDevil;
|
||||
|
||||
extern "C" int KDE_EXPORT kdemain(int argc, char **argv)
|
||||
{
|
||||
KAboutData about("kiobluetooth", "bluedevil", ki18n("kiobluetooth"), bluedevil_version);
|
||||
|
@ -70,19 +66,19 @@ KioBluetooth::KioBluetooth(const QByteArray &pool, const QByteArray &app)
|
|||
s.mimetype = "application/vnd.kde.bluedevil-sendfile";
|
||||
s.uuid = "00001105-0000-1000-8000-00805F9B34FB";
|
||||
m_supportedServices.insert("00001105-0000-1000-8000-00805F9B34FB", s);
|
||||
|
||||
s.name = i18n("Browse Files");
|
||||
s.icon = "edit-find";
|
||||
s.mimetype = "";
|
||||
s.mimetype = QString();
|
||||
s.uuid = "00001106-0000-1000-8000-00805F9B34FB";
|
||||
m_supportedServices.insert("00001106-0000-1000-8000-00805F9B34FB", s);
|
||||
|
||||
kDebug() << "Kio Bluetooth instanced!";
|
||||
m_kded = new org::kde::BlueDevil("org.kde.kded", "/modules/bluedevil", QDBusConnection::sessionBus(), 0);
|
||||
|
||||
if (!Manager::self()->usableAdapter()) {
|
||||
kDebug() << "No available interface";
|
||||
if (!m_kded->isOnline()) {
|
||||
kDebug() << "Bluetooth is offline";
|
||||
infoMessage(i18n("No Bluetooth adapters have been found."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,14 +96,22 @@ QList<KioBluetooth::Service> KioBluetooth::getSupportedServices(const QStringLis
|
|||
|
||||
void KioBluetooth::listRemoteDeviceServices()
|
||||
{
|
||||
m_kded->stopDiscovering();
|
||||
infoMessage(i18n("Retrieving services..."));
|
||||
|
||||
kDebug() << "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()) {
|
||||
kDebug() << "Invalid hostname!";
|
||||
infoMessage(i18n("This address is unavailable."));
|
||||
finished();
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentHostServices = getSupportedServices(info.value("UUIDs").split(','));
|
||||
|
||||
kDebug() << "Num of supported services: " << m_currentHostServices.size();
|
||||
|
||||
totalSize(m_currentHostServices.count());
|
||||
int i = 1;
|
||||
Q_FOREACH (const Service &service, m_currentHostServices) {
|
||||
|
@ -138,19 +142,24 @@ void KioBluetooth::listRemoteDeviceServices()
|
|||
}
|
||||
|
||||
listEntry(KIO::UDSEntry(), true);
|
||||
infoMessage("");
|
||||
infoMessage(QString());
|
||||
finished();
|
||||
}
|
||||
|
||||
void KioBluetooth::listDevices()
|
||||
{
|
||||
kDebug() << "Asking kded for devices";
|
||||
QMapDeviceInfo devices = m_kded->knownDevices().value();
|
||||
QMapDeviceInfo devices = m_kded->allDevices().value();
|
||||
kDebug() << devices.keys();
|
||||
|
||||
Q_FOREACH(const DeviceInfo device, devices) {
|
||||
listDevice(device);
|
||||
}
|
||||
|
||||
listEntry(KIO::UDSEntry(), true);
|
||||
|
||||
m_kded->startDiscovering(10 * 1000);
|
||||
|
||||
infoMessage(i18n("Scanning for new devices..."));
|
||||
finished();
|
||||
}
|
||||
|
@ -215,24 +224,25 @@ void KioBluetooth::get(const KUrl &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)
|
||||
{
|
||||
kDebug() << "Setting host: " << constHostname;
|
||||
kDebug() << "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('-', ':').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(':'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,13 +33,6 @@
|
|||
*/
|
||||
class KioBluetoothPrivate;
|
||||
|
||||
namespace BlueDevil {
|
||||
class Device;
|
||||
class Adapter;
|
||||
}
|
||||
|
||||
using namespace BlueDevil;
|
||||
|
||||
class KioBluetooth : public QObject, public KIO::SlaveBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -78,7 +71,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
|
||||
|
@ -117,10 +110,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
|
||||
|
@ -128,12 +120,6 @@ private:
|
|||
*/
|
||||
QList<Service> m_currentHostServices;
|
||||
|
||||
/**
|
||||
* This is an array containing as key the uuid and as value the name of the service that the
|
||||
* given uuid represents.
|
||||
*/
|
||||
QMap<QString, QString> 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.
|
||||
|
@ -146,4 +132,4 @@ private:
|
|||
org::kde::BlueDevil *m_kded;
|
||||
};
|
||||
|
||||
#endif // KIOBLUETOOTH_H
|
||||
#endif // KIOBLUETOOTH_H
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
#include <KAboutData>
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <bluedevil/bluedevilmanager.h>
|
||||
#include <bluedevil/bluedeviladapter.h>
|
||||
|
||||
using namespace BlueDevil;
|
||||
K_PLUGIN_FACTORY(ObexFtpFactory,
|
||||
registerPlugin<ObexFtpDaemon>();)
|
||||
K_EXPORT_PLUGIN(ObexFtpFactory("obexftpdaemon", "obexftpdaemon"))
|
||||
|
@ -55,7 +51,8 @@ ObexFtpDaemon::ObexFtpDaemon(QObject *parent, const QList<QVariant>&)
|
|||
: KDEDModule(parent)
|
||||
, d(new Private)
|
||||
{
|
||||
d->m_status = Private::Offline;
|
||||
qDBusRegisterMetaType<DBusManagerStruct>();
|
||||
qDBusRegisterMetaType<QVariantMapMap>();
|
||||
|
||||
KAboutData aboutData(
|
||||
"obexftpdaemon",
|
||||
|
@ -70,23 +67,21 @@ ObexFtpDaemon::ObexFtpDaemon(QObject *parent, const QList<QVariant>&)
|
|||
aboutData.addAuthor(ki18n("Alejandro Fiestas Olivares"), ki18n("Maintainer"), "afiestas@kde.org",
|
||||
"http://www.afiestas.org");
|
||||
|
||||
connect(Manager::self(), SIGNAL(usableAdapterChanged(Adapter*)),
|
||||
SLOT(usableAdapterChanged(Adapter*)));
|
||||
|
||||
d->m_status = Private::Offline;
|
||||
d->m_interface = new OrgFreedesktopDBusObjectManagerInterface("org.bluez.obex", "/", QDBusConnection::sessionBus(), this);
|
||||
connect(d->m_interface, SIGNAL(InterfacesRemoved(QDBusObjectPath,QStringList)),
|
||||
SLOT(interfaceRemoved(QDBusObjectPath,QStringList)));
|
||||
|
||||
d->m_serviceWatcher = new QDBusServiceWatcher("org.bluez.obex", QDBusConnection::sessionBus(),
|
||||
QDBusServiceWatcher::WatchForUnregistration, this);
|
||||
QDBusServiceWatcher::WatchForRegistration | 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()));
|
||||
|
||||
qDBusRegisterMetaType<DBusManagerStruct>();
|
||||
qDBusRegisterMetaType<QVariantMapMap>();
|
||||
|
||||
//WARNING this blocks if org.bluez in system bus is dead
|
||||
if (Manager::self()->usableAdapter()) {
|
||||
if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.bluez.obex")) {
|
||||
onlineMode();
|
||||
} else {
|
||||
offlineMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +106,7 @@ void ObexFtpDaemon::onlineMode()
|
|||
|
||||
void ObexFtpDaemon::offlineMode()
|
||||
{
|
||||
kDebug(dobex()) << "Offline mode";
|
||||
kDebug(dobex());
|
||||
if (d->m_status == Private::Offline) {
|
||||
kDebug(dobex()) << "Already in offlineMode";
|
||||
return;
|
||||
|
@ -123,27 +118,24 @@ 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)
|
||||
{
|
||||
kDebug(dobex()) << address;
|
||||
address.replace("-", ":");
|
||||
|
||||
if(d->m_sessionMap.contains(address)) {
|
||||
if (d->m_sessionMap.contains(address)) {
|
||||
return d->m_sessionMap[address];
|
||||
}
|
||||
|
||||
//At this point we always want delayed reply
|
||||
kDebug(dobex()) << "Creating session for" << address;
|
||||
|
||||
// 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();
|
||||
|
@ -157,30 +149,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("org.bluez.obex",
|
||||
transfer,
|
||||
"org.bluez.obex.Transfer1",
|
||||
"Cancel");
|
||||
|
||||
QDBusReply<void> reply = QDBusConnection::sessionBus().call(call);
|
||||
return reply.isValid();
|
||||
}
|
||||
|
||||
void ObexFtpDaemon::sessionCreated(KJob* job)
|
||||
{
|
||||
CreateSessionJob* cJob = qobject_cast<CreateSessionJob*>(job);
|
||||
kDebug(dobex()) << 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<QDBusMessage> 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)
|
||||
|
@ -197,4 +205,4 @@ void ObexFtpDaemon::interfaceRemoved(const QDBusObjectPath &dbusPath, const QStr
|
|||
kDebug(dobex()) << d->m_sessionMap.remove(address);
|
||||
}
|
||||
|
||||
extern int dobex() { static int s_area = KDebug::registerArea("ObexDaemon", false); return s_area; }
|
||||
extern int dobex() { static int s_area = KDebug::registerArea("ObexDaemon", false); return s_area; }
|
||||
|
|
|
@ -28,44 +28,28 @@ class KJob;
|
|||
class QDBusMessage;
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
namespace BlueDevil {
|
||||
class Adapter;
|
||||
};
|
||||
using namespace BlueDevil;
|
||||
|
||||
class KDE_EXPORT ObexFtpDaemon
|
||||
: public KDEDModule
|
||||
class KDE_EXPORT ObexFtpDaemon : public KDEDModule
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.ObexFtp")
|
||||
|
||||
public:
|
||||
/**
|
||||
* Connects to usableAdapterChanged
|
||||
*/
|
||||
ObexFtpDaemon(QObject *parent, const QList<QVariant>&);
|
||||
virtual ~ObexFtpDaemon();
|
||||
|
||||
public Q_SLOTS:
|
||||
Q_SCRIPTABLE bool isOnline();
|
||||
Q_SCRIPTABLE QString session(QString address, 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;
|
||||
|
|
|
@ -63,15 +63,12 @@ void CreateSessionJob::createSession()
|
|||
kDebug(dobex());
|
||||
QVariantMap args;
|
||||
args["Target"] = "ftp";
|
||||
// args["Source"] = "00:02:72:D6:8F:2C";
|
||||
m_client = new OrgBluezObexClient1Interface("org.bluez.obex",
|
||||
"/org/bluez/obex",
|
||||
QDBusConnection::sessionBus(), this);
|
||||
|
||||
QDBusPendingReply <QDBusObjectPath > reply = m_client->CreateSession(m_address, args);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply);
|
||||
|
||||
kDebug(dobex()) << "DROGUES";
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(sessionCreated(QDBusPendingCallWatcher*)));
|
||||
}
|
||||
|
||||
|
@ -84,12 +81,6 @@ void CreateSessionJob::sessionCreated(QDBusPendingCallWatcher* watcher)
|
|||
kDebug(dobex()) << "Error:";
|
||||
kDebug(dobex()) << reply.error().name();
|
||||
kDebug(dobex()) << reply.error().message();
|
||||
// Q_FOREACH(const QDBusMessage &msg, m_msgs) {
|
||||
// kDebug(dobex()) << 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();
|
||||
|
@ -98,4 +89,4 @@ void CreateSessionJob::sessionCreated(QDBusPendingCallWatcher* watcher)
|
|||
|
||||
m_path = reply.value().path();
|
||||
emitResult();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,16 @@
|
|||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.kde.ObexFtp">
|
||||
<method name="isOnline">
|
||||
<arg name="online" type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="session">
|
||||
<arg name="address" type="s" direction="in"/>
|
||||
<arg name="sessionPath" type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="cancelTransfer">
|
||||
<arg name="transfer" type="s" direction="in"/>
|
||||
<arg name="success" type="b" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
@ -52,12 +52,15 @@ extern "C" int KDE_EXPORT kdemain(int argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool urlIsRoot(const KUrl &url)
|
||||
{
|
||||
return (url.directory() == QLatin1String("/") || url.directory().isEmpty()) && url.fileName().isEmpty();
|
||||
}
|
||||
|
||||
KioFtp::KioFtp(const QByteArray &pool, const QByteArray &app)
|
||||
: SlaveBase("obexftp", pool, app)
|
||||
, m_transfer(0)
|
||||
{
|
||||
m_settingHost = false;
|
||||
|
||||
m_timer = new QTimer();
|
||||
m_timer->setInterval(100);
|
||||
|
||||
|
@ -78,6 +81,47 @@ void KioFtp::launchProgressBar()
|
|||
m_timer->start();
|
||||
}
|
||||
|
||||
void KioFtp::connectToHost()
|
||||
{
|
||||
QDBusPendingReply<QString> reply = m_kded->session(m_host);
|
||||
reply.waitForFinished();
|
||||
|
||||
const QString &sessionPath = reply.value();
|
||||
|
||||
if (reply.isError() || sessionPath.isEmpty()) {
|
||||
kDebug() << reply.error().message();
|
||||
kDebug() << reply.error().name();
|
||||
|
||||
delete m_transfer;
|
||||
m_transfer = 0;
|
||||
m_sessionPath.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_sessionPath != sessionPath) {
|
||||
m_statMap.clear();
|
||||
delete m_transfer;
|
||||
m_transfer = new org::bluez::obex::FileTransfer1("org.bluez.obex", sessionPath, QDBusConnection::sessionBus());
|
||||
m_sessionPath = sessionPath;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void KioFtp::updateProcess()
|
||||
{
|
||||
if (m_counter == 49) {
|
||||
|
@ -92,35 +136,27 @@ void KioFtp::updateProcess()
|
|||
|
||||
void KioFtp::listDir(const KUrl &url)
|
||||
{
|
||||
if (!testConnection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "listdir: " << url;
|
||||
|
||||
infoMessage(i18n("Retrieving information from remote device..."));
|
||||
|
||||
kDebug() << "Asking for listFolder";
|
||||
kDebug() << "Asking for listFolder" << url.path();
|
||||
|
||||
//TODO: Check if changeFolder fails
|
||||
m_transfer->ChangeFolder(url.path()).waitForFinished();
|
||||
|
||||
QDBusPendingReply <QVariantMapList > reply = m_transfer->ListFolder();
|
||||
reply.waitForFinished();
|
||||
|
||||
if (reply.isError()) {
|
||||
kDebug() << reply.error().message();
|
||||
error(KIO::ERR_SLAVE_DEFINED, i18n("Bluetooth is not enabled"));
|
||||
finished();
|
||||
if (!changeFolder(url.path())) {
|
||||
return;
|
||||
}
|
||||
QVariantMapList folderList = reply.value();
|
||||
Q_FOREACH(const QVariantMap folder, folderList) {
|
||||
KIO::UDSEntry entry = entryFromInfo(folder);
|
||||
|
||||
KUrl statUrl(url);
|
||||
statUrl.setFileName(folder["Name"].toString());
|
||||
if (!m_statMap.contains(statUrl.prettyUrl())) {
|
||||
kDebug() << "Stat: " << statUrl.prettyUrl() << entry.numberValue(KIO::UDSEntry::UDS_SIZE);
|
||||
m_statMap.insert(statUrl.prettyUrl(), entry);
|
||||
}
|
||||
bool ok;
|
||||
const QList<KIO::UDSEntry> &list = listFolder(url, &ok);
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_FOREACH (const KIO::UDSEntry &entry, list) {
|
||||
listEntry(entry, false);
|
||||
}
|
||||
|
||||
|
@ -133,11 +169,13 @@ void KioFtp::copy(const KUrl &src, const KUrl &dest, int permissions, KIO::JobFl
|
|||
Q_UNUSED(permissions)
|
||||
Q_UNUSED(flags)
|
||||
|
||||
if (!testConnection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "copy: " << src.url() << " to " << dest.url();
|
||||
|
||||
copyHelper(src, dest);
|
||||
|
||||
finished();
|
||||
}
|
||||
|
||||
void KioFtp::rename(const KUrl& src, const KUrl& dest, KIO::JobFlags flags)
|
||||
|
@ -146,15 +184,18 @@ void KioFtp::rename(const KUrl& src, const KUrl& dest, KIO::JobFlags flags)
|
|||
Q_UNUSED(dest)
|
||||
Q_UNUSED(flags)
|
||||
|
||||
error(KIO::ERR_UNSUPPORTED_ACTION, src.prettyUrl());
|
||||
finished();
|
||||
error(KIO::ERR_UNSUPPORTED_ACTION, QString());
|
||||
}
|
||||
|
||||
void KioFtp::get(const KUrl& url)
|
||||
{
|
||||
if (!testConnection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
KTemporaryFile tempFile;
|
||||
tempFile.setSuffix(url.fileName());
|
||||
tempFile.open();//Create the file
|
||||
tempFile.open(); // Create the file
|
||||
kDebug() << tempFile.fileName();
|
||||
|
||||
copyHelper(url, KUrl(tempFile.fileName()));
|
||||
|
@ -172,6 +213,10 @@ void KioFtp::get(const KUrl& 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)
|
||||
{
|
||||
|
@ -179,35 +224,27 @@ void KioFtp::setHost(const QString &host, quint16 port, const QString &user, con
|
|||
Q_UNUSED(user)
|
||||
Q_UNUSED(pass)
|
||||
|
||||
m_host = host;
|
||||
|
||||
infoMessage(i18n("Connecting to the device"));
|
||||
|
||||
kDebug() << "setHost: " << host;
|
||||
|
||||
kDebug() << "Waiting to stablish the connection 2";
|
||||
QDBusPendingReply <QString > reply = m_kded->session(host);
|
||||
reply.waitForFinished();
|
||||
|
||||
kDebug() << "AFTER" << reply.isError();
|
||||
if (reply.isError()) {
|
||||
kDebug() << reply.error().message();
|
||||
kDebug() << reply.error().name();
|
||||
}
|
||||
|
||||
kDebug() << "Got a path" << reply.value();
|
||||
|
||||
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 KUrl& url, bool isfile)
|
||||
{
|
||||
Q_UNUSED(isfile)
|
||||
|
||||
kDebug() << "Del: " << url.url();
|
||||
m_transfer->ChangeFolder(url.directory()).waitForFinished();
|
||||
m_transfer->Delete(url.fileName()).waitForFinished();
|
||||
if (!testConnection()) {
|
||||
return;
|
||||
}
|
||||
if (!changeFolder(url.directory())) {
|
||||
return;
|
||||
}
|
||||
if (!deleteFile(url.fileName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
finished();
|
||||
}
|
||||
|
||||
|
@ -215,14 +252,28 @@ void KioFtp::mkdir(const KUrl& url, int permissions)
|
|||
{
|
||||
Q_UNUSED(permissions)
|
||||
|
||||
if (!testConnection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "MkDir: " << url.url();
|
||||
m_transfer->ChangeFolder(url.directory()).waitForFinished();
|
||||
m_transfer->CreateFolder(url.fileName()).waitForFinished();
|
||||
|
||||
if (!changeFolder(url.directory())) {
|
||||
return;
|
||||
}
|
||||
if (!createFolder(url.fileName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
finished();
|
||||
}
|
||||
|
||||
void KioFtp::stat(const KUrl &url)
|
||||
{
|
||||
if (!testConnection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "Stat: " << url.url();
|
||||
kDebug() << "Stat Dir: " << url.directory();
|
||||
kDebug() << "Stat File: " << url.fileName();
|
||||
|
@ -237,8 +288,7 @@ void KioFtp::stat(const KUrl &url)
|
|||
void KioFtp::copyHelper(const KUrl& src, const KUrl& dest)
|
||||
{
|
||||
if (src.scheme() == "obexftp" && dest.scheme() == "obexftp") {
|
||||
error(KIO::ERR_UNSUPPORTED_ACTION, src.prettyUrl());
|
||||
//TODO: with obexd this seems possible, we should at least try
|
||||
copyWithinObexftp(src, dest);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,6 +303,16 @@ void KioFtp::copyHelper(const KUrl& src, const KUrl& dest)
|
|||
}
|
||||
|
||||
kDebug() << "This shouldn't happen...";
|
||||
}
|
||||
|
||||
void KioFtp::copyWithinObexftp(const KUrl &src, const KUrl &dest)
|
||||
{
|
||||
kDebug() << "Source: " << src << "Dest:" << dest;
|
||||
|
||||
if (!copyFile(src.path(), dest.path())) {
|
||||
return;
|
||||
}
|
||||
|
||||
finished();
|
||||
}
|
||||
|
||||
|
@ -260,28 +320,17 @@ void KioFtp::copyFromObexftp(const KUrl& src, const KUrl& dest)
|
|||
{
|
||||
kDebug() << "Source: " << src << "Dest:" << dest;
|
||||
|
||||
//Just in case the url is not in the stat, some times happens...
|
||||
if (!m_statMap.contains(src.prettyUrl())) {
|
||||
kDebug() << "The url is not in the cache, stating it";
|
||||
statHelper(src);
|
||||
}
|
||||
|
||||
if (m_statMap.value(src.prettyUrl()).isDir()) {
|
||||
kDebug() << "Skipping to copy: " << src.prettyUrl();
|
||||
//TODO: Check if dir copying works with obexd
|
||||
error(KIO::ERR_IS_DIRECTORY, src.prettyUrl());
|
||||
if (!changeFolder(src.directory())) {
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "Changing dir:" << src.directory();
|
||||
m_transfer->ChangeFolder(src.directory()).waitForFinished();
|
||||
|
||||
QString dbusPath = m_transfer->GetFile(dest.path(), src.fileName()).value().path();
|
||||
kDebug() << "Path from GetFile:" << dbusPath;
|
||||
|
||||
int size = m_statMap[src.prettyUrl()].numberValue(KIO::UDSEntry::UDS_SIZE);
|
||||
totalSize(size);
|
||||
|
||||
TransferFileJob *getFile = new TransferFileJob(dbusPath, this);
|
||||
getFile->setSize(size);
|
||||
getFile->exec();
|
||||
|
||||
finished();
|
||||
|
@ -291,14 +340,17 @@ void KioFtp::copyToObexftp(const KUrl& src, const KUrl& dest)
|
|||
{
|
||||
kDebug() << "Source:" << src << "Dest:" << dest;
|
||||
|
||||
kDebug() << "Changing folder: " << dest.directory();
|
||||
m_transfer->ChangeFolder(dest.directory());
|
||||
if (!changeFolder(dest.directory())) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString dbusPath = m_transfer->PutFile(src.path(), dest.fileName()).value().path();
|
||||
kDebug() << "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();
|
||||
|
@ -314,10 +366,10 @@ void KioFtp::statHelper(const KUrl& url)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((url.directory() == "/" || url.directory().isEmpty()) && url.fileName().isEmpty()) {
|
||||
if (urlIsRoot(url)) {
|
||||
kDebug() << "Url is root";
|
||||
KIO::UDSEntry entry;
|
||||
entry.insert(KIO::UDSEntry::UDS_NAME, QString::fromLatin1("/"));
|
||||
entry.insert(KIO::UDSEntry::UDS_NAME, QLatin1String("/"));
|
||||
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
||||
entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700);
|
||||
entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1( "inode/directory" ) );
|
||||
|
@ -325,52 +377,146 @@ void KioFtp::statHelper(const KUrl& url)
|
|||
kDebug() << "Adding stat cached: " << url.prettyUrl();
|
||||
m_statMap[url.prettyUrl()] = entry;
|
||||
statEntry(entry);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "statMap does NOT contains the url";
|
||||
//TODO: Check if changeFolder fails
|
||||
m_transfer->ChangeFolder(url.directory()).waitForFinished();
|
||||
QVariantMapList folderList = m_transfer->ListFolder().value();
|
||||
kDebug() << url.directory() << folderList.count();
|
||||
Q_FOREACH(const QVariantMap folder, folderList) {
|
||||
KIO::UDSEntry entry = entryFromInfo(folder);
|
||||
|
||||
QString fileName = folder["Name"].toString();
|
||||
if (url.fileName() == fileName) {
|
||||
statEntry(entry);
|
||||
}
|
||||
if (!changeFolder(url.directory())) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Most probably the client of the kio will stat each file
|
||||
//so since we are on it, let's cache all of them.
|
||||
KUrl statUrl(url);
|
||||
statUrl.setFileName(fileName);
|
||||
if (!m_statMap.contains(statUrl.prettyUrl())) {
|
||||
kDebug() << "Stat: " << statUrl.prettyUrl() << entry.stringValue(KIO::UDSEntry::UDS_NAME) << entry.numberValue(KIO::UDSEntry::UDS_SIZE);
|
||||
m_statMap.insert(statUrl.prettyUrl(), entry);
|
||||
}
|
||||
bool ok;
|
||||
const QList<KIO::UDSEntry> &list = listFolder(url, &ok);
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_FOREACH (const KIO::UDSEntry &entry, list) {
|
||||
statEntry(entry);
|
||||
}
|
||||
|
||||
kDebug() << "Finished";
|
||||
}
|
||||
|
||||
KIO::UDSEntry KioFtp::entryFromInfo(const QVariantMap& info)
|
||||
QList<KIO::UDSEntry> KioFtp::listFolder(const KUrl &url, bool *ok)
|
||||
{
|
||||
kDebug() << info;
|
||||
QList<KIO::UDSEntry> list;
|
||||
|
||||
KIO::UDSEntry entry;
|
||||
entry.insert(KIO::UDSEntry::UDS_NAME, info["Name"].toString());
|
||||
entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, info["Created"].toString());
|
||||
entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700);
|
||||
entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, info["Modified"].toString());
|
||||
QDBusPendingReply<QVariantMapList> reply = m_transfer->ListFolder();
|
||||
reply.waitForFinished();
|
||||
|
||||
if (info["Type"].toString() == QLatin1String("folder")) {
|
||||
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
||||
} else {
|
||||
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG);
|
||||
entry.insert(KIO::UDSEntry::UDS_SIZE, info["Size"].toLongLong());
|
||||
if (reply.isError()) {
|
||||
error(KIO::ERR_CANNOT_OPEN_FOR_READING, url.directory());
|
||||
*ok = false;
|
||||
return list;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
Q_FOREACH (const QVariantMap &item, reply.value()) {
|
||||
KIO::UDSEntry entry;
|
||||
entry.insert(KIO::UDSEntry::UDS_NAME, item["Name"].toString());
|
||||
entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, item["Label"].toString());
|
||||
entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700);
|
||||
entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, QDateTime::fromString(item["Modified"].toString(), "yyyyMMddThhmmssZ").toTime_t());
|
||||
entry.insert(KIO::UDSEntry::UDS_SIZE, item["Size"].toLongLong());
|
||||
if (item["Type"] == QLatin1String("folder")) {
|
||||
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
||||
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
|
||||
} else {
|
||||
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG);
|
||||
}
|
||||
if (urlIsRoot(url)) {
|
||||
updateRootEntryIcon(entry, item["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.
|
||||
KUrl statUrl(url);
|
||||
statUrl.setFileName(item["Name"].toString());
|
||||
if (!m_statMap.contains(statUrl.prettyUrl())) {
|
||||
kDebug() << "Stat: " << statUrl.prettyUrl() << entry.stringValue(KIO::UDSEntry::UDS_NAME) << entry.numberValue(KIO::UDSEntry::UDS_SIZE);
|
||||
m_statMap.insert(statUrl.prettyUrl(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
*ok = true;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool KioFtp::changeFolder(const QString &folder)
|
||||
{
|
||||
QDBusPendingReply<> reply = m_transfer->ChangeFolder(folder);
|
||||
reply.waitForFinished();
|
||||
|
||||
if (reply.isError()) {
|
||||
error(KIO::ERR_CANNOT_ENTER_DIRECTORY, folder);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KioFtp::createFolder(const QString &folder)
|
||||
{
|
||||
QDBusPendingReply<> reply = m_transfer->CreateFolder(folder);
|
||||
reply.waitForFinished();
|
||||
|
||||
if (reply.isError()) {
|
||||
error(KIO::ERR_COULD_NOT_MKDIR, folder);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KioFtp::copyFile(const QString &src, const QString &dest)
|
||||
{
|
||||
QDBusPendingReply<> reply = m_transfer->CopyFile(src, dest);
|
||||
reply.waitForFinished();
|
||||
|
||||
if (reply.isError()) {
|
||||
kDebug() << 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, "drive-removable-media");
|
||||
} else if (memoryType == QLatin1String("MMC")) {
|
||||
entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "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, "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, "media-flash-sd-mmc");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,27 +50,37 @@ public:
|
|||
virtual void rename(const KUrl& src, const KUrl& dest, KIO::JobFlags flags);
|
||||
virtual void get(const KUrl& url);
|
||||
|
||||
bool cancelTransfer(const QString &transfer);
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateProcess();
|
||||
|
||||
KIO::UDSEntry entryFromInfo(const QVariantMap &info);
|
||||
private:
|
||||
void copyHelper(const KUrl &src, const KUrl &dest);
|
||||
void copyWithinObexftp(const KUrl &src, const KUrl &dest);
|
||||
void copyFromObexftp(const KUrl &src, const KUrl &dest);
|
||||
void copyToObexftp(const KUrl &src, const KUrl &dest);
|
||||
void statHelper(const KUrl &url);
|
||||
|
||||
QList<KIO::UDSEntry> listFolder(const KUrl &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();
|
||||
|
||||
private:
|
||||
int m_counter;
|
||||
bool m_settingHost;
|
||||
QEventLoop m_eventLoop;
|
||||
int m_counter;
|
||||
QMap<QString, KIO::UDSEntry> m_statMap;
|
||||
QString m_address;
|
||||
QString m_sessionPath;
|
||||
QTimer *m_timer;
|
||||
org::kde::ObexFtp *m_kded;
|
||||
QString m_host;
|
||||
QString m_sessionPath;
|
||||
QTimer *m_timer;
|
||||
org::kde::ObexFtp *m_kded;
|
||||
OrgBluezObexFileTransfer1Interface *m_transfer;
|
||||
|
||||
};
|
||||
|
||||
#endif // KIO_OBEXFTP_H
|
||||
|
|
|
@ -34,7 +34,6 @@ TransferFileJob::TransferFileJob(const QString& path, KioFtp* parent)
|
|||
, m_speedBytes(0)
|
||||
, m_parent(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransferFileJob::~TransferFileJob()
|
||||
|
@ -50,16 +49,7 @@ void TransferFileJob::start()
|
|||
|
||||
bool TransferFileJob::doKill()
|
||||
{
|
||||
QDBusPendingReply <void > reply = m_transfer->Cancel();
|
||||
reply.waitForFinished();
|
||||
|
||||
return !reply.isError();
|
||||
}
|
||||
|
||||
void TransferFileJob::setSize(int size)
|
||||
{
|
||||
kDebug() << size;
|
||||
m_parent->totalSize(size);
|
||||
return m_parent->cancelTransfer(m_path);
|
||||
}
|
||||
|
||||
void TransferFileJob::createObjects()
|
||||
|
@ -97,7 +87,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")) {
|
||||
|
@ -114,7 +103,7 @@ void TransferFileJob::transferChanged(const QVariant& value)
|
|||
kDebug() << "Transferred: " << value;
|
||||
if (m_parent->wasKilled()) {
|
||||
kDebug() << "Kio was killed, aborting task";
|
||||
m_transfer->Cancel().waitForFinished();
|
||||
doKill();
|
||||
emitResult();
|
||||
return;
|
||||
}
|
||||
|
@ -137,4 +126,4 @@ void TransferFileJob::transferChanged(const QVariant& value)
|
|||
}
|
||||
|
||||
m_parent->processedSize(bytes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
#endif //KIO_GET_FILE_JOB_H
|
||||
|
|
|
@ -44,7 +44,7 @@ Monolithic::Monolithic(QObject* parent)
|
|||
|
||||
offlineMode();
|
||||
|
||||
if (!Manager::self()->adapters().isEmpty()) {
|
||||
if (Manager::self()->usableAdapter()) {
|
||||
onlineMode();
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,6 @@ Monolithic::Monolithic(QObject* parent)
|
|||
setStandardActionsEnabled(false);
|
||||
setAssociatedWidget(contextMenu());
|
||||
|
||||
setStatus(KStatusNotifierItem::Active);
|
||||
poweredChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ void SSPPairingPage::initializePage()
|
|||
void SSPPairingPage::confirmationRequested(quint32 passkey, const QDBusMessage& msg)
|
||||
{
|
||||
m_msg = msg;
|
||||
m_msg.setDelayedReply(true);
|
||||
|
||||
KPushButton *matches = new KPushButton(KStandardGuiItem::apply());
|
||||
matches->setText(i18n("Matches"));
|
||||
|
@ -119,6 +120,7 @@ void SSPPairingPage::matchesClicked()
|
|||
void SSPPairingPage::notMatchClicked()
|
||||
{
|
||||
m_buttonClicked = QWizard::CustomButton2;
|
||||
QDBusConnection::systemBus().send(m_msg.createErrorReply("org.bluez.Rejected", "Rejected"));
|
||||
|
||||
wizard()->next();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue