summaryrefslogtreecommitdiffstats
path: root/kpilot/kpilotProbeDialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kpilot/kpilotProbeDialog.cpp')
-rw-r--r--kpilot/kpilotProbeDialog.cpp363
1 files changed, 363 insertions, 0 deletions
diff --git a/kpilot/kpilotProbeDialog.cpp b/kpilot/kpilotProbeDialog.cpp
new file mode 100644
index 0000000..da495a4
--- /dev/null
+++ b/kpilot/kpilotProbeDialog.cpp
@@ -0,0 +1,363 @@
+/* conduitConfigDialog.cpp KPilot
+**
+** Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+**
+** This file defines a .ui-based configuration dialog for conduits.
+*/
+
+/*
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-pim@kde.org
+*/
+
+#include "options.h"
+
+#include <tqlayout.h>
+#include <tqgroupbox.h>
+#include <tqlabel.h>
+#include <tqvbox.h>
+#include <tqtimer.h>
+#include <tqptrlist.h>
+#include <tqmap.h>
+#include <tqvaluelist.h>
+
+#include <tdemessagebox.h>
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <tdeconfigskeleton.h>
+#include <tdeapplication.h>
+#include <kprogress.h>
+
+#include "kpilotConfig.h"
+#include "pilotUser.h"
+#include "pilotSysInfo.h"
+#include "options.h"
+#include "kpilotdevicelink.h"
+
+#include "kpilotProbeDialog.moc"
+#include "pilotDaemonDCOP_stub.h"
+
+/*
+We can't connect to /dev/ttyUSB0 and /dev/ttyUSB1 at the same time, because that
+will lock up kpilot completely. In particular, it gets a connection on /dev/ttyUSB0,
+which it processes, and while processing, a connection on USB1 is also detected.
+However, when kpilot gets 'round to process it, the link is already closed, and
+pi_connect hangs forever.
+
+Now, I split up the list of devices to probe into three list, one holding /dev/pilot,
+the second holding all /dev/xxx0 and /dev/xxx2 (e.g. /dev/ttyUSB0 and /dev/ttyUSB2),
+and finally a third holding the remaining /dev/xxx1 and /dev/xxx3 devices. Each of
+these three sets of devices is activated for a few seconds, and then the next set is
+probed. This way, I ensure that kpilot never listens on /dev/ttyUSB0 and /dev/ttyUSB1
+at the same time.
+
+Now the first detection works fine. However, it seems the Linux kernel has another
+problem with /dev/ttyUSB0. I have a Clie, which uses ttyUSB0, and as soon as the
+wizard tries to listen on ttyUSB1 (after it detected the handheld on ttyUSB0 already),
+the kernel writes a warning message to the syslog:
+visor ttyUSB1: Device lied about number of ports, please use a lower one.
+
+If I continue autodetection once again afterwards, the visor module kind of crashes.
+lsmod shows an impossible usage count for the module:
+
+reinhold@einstein:/kde/builddir$ lsmod
+Module Size Used by
+visor 17164 4294967294
+usbserial 30704 1 visor
+
+After that, the kernel doesn't detect the device ever again (until the computer is rebooted),
+and the module can't be unloaded.
+*/
+
+
+ProbeDialog::ProbeDialog(TQWidget *parent, const char *n) :
+ KDialogBase(parent, n, true, i18n("Autodetecting Your Handheld"), KDialogBase::Ok|KDialogBase::Cancel|KDialogBase::User1, KDialogBase::Cancel, true, i18n("Restart Detection")),
+ mDetected(false), mUserName(), mDevice()
+{
+ FUNCTIONSETUP;
+
+ TQVBox *mainWidget = makeVBoxMainWidget();
+
+ fInfoText = new TQLabel( i18n( "KPilot is now trying to automatically detect the device of your handheld. Please press the hotsync button if you have not done so already." ), mainWidget, "fInfoText" );
+ fInfoText->setAlignment( TQLabel::WordBreak );
+
+ fStatusGroup = new TQGroupBox( i18n("Status"), mainWidget, "fStatusGroup" );
+ fStatusGroup->setColumnLayout(0, Qt::Vertical );
+ fStatusGroupLayout = new TQGridLayout( fStatusGroup->layout() );
+
+ fStatus = new TQLabel( i18n("Autodetection not yet started..."), fStatusGroup, "fStatus" );
+ fStatus->setAlignment( TQLabel::WordBreak );
+ fStatusGroupLayout->addWidget( fStatus, 0, 0 );
+
+ fProgress = new KProgress( 100, fStatusGroup, "fProgress" );
+ fStatusGroupLayout->addWidget( fProgress, 1, 0 );
+
+
+
+ fResultsGroup = new TQGroupBox( i18n( "Detected Values" ), mainWidget, "fResultsGroup" );
+ fResultsGroup->setEnabled( FALSE );
+ fResultsGroup->setColumnLayout(0, Qt::Vertical );
+ fResultsGroupLayout = new TQGridLayout( fResultsGroup->layout() );
+ fResultsGroupLayout->setAlignment( TQt::AlignTop );
+
+ fUserLabel = new TQLabel( i18n( "Handheld user:" ), fResultsGroup, "fUserLabel" );
+ fUserLabel->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)4, (TQSizePolicy::SizeType)5, 0, 0, fUserLabel->sizePolicy().hasHeightForWidth() ) );
+ fResultsGroupLayout->addWidget( fUserLabel, 0, 0 );
+
+ fDeviceLabel = new TQLabel( i18n( "Device:" ), fResultsGroup, "fDeviceLabel" );
+ fResultsGroupLayout->addWidget( fDeviceLabel, 1, 0 );
+
+ fUser = new TQLabel( i18n("[Not yet known]"), fResultsGroup, "fUser" );
+ fResultsGroupLayout->addWidget( fUser, 0, 1 );
+
+ fDevice = new TQLabel( i18n("[Not yet known]"), fResultsGroup, "fDevice" );
+ fResultsGroupLayout->addWidget( fDevice, 1, 1 );
+
+
+ resize( TQSize(459, 298).expandedTo(minimumSizeHint()) );
+ clearWState( WState_Polished );
+ enableButtonOK(false);
+
+ mDevicesToProbe[0] << "/dev/pilot";
+ mDevicesToProbe[1] <<"/dev/ttyS0"<<"/dev/ttyS2"
+ <<"/dev/tts/0"<<"/dev/tts/2"
+ <<"/dev/ttyUSB0"<<"/dev/ttyUSB2"
+ <<"/dev/usb/tts/0"<<"/dev/usb/tts/2"
+ <<"/dev/cuaa0"<<"/dev/cuaa2"
+ <<"/dev/cuad0"<<"/dev/cuad2"
+ <<"/dev/ucom0"<<"/dev/ucom2";
+ mDevicesToProbe[2] <<"/dev/ttyS1"<<"/dev/ttyS3"
+ <<"/dev/tts/1"<<"/dev/tts/3"
+ <<"/dev/ttyUSB1"<<"/dev/ttyUSB3"
+ <<"/dev/usb/tts/1"<<"/dev/usb/tts/3"
+ <<"/dev/cuaa1"<<"/dev/cuaa3"
+ <<"/dev/cuad1"<<"/dev/cuad3"
+ <<"/dev/ucom1"<<"/dev/ucom3";
+
+ fProcessEventsTimer = new TQTimer( this );
+ fTimeoutTimer = new TQTimer( this );
+ fProgressTimer = new TQTimer( this );
+ fRotateLinksTimer = new TQTimer( this );
+ connect( fProcessEventsTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(processEvents()) );
+ connect( fTimeoutTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeout()) );
+ connect( fProgressTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT( progress()) );
+ connect( fRotateLinksTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT( detect()) );
+ connect( this, TQT_SIGNAL(finished()), this, TQT_SLOT(disconnectDevices()) );
+}
+
+ProbeDialog::~ProbeDialog()
+{
+ FUNCTIONSETUP;
+}
+
+void ProbeDialog::processEvents()
+{
+ FUNCTIONSETUP;
+ TDEApplication::kApplication()->processEvents();
+}
+
+void ProbeDialog::progress()
+{
+ fProgress->advance(1);
+}
+
+int ProbeDialog::exec()
+{
+ mDetected = false;
+ mUserName = TQString();
+ mDevice = TQString();
+ TQTimer::singleShot( 0, this, TQT_SLOT( startDetection() ) );
+ return KDialogBase::exec();
+}
+
+void ProbeDialog::startDetection()
+{
+ FUNCTIONSETUP;
+
+ disconnectDevices();
+ fProgress->setProgress(0);
+ fStatus->setText( i18n("Starting detection...") );
+ TQTimer::singleShot(0, this, TQT_SLOT(processEvents()) );
+ processEvents();
+ PilotDaemonDCOP_stub *daemonStub = new PilotDaemonDCOP_stub("kpilotDaemon", "KPilotDaemonIface");
+ if (daemonStub) {
+ daemonStub->stopListening();
+ }
+ KPILOT_DELETE(daemonStub);
+ processEvents();
+ if (!fTimeoutTimer->start( 30000, true ) )
+ {
+ WARNINGKPILOT << "Could not start fTimeoutTimer" << endl;
+ }
+ if (!fProcessEventsTimer->start( 100, false ) )
+ {
+ WARNINGKPILOT << "Could not start fProcessEventsTimer" << endl;
+ }
+ if (!fProgressTimer->start( 300, false) )
+ {
+ WARNINGKPILOT << "Could not start Progress timer" << endl;
+ }
+
+ KPilotDeviceLink*link;
+ for (int i=0; i<3; i++)
+ {
+ TQStringList::iterator end(mDevicesToProbe[i].end());
+ for (TQStringList::iterator it=mDevicesToProbe[i].begin(); it!=end; ++it)
+ {
+ link = new KPilotDeviceLink();
+ link->setDevice((*it));
+#ifdef DEBUG
+ DEBUGKPILOT<<"new kpilotDeviceLink for "<<(*it)<<endl;
+#endif
+ mDeviceLinks[i].append( link );
+ connect( link, TQT_SIGNAL(deviceReady(KPilotDeviceLink*)), this, TQT_SLOT(connection(KPilotDeviceLink*)) );
+ processEvents();
+ }
+ }
+ fStatus->setText( i18n("Waiting for handheld to connect...") );
+ mProbeDevicesIndex=0;
+
+ detect();
+ if (!fRotateLinksTimer->start( 3000, false) )
+ {
+ WARNINGKPILOT << "Could not start Device link rotation timer" << endl;
+ }
+}
+
+
+void ProbeDialog::detect(int i)
+{
+ FUNCTIONSETUP;
+
+ mProbeDevicesIndex = i;
+ PilotLinkList::iterator end(mDeviceLinks[mProbeDevicesIndex].end());
+
+ for (PilotLinkList::iterator it=mDeviceLinks[mProbeDevicesIndex].begin(); it!=end; ++it)
+ {
+ if (*it) (*it)->reset();
+ }
+}
+
+void ProbeDialog::detect()
+{
+ detect( (mProbeDevicesIndex+1)%3 );
+}
+
+void ProbeDialog::timeout()
+{
+ disconnectDevices();
+ if (!mDetected) {
+ fStatus->setText( i18n("Timeout reached, could not detect a handheld.") );
+ KMessageBox::information ( this, i18n("<qt>A handheld could not be detected. Possible check the following things:</p>"
+ "<ul><li> Have you pressed the hotsync button on the handheld?\n"
+ "<li> Make sure the device sits in the cradle correctly.\n"
+ "<li> Make sure the cradle is correctly plugged in to the computer.\n"
+ "<li> Have you checked that your device is actually supported by kpilot (see http://www.kpilot.org).\n"
+ "</ul>"
+ ), i18n("Automatic Detection Failed"), "AutoDetectionFailed");
+ }
+}
+
+void ProbeDialog::connection( KPilotDeviceLink*lnk)
+{
+ FUNCTIONSETUP;
+
+ mActiveLink = lnk;
+ if ( !mActiveLink ) return;
+ const KPilotUser &usr( mActiveLink->getPilotUser() );
+
+ mUserName = usr.name();
+ mDevice = mActiveLink->pilotPath();
+
+ fStatus->setText( i18n("Found a connected device on %1").arg(mDevice) );
+ fUser->setText( mUserName );
+ fDevice->setText( mDevice );
+ mDetected = true;
+
+ fResultsGroup->setEnabled( true );
+ enableButtonOK(true);
+
+ TQTimer::singleShot(0, this, TQT_SLOT(retrieveDBList()));
+}
+
+void ProbeDialog::retrieveDBList()
+{
+ KPilotLink::DBInfoList dbs = mActiveLink->getDBList();
+ mDBs.clear();
+ char buff[7];
+ buff[0] = '[';
+
+ for ( KPilotLink::DBInfoList::ConstIterator i = dbs.begin();
+ i != dbs.end(); ++i )
+ {
+ set_long( &buff[1], (*i).creator );
+ buff[5] = ']';
+ buff[6] = '\0';
+ TQString cr( buff );
+ mDBs << cr;
+ mDBs << TQString( (*i).name );
+ }
+ mDBs.sort();
+
+ TQString old( TQString::null );
+ TQStringList::Iterator itr = mDBs.begin();
+ while ( itr != mDBs.end() ) {
+ if ( old == *itr ) {
+ itr = mDBs.remove( itr );
+ } else {
+ old = *itr;
+ ++itr;
+ }
+ }
+
+ // End sync gracefully, but don't change settings on the handheld.
+ mActiveLink->endSync( KPilotLink::NoUpdate );
+
+ TQTimer::singleShot(0, this, TQT_SLOT(disconnectDevices()));
+}
+void ProbeDialog::disconnectDevices()
+{
+ FUNCTIONSETUP;
+
+ if (!mDetected) fStatus->setText( i18n("Disconnected from all devices") );
+ fProcessEventsTimer->stop( );
+ fTimeoutTimer->stop();
+ fProgressTimer->stop();
+ fRotateLinksTimer->stop();
+ fProgress->setProgress(fProgress->totalSteps());
+ for (int i=0; i<3; ++i)
+ {
+ PilotLinkList::iterator end(mDeviceLinks[i].end());
+ for (PilotLinkList::iterator it=mDeviceLinks[i].begin(); it!=end; ++it)
+ {
+ (*it)->close();
+ KPILOT_DELETE(*it);
+ }
+ mDeviceLinks[i].clear();
+ }
+
+
+ PilotDaemonDCOP_stub *daemonStub = new PilotDaemonDCOP_stub("kpilotDaemon", "KPilotDaemonIface");
+ if (daemonStub)
+ {
+ daemonStub->startListening();
+ }
+ KPILOT_DELETE(daemonStub);
+}
+