/* 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 , TQt : : 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 , TQt : : 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 , TQ_SIGNAL ( timeout ( ) ) , this , TQ_SLOT ( processEvents ( ) ) ) ;
connect ( fTimeoutTimer , TQ_SIGNAL ( timeout ( ) ) , this , TQ_SLOT ( timeout ( ) ) ) ;
connect ( fProgressTimer , TQ_SIGNAL ( timeout ( ) ) , this , TQ_SLOT ( progress ( ) ) ) ;
connect ( fRotateLinksTimer , TQ_SIGNAL ( timeout ( ) ) , this , TQ_SLOT ( detect ( ) ) ) ;
connect ( this , TQ_SIGNAL ( finished ( ) ) , this , TQ_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 , TQ_SLOT ( startDetection ( ) ) ) ;
return KDialogBase : : exec ( ) ;
}
void ProbeDialog : : startDetection ( )
{
FUNCTIONSETUP ;
disconnectDevices ( ) ;
fProgress - > setProgress ( 0 ) ;
fStatus - > setText ( i18n ( " Starting detection... " ) ) ;
TQTimer : : singleShot ( 0 , this , TQ_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 , TQ_SIGNAL ( deviceReady ( KPilotDeviceLink * ) ) , this , TQ_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 , TQ_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 , TQ_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 ) ;
}