diff options
Diffstat (limited to 'kpilot/kpilotProbeDialog.cpp')
-rw-r--r-- | kpilot/kpilotProbeDialog.cpp | 363 |
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); +} + |