Logo Search packages:      
Sourcecode: kdebluetooth version File versions

wizarddialog.cpp

/*
 *
 *  KBluetooth4 - KDE4 Bluetooth Framework
 *
 *  Copyright (C) 2008  Tom Patzig <tpatzig@suse.de>
 *
 *  This file is part of kbluetooth4.
 *
 *  kbluetooth4 is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  kbluetooth4 is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with kbluetooth4; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
*/

#include "wizarddialog.h"
#include <KDebug>
#include <klocalizedstring.h>
#include <KMessageBox>



#define HID "00001124-0000-1000-8000-00805F9B34FB"
#define PNP "00001200-0000-1000-8000-00805F9B34FB"
#define HEADSET "00001108-0000-1000-8000-00805F9B34FB"


BTWizard::BTWizard(QObject* parent) : QWizard(),btmanager(Solid::Control::BluetoothManager::self())
{
      iface = new Solid::Control::BluetoothInterface(btmanager.defaultInterface());

      addPage(createIntroPage());
      addPage(createSelectServicePage());
      addPage(createSelectDevicePage());
      addPage(createConnectionPage());
      setWindowIcon(KIcon("preferences-system-bluetooth"));
      setWindowTitle("Bluetooth Device Wizard");
      setPixmap(QWizard::WatermarkPixmap,KIcon("preferences-system-bluetooth").pixmap(128,128));
      
      connect(button(QWizard::CancelButton),SIGNAL(clicked()),this,SLOT(slotCancel()));
      connect(button(QWizard::NextButton),SIGNAL(clicked()),this,SLOT(slotNext()));
      connect(button(QWizard::FinishButton),SIGNAL(clicked()),this,SLOT(slotFinish()));

//    deviceMap = new QMap<QString,Solid::Control::BluetoothRemoteDevice*>;
      
      show();
}

BTWizard::~BTWizard()
{
      kDebug() << "Deleting Wizard";
      if (introPage)
            delete introPage;
      if (servicePage)
            delete servicePage;
      if (devicePage)
            delete devicePage;
      if (connPage)
            delete connPage;
      

      qDeleteAll(deviceMap.begin(),deviceMap.end());
//    qDeleteAll(macMap.begin(),macMap.end());

      
}

WizardPage* BTWizard::createIntroPage()
{
     introPage = new WizardPage;

     introPage->setTitle(i18n("Setup Bluetooth Devices"));

     introLabel = new QLabel(i18n("This wizard will help to setup your Bluetooth devices."),introPage);
     introLabel->setWordWrap(true);

     introLayout = new QVBoxLayout(introPage);
     introLayout->addWidget(introLabel);
     introPage->setLayout(introLayout);

     return introPage;


}

WizardPage* BTWizard::createSelectServicePage()
{
      servicePage = new WizardPage;
      
      servicePage->setTitle(i18n("Select Device type"));
      
      serviceLabel = new QLabel(i18n("Please select the type of your Bluetooth device."),servicePage);
      serviceLabel->setWordWrap(true);
      
      serviceRadioButton1 = new QRadioButton(i18n("Input Device"),servicePage);
      serviceRadioButton2 = new QRadioButton(i18n("Audio Device"),servicePage);
      serviceLayout = new QVBoxLayout(servicePage);
      serviceLayout->addWidget(serviceLabel);
      serviceLayout->addWidget(serviceRadioButton1);
      serviceLayout->addWidget(serviceRadioButton2);
      servicePage->setLayout(serviceLayout);
      
      serviceRadioButton2->setEnabled(false);
      serviceRadioButton1->setChecked(true);
            
      
      
      return servicePage;
      
      
}

WizardPage* BTWizard::createSelectDevicePage()
{
      devicePage = new WizardPage;
      devicePage->setComplete(false);
      
      devicePage->setTitle(i18n("Select your Device"));

        deviceLabel = new QLabel(i18n("Please select your Bluetooth device."),devicePage);
        deviceLabel->setWordWrap(true);

      deviceWidget = new QListWidget(devicePage);
      connect(deviceWidget,SIGNAL(itemSelectionChanged()),this,SLOT(slotDeviceSelectionChanged()));

      
      deviceLabel1 = new QLabel(i18n("<b>If your Device is not in the List:</b>"),devicePage);
      deviceLabel2 = new QLabel(i18n("* Make sure bluetooth is enabled on the device"),devicePage);
      deviceLabel3 = new QLabel(i18n("* Make sure the device is in discoverable mode"),devicePage);
      deviceLabel4 = new QLabel(i18n("* Search again"),devicePage);
      deviceButton = new QPushButton("Search",devicePage);
      deviceComboBox = new QComboBox(devicePage);
      
      deviceComboBox->addItem(i18n("All"));
      deviceComboBox->addItem(i18n("Keyboard/Mouse"));
      deviceComboBox->addItem(i18n("Phones"));
      deviceLabel5 = new QLabel(i18n("Filter:"),devicePage);

      deviceLayout2 = new QHBoxLayout;
      deviceLayout2->addWidget(deviceButton);
      deviceLayout2->addStretch();
      deviceLayout2->addWidget(deviceLabel5);
      deviceLayout2->addWidget(deviceComboBox);
      connect(deviceComboBox,SIGNAL(currentIndexChanged(const QString&)),this,SLOT(changeFilterView(const QString&)));

      deviceButton->setEnabled(false);
      connect(deviceButton,SIGNAL(clicked()),this,SLOT(slotSearch()));

        deviceLayout = new QVBoxLayout;
        deviceLayout->addWidget(deviceLabel);
        deviceLayout->addWidget(deviceWidget);
        deviceLayout->addWidget(deviceLabel1);
        deviceLayout->addWidget(deviceLabel2);
        deviceLayout->addWidget(deviceLabel3);
        deviceLayout->addWidget(deviceLabel4);

        deviceLayout->addLayout(deviceLayout2);

        devicePage->setLayout(deviceLayout);

        return devicePage;

}

WizardPage* BTWizard::createConnectionPage()
{
      connPage = new WizardPage;
      connPage->setComplete(false);
      connPage->setTitle(i18n("Summary"));
      connLabel = new QLabel(i18n("Connection will be established to this Bluetooth device"),connPage);
      connLabel->setWordWrap(true);


      connLabel1 = new QLabel(connPage);
      connLabel2 = new QLabel(connPage);
      connLabel3 = new QLabel(connPage);
      connLabel4 = new QLabel(connPage);
      connLabel5 = new QLabel(connPage);
            
      connLayout = new QVBoxLayout(connPage);
      connLayout->addWidget(connLabel);
      connLayout->addWidget(connLabel1);
      connLayout->addWidget(connLabel2);
      connLayout->addWidget(connLabel3);
      connLayout->addWidget(connLabel4);
      connLayout->addWidget(connLabel5);
      connPage->setLayout(connLayout);

      connect(connPage,SIGNAL(completeChanged()),this,SLOT(slotValidatePage()));

      return connPage;
}


void BTWizard::slotRemoteDeviceFound(QString ubi,int dclass, int rssi)
{
      item = 0;
      dev = iface->createBluetoothRemoteDevice(ubi);
      if (deviceMap.contains(ubi) && (deviceWidget->findItems(dev->name() + " - " + dev->address(),Qt::MatchExactly ).count() > 0 )) 
            return;

      if (!deviceMap.contains(ubi)) {
                  deviceMap.insert(ubi,dev);
                  macMap.insert(dev->address(),ubi);
            }

      if (deviceWidget->findItems(dev->name() + " - " + dev->address(),Qt::MatchExactly ).count() <= 0) {
            kDebug() << "dev major class: " << dev->majorClass();

            QString filter = deviceComboBox->currentText();
            filterList(dev,filter);
      }
}

void BTWizard::slotDiscoveryCompleted()
{
      deviceButton->setEnabled(true);
      deviceButton->setText("Search");
      disconnect(iface,SIGNAL(remoteDeviceFound(QString,int,int)),this,SLOT(slotRemoteDeviceFound(QString,int,int)));
      disconnect(iface,SIGNAL(discoveryCompleted()),this,SLOT(slotDiscoveryCompleted()));
      disconnect(iface,SIGNAL(remoteNameUpdated(const QString&, const QString&)),this,SLOT(slotNewNameFound(const QString&, const QString&)));
      devicePage->setComplete( deviceWidget->currentItem() ? true : false );
      
}

void BTWizard::slotDeviceSelectionChanged()
{
      kDebug() << deviceWidget->currentItem();
      if (deviceButton->isEnabled()) 
            devicePage->setComplete( deviceWidget->currentItem() ? true : false );
      else
            devicePage->setComplete(false);

}

void BTWizard::slotSearch()
{
      kDebug() << "searching..." ;
      devicePage->setComplete(false);
      deviceButton->setEnabled(false);
      deviceButton->setText("Searching...");
      iface->discoverDevices();
      deviceWidget->clear();
      connect(iface,SIGNAL(remoteDeviceFound(QString,int,int)),this,SLOT(slotRemoteDeviceFound(QString,int,int)));
      connect(iface,SIGNAL(discoveryCompleted()),this,SLOT(slotDiscoveryCompleted()));
      connect(iface,SIGNAL(remoteNameUpdated(const QString&, const QString&)),this,SLOT(slotNewNameFound(const QString&, const QString&)));
      
}

void BTWizard::slotNewNameFound(const QString& address, const QString& name)
{
      kDebug() << "New Remote Name found " << name; 
      if (deviceWidget->findItems(address,Qt::MatchContains ).count() > 0) {
            QListWidgetItem* it = deviceWidget->findItems(address,Qt::MatchContains).at(0);
            it->setText(name + " - " + address);
      }

}


void BTWizard::slotNext()
{
      kDebug() << "Page ID: " << currentId();
      switch (currentId()) {

            case 2 :
                  if (serviceRadioButton1->isChecked())
                        service = "input";
                  if (serviceRadioButton2->isChecked())
                        service = "audio";
                  kDebug() << "page 2 reached!";
                  slotSearch();
                  break;
            case 3 :
                  if(deviceWidget->currentItem()) {
                        QString ubi = macMap.value(deviceWidget->currentItem()->text().split(" - ").at(1));
                        finalDev = deviceMap.value(ubi);

                        connLabel->setText(i18n("Checking the Device for input capabilities..."));
                        connLabel1->setText("");
                        connLabel2->setText("");
                        connLabel3->setText("");
                        connLabel4->setText("");
                        connPage->setComplete(false);

                        checkForHIDDevice(finalDev);
                  }
                  break;
      }
}

void BTWizard::slotFinish()
{
      
      kDebug() << "trying to finish...";
      kDebug() << "trying to connect...UBI= " << finalDev->ubi();
//    if (finalDev->minorClass() == "keyboard") {
            createBonding();
//    }
      createInputDev();

}

void BTWizard::createInputDev()
{
      Solid::Control::BluetoothManager &man = Solid::Control::BluetoothManager::self();
      
//    inputDev = man.createBluetoothInputDevice(finalDev->ubi());
      KJob *job = man.setupInputDevice(finalDev->ubi());
//          inputDev->connect();

      connect(&man,SIGNAL(inputDeviceCreated(const QString&)),this,SLOT(slotDeviceCreated(const QString&)));

      if (job==0)
      {
            kDebug() << "Error: unsupported operation!";
      }

        connectJob(job);

      job->start();
      m_loop.exec();

      if (m_error)
      {
            kDebug() << "Error: " << m_errorString;
            KMessageBox::error(0 , m_errorString, "Error during device setup");
      }
}
void BTWizard::createBonding()
{
      if (finalDev->hasBonding())
            finalDev->removeBonding();
      KJob* bondJob = finalDev->createBonding();

      if (bondJob==0)
      {
            kDebug() << "Error: unsupported operation!";
      }

        connectJob(bondJob);

      bondJob->start();
      m_loop.exec();

      if (m_error)
      {
            kDebug() << "Error: " << m_errorString;
            KMessageBox::error(0 , m_errorString, "Error while bonding/pairing device");
      }

}

void BTWizard::connectJob(KJob *job)
{
    connect(job, SIGNAL(result(KJob *)),
             this, SLOT(slotResult(KJob *)));
    connect(job, SIGNAL(percent(KJob *, unsigned long)),
             this, SLOT(slotPercent(KJob *, unsigned long)));
    connect(job, SIGNAL(infoMessage(KJob *, const QString &, const QString &)),
             this, SLOT(slotInfoMessage(KJob *, const QString &)));
}

void BTWizard::slotPercent(KJob* /*job */, unsigned long percent)
{
    kDebug() << "Progress: " <<  percent;
}

void BTWizard::slotInfoMessage(KJob* /*job */, const QString &message)
{
    kDebug() << "Info: " <<  message;
}

void BTWizard::slotResult(KJob *job)
{
    m_error = 0;

    if (job->error())
    {
        m_error = job->error();
        m_errorString = job->errorString();
    }

    m_loop.exit();
}



void BTWizard::slotDeviceCreated(const QString& ubi)
{
      kDebug() << "device created " << ubi;

//        Solid::Control::BluetoothManager &man = Solid::Control::BluetoothManager::self();

//        inputDev = man.createBluetoothInputDevice(ubi);
//    inputDev->slotConnect();
      
//    connect(inputDev,SIGNAL(connected()),this,SLOT(slotDeviceConnected()));
      
//    kDebug() << "device is connected: " << inputDev->isConnected();
      
//    KMessageBox::information(this, "Connection successful established!");

}

void BTWizard::slotDeviceConnected()
{
      kDebug() << "device connected ";

}

void BTWizard::slotCancel()
{
      close();
}

void BTWizard::changeFilterView(const QString& filter)
{
      deviceWidget->clear();
            
      foreach(Solid::Control::BluetoothRemoteDevice* dev,deviceMap) {
            filterList(dev, filter);
      }

}

void BTWizard::filterList(Solid::Control::BluetoothRemoteDevice* dev, const QString& filter)
{
      QString minClass = dev->minorClass();
      QString majClass = dev->majorClass();
      if (minClass == "input-keyboard" && filter == "Keyboard/Mouse") {
            item = new QListWidgetItem(KIcon("input-keyboard"),dev->name() + " - " + dev->address(),deviceWidget);
            deviceWidget->addItem(item);
      } else if ( minClass == "pointing" && filter == "Keyboard/Mouse") {
            item = new QListWidgetItem(KIcon("input-mouse"),dev->name() + " - " + dev->address(),deviceWidget);
            deviceWidget->addItem(item);
      } else if ( majClass == "phone" && filter == "Phones") {
            item = new QListWidgetItem(KIcon("phone"),dev->name() + " - " + dev->address(),deviceWidget);
            deviceWidget->addItem(item);
      } else if(filter == "All") {
            if (minClass == "input-keyboard") {
                  item = new QListWidgetItem(KIcon("input-keyboard"),dev->name() + " - " + dev->address(),deviceWidget);
                  deviceWidget->addItem(item);
            } else if ( minClass == "pointing") {
                  item = new QListWidgetItem(KIcon("input-mouse"),dev->name() + " - " + dev->address(),deviceWidget);
                  deviceWidget->addItem(item);
            } else if ( majClass == "phone") {
                  item = new QListWidgetItem(KIcon("phone"),dev->name() + " - " + dev->address(),deviceWidget);
                  deviceWidget->addItem(item);
            } else if ( majClass == "computer") {
                  item = new QListWidgetItem(KIcon("computer"),dev->name() + " - " + dev->address(),deviceWidget);
                  deviceWidget->addItem(item);
            }

      }
      
}

void BTWizard::checkForHIDDevice(Solid::Control::BluetoothRemoteDevice* device)
{
      kDebug() << "checking HID capabs for " << device->name() << " " << device->ubi();
      device->serviceHandles( HID );
      connect(device,SIGNAL(serviceHandlesAvailable(const QString&, const QList<uint>&)),this,SLOT(slotServiceHandleReady(const QString&, const QList<uint>&)));
}

void BTWizard::slotServiceHandleReady(const QString& ubi, const QList<uint>& handle)
{
      // a HID device is found
      if (handle.size()) {
            kDebug() << "Service Handle for "<< ubi << " ready !: " << handle;
            connLabel->setText(i18n("Connection will be established to this Bluetooth device"));
            connLabel1->setText(i18n("<b>Name: </b>%1",(finalDev->name())));
            connLabel2->setText(i18n("<b>Address: </b>%1",(finalDev->address())));
            connLabel3->setText(i18n("<b>Device class: </b>%1, %2",(finalDev->majorClass()),(finalDev->minorClass())));
            connLabel4->setText(i18n("<b>Manufacturer: </b>%1",(finalDev->manufacturer())));
            connPage->setComplete(true);

      } else 
            connLabel->setText(i18n("The selected Device does not support input services.\nPlease, select an other one."));
}

Generated by  Doxygen 1.6.0   Back to index