#!/usr/bin/env python

"""
v 4.9

kAnyRemote
KDE GUI for anyRemote - a bluetooth remote for your PC.

Copyright (C) 2007,2008 Mikhail Fedotov <anyremote@mail.ru>

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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
"""

import os
import re
import signal
import socket
import SocketServer
import sys
import sys
import threading
import thread
import time
from sets import Set

try:
    from qt import *
except ImportError:
   print 'Install PyQT first !!!'
   quit()

try:
   from kdecore import KAboutData, KApplication, KCmdLineArgs, KIcon, KIconLoader
   from kdeui import KAboutApplication, KSystemTray, KTextEdit
   from kfile import KURLRequester
   from dcopexport import DCOPExObj
except ImportError:
   print 'Install PyKDE first !!!'
   quit()

pybluez = True 
try:
    import bluetooth
except ImportError:
   pybluez = False


signal.signal(signal.SIGINT, signal.SIG_DFL)

##################################################################################
#
# Blink Icon class
#
##################################################################################

class BlinkThread(QThread):
        def __init__(self,receiver):
            QThread.__init__(self) 
	    self.receiver = receiver

        def run(self):
	   sendEvent(self.receiver,20001," ") 
	   time.sleep(0.2)
	   sendEvent(self.receiver,20002," ") 
	   
##################################################################################
#
# Reader of cfg. files
#
##################################################################################
class CfgFileReader(threading.Thread):

    def __init__(self, receiver, cReader):
	threading.Thread.__init__(self)
	self.receiver = receiver
	self.cfgDirs  = cReader.cfgDirs
	self.all      = cReader.showAll_
	self.apps     = cReader.showApps_
	self.cust     = cReader.showCustom_
	self.ex       = cReader.showExamples_ 
	self.at       = cReader.showAt_
	self.srv      = cReader.showSrv_   
	self.bm       = cReader.showBm_   

    def run(self):
        global debug
	
	if debug:
	    print 'CfgFileReader.run'
	
	self.regExp  = re.compile("^[^a-zA-Z0-9]*Gui")
	#self.regExp1 = re.compile("^[^a-zA-Z0-9%]*Device[^=]*=[^a-zA-Z0-9]*bluetooth.+$")
	#self.regExp2 = re.compile("^[^a-zA-Z0-9%]*Device[^=]*=[^a-zA-Z0-9]*socket.+$")
	self.regExpB = re.compile("^[^a-zA-Z0-9%]*VERS[^=]*=.+$")
	self.regExpAT = re.compile("^[^a-zA-Z0-9%]*Device[^=]*=/dev/[a-zA-Z0-9]+$")

	for cfgDir in self.cfgDirs:
	    
	    if cfgDir == '':
	        continue
	    if debug: 
	        print 'Collect files in '+cfgDir
	    
	    self.idx = 0
	    if os.path.isfile(cfgDir):
	        self.processOneFile(cfgDir)
	    else:
	        for root, dirs, files in os.walk(cfgDir):
	            for cfgFile in files:
	    	        self.processOneFile(root + os.sep + cfgFile)
			
	# start StatusUpdater if needed
	sendEvent(self.receiver, 20007, '')
	    
    def processOneFile(self,cfgFile):
        global debug, iconsK, appData, lastCfgFile
	
	fd = open(cfgFile,'r')
	if fd:
	    aName    = ''
	    aInst    = ''
	    aRun     = ''
	    aIcon    = ''
	    aType    = ''
	    aDevice  = ''
	    aBemused = ''
	
            for line in fd:
	
		if self.regExp.match(line):

	    	    p = re.search("^[^a-zA-Z0-9]*GuiAppName[^=]*=(.+)$", line)
	    	    if p != None:
	    		aName = p.group(1)

	    	    p = re.search("^[^a-zA-Z0-9]*GuiAppBinary[^=]*=(.+)$", line)
	    	    if p != None:
	    		aInst = p.group(1)
	    	
	    	    p = re.search("^[^a-zA-Z0-9]*GuiAppRun[^=]*=(.+)$", line)
	    	    if p != None:
	    		aRun = p.group(1)
	       
	    	    p = re.search("^[^a-zA-Z0-9]*GuiAppIcon[^=]*=(.+)$", line)
	    	    if p != None:
	    		aIcon = p.group(1)

	    	    p = re.search("^[^a-zA-Z0-9]*GuiAppType[^=]*=(.+)$", line)
	    	    if p != None:
	    		aType = p.group(1)
		
		

	    	if self.regExpAT.match(line):
	    	    aDevice = 'a'

	    	#if self.regExp1.match(line):
	    	#    aDevice = 's'

	    	#if self.regExp2.match(line):
	    	#    aDevice = 's'

	    	if self.regExpB.match(line):
	    	    aBemused = 1
	
	    aMode = 'Server'    
	    if aBemused == 1:
		aMode = 'Bemused'
	    elif aDevice == 'a':
		aMode = 'AT'
	    	
	    if aName == '':
	    	aName = os.path.basename(cfgFile)
	    	
	    if aInst == '':
	    	isInst = 'No information'
	    else:
	    	isInst = isInstalled(aInst)

	    show = 1
	    status = ''
	    if isInst == 'OK':
	    	status = 'Available'
	    elif isInst == 'NOK':
	        status = 'Not available'
		if not self.all:
	            show = 0
	    
	    if not self.all:
	    	if aMode == 'AT' and not self.at:
	    	    show = 0
	    	elif aMode == 'Server' and not self.srv:
	    	    show = 0
	        elif aMode == 'Bemused' and not self.bm:
	    	    show = 0
	    
	        if aType == 'Application' and not self.apps:
	            show = 0
	        elif aType == 'Custom' and not self.cust:
	            show = 0
	        elif aType == 'Example' and not self.ex :
	            show = 0
	        elif aType == '':
	            show = 0
		    
            if show == 1:
		if debug:
	    	    print 'Proceed with '+aName
	
	    	if aIcon == '':
	    	    aIcon = 'filenew.png'
	    
		pbuf = iconsK.loadIcon(aIcon, KIcon.Small)
		
                isRun = 'No Information'
	    	if aRun != '':
	    	    isRun  = getResult(aRun,'reader')

		appData[self.idx] = [aName, pbuf, aInst, aRun, isRun, cfgFile, status, aMode, aType]
	    	sendEvent(self.receiver, 20004, [aName, pbuf, isRun, status, aMode, aType, self.idx])
			
		self.idx = self.idx + 1
		
	    else:
		if debug:
	    	    #print 'Skip '+aName
		    pass
	    	
	    fd.close()
	    
##################################################################################
#
# Device Browser
#
##################################################################################
class DeviceBrowser(QMainWindow):

    def __init__(self,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)

        if not name:
            self.setName("DeviceBrowser")

        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        DeviceBrowserLayout = QGridLayout(self.centralWidget(),1,1,11,6,"DeviceBrowserLayout")

        self.treeview = QListView(self.centralWidget(),"treeview")
        self.treeview.addColumn(self.__tr("Name       "))
        self.treeview.addColumn(self.__tr("Device Name"))
        self.treeview.addColumn(self.__tr("Address          "))
        self.treeview.addColumn(self.__tr("Status       "))

        DeviceBrowserLayout.addWidget(self.treeview,0,0)

        self.scanAction    = QAction(self,"scanAction")
        self.detailsAction = QAction(self,"detailsAction")
        self.deleteAction  = QAction(self,"deleteAction")
        self.closeAction   = QAction(self,"closeAction")

        self.MenuBar = QMenuBar(self,"MenuBar")

        self.fileMenu = QPopupMenu(self)
        self.scanAction.addTo   (self.fileMenu)
        self.detailsAction.addTo(self.fileMenu)
        self.deleteAction.addTo (self.fileMenu)
        self.closeAction.addTo  (self.fileMenu)
        self.MenuBar.insertItem(QString(""),self.fileMenu,1)

        self.languageChange()

        self.resize(QSize(500,250).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

        self.connect(self.scanAction,   SIGNAL("activated()"),self.scan)
        self.connect(self.detailsAction,SIGNAL("activated()"),self.details)
        self.connect(self.deleteAction, SIGNAL("activated()"),self.deleteDev)
        self.connect(self.closeAction,  SIGNAL("activated()"),self.closeAct)

	self.connect(self.treeview,SIGNAL('doubleClicked(QListViewItem*, const QPoint&, int)'), self.listDClicked)
	
	self.treeview.setColumnWidthMode (0,QListView.Maximum) 
	self.treeview.setColumnWidthMode (1,QListView.Maximum) 
	self.treeview.setColumnWidthMode (2,QListView.Maximum) 
	self.treeview.setColumnWidthMode (3,QListView.Maximum) 
	
	self.treeview.setMultiSelection(False)
	self.treeview.setSortColumn(0)
	
	self.populateDeviceList()

    def languageChange(self):
        self.setCaption(self.__tr("kAnyRemote device browser"))
        self.treeview.header().setLabel(0,self.__tr("Name"))
        self.treeview.header().setLabel(1,self.__tr("Device Name"))
        self.treeview.header().setLabel(2,self.__tr("Address"))
        self.treeview.header().setLabel(3,self.__tr("Status"))
        self.treeview.clear()
        item = QListViewItem(self.treeview,None)

        self.scanAction.setText(self.__trUtf8("Scan for devices"))
        self.scanAction.setMenuText(self.__trUtf8("Scan for devices"))
        self.scanAction.setAccel(self.__tr("Ctrl+S"))
        self.detailsAction.setText(self.__trUtf8("Details"))
        self.detailsAction.setMenuText(self.__trUtf8("Details"))
        self.detailsAction.setAccel(self.__tr("Ctrl+D"))
        self.deleteAction.setText(self.__trUtf8("Delete"))
        self.deleteAction.setMenuText(self.__trUtf8("Delete"))
        self.deleteAction.setAccel(self.__tr("Ctrl+E"))
        self.closeAction.setText(self.__trUtf8("Close"))
        self.closeAction.setMenuText(self.__trUtf8("Close"))
        self.closeAction.setAccel(QString.null)
        if self.MenuBar.findItem(1):
            self.MenuBar.findItem(1).setText(self.__tr("&File"))
	
	self.detailsWin = None
	self.selected = None

    def populateDeviceList(self):
        global bt_devices
	self.treeview.clear()
	
	for k, v in bt_devices.iteritems():
            lvi = QListViewItem(self.treeview)
            lvi.setText(0,bt_devices[k][2])       
            lvi.setText(1,bt_devices[k][1])
            lvi.setText(2,bt_devices[k][0])
            lvi.setText(3,bt_devices[k][4])

    def scan(self):
        browseDevices()

    def details(self):
        global bt_devices
	
	item = self.treeview.selectedItem()
    	if item == None:
	    return
	try:
	    row = bt_devices[str(item.text(2))]
	except KeyError:
	    print 'DeviceBrowser.details: KeyError'
	    return
	    
        showDetailsWin(row[0],row[1],row[2],row[3],False)

    def listDClicked(self,
     listItem, point, column):
	self.details()

    def deleteDev(self):
        global bt_devices
	
	item = self.treeview.selectedItem()
	self.treeview.takeItem(item)

    def closeAct(self):
        self.hide()

    def customEvent(self,event):
        if event.type() == 30000:
           self.populateDeviceList()

    def __tr(self,s,c = None):
        return qApp.translate("DeviceBrowser",s,c)

    def __trUtf8(self,s,c = None):
        return qApp.translate("DeviceBrowser",s,c,QApplication.UnicodeUTF8)

##################################################################################
#
# Device Details
#
##################################################################################
class DeviceDetail(QMainWindow):
    def __init__(self, ba, m, n, act, is_new, jDir, parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)
        self.statusBar()

	self.model     = str(m).replace('\n','')
	self.dname     = str(n).replace('\n','')
	self.btAddr    = str(ba)
	self.cfile     = str(act)
	self.isNew     = str(is_new)
	self.midletDir = jDir

        if not name:
            self.setName("DeviceDetail")

        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        DeviceDetailLayout = QGridLayout(self.centralWidget(),1,1,11,6,"DeviceDetailLayout")

        self.deviceNameValue = QLabel(self.centralWidget(),"deviceNameValue")
        DeviceDetailLayout.addWidget(self.deviceNameValue,0,2)

        self.btAddress = QLabel(self.centralWidget(),"btAddress")
        DeviceDetailLayout.addMultiCellWidget(self.btAddress,0,0,4,5)
        self.btAddressValue = QLabel(self.centralWidget(),"btAddressValue")
        DeviceDetailLayout.addMultiCellWidget(self.btAddressValue,0,0,6,7)

        self.deviceName = QLabel(self.centralWidget(),"deviceName")
        DeviceDetailLayout.addMultiCellWidget(self.deviceName,0,0,0,1)

        self.specifyName = QLabel(self.centralWidget(),"specifyName")
        DeviceDetailLayout.addMultiCellWidget(self.specifyName,1,1,0,1)

        self.runWhen = QCheckBox(self.centralWidget(),"runWhen")
        DeviceDetailLayout.addMultiCellWidget(self.runWhen,2,2,0,7)
	QToolTip.add(self.runWhen, 'anyRemote will be run only if no other instances of anyRemote runned');
	
        self.fileWhen = QLineEdit(self.centralWidget(),"fileWhen")
        DeviceDetailLayout.addMultiCellWidget(self.fileWhen,3,3,0,6)
        self.choose = QPushButton(self.centralWidget(),"choose")
        DeviceDetailLayout.addWidget(self.choose,3,7)

        self.devName = QLineEdit(self.centralWidget(),"devName")
        DeviceDetailLayout.addMultiCellWidget(self.devName,1,1,2,7)
	
        spacer1 = QSpacerItem(20,16,QSizePolicy.Minimum,QSizePolicy.Expanding)
        DeviceDetailLayout.addMultiCell(spacer1,4,4,2,3)

	self.kSeparator1 = QFrame(self.centralWidget(),"kSeparator1")
        self.kSeparator1.setFrameShape(QFrame.HLine)
        self.kSeparator1.setFrameShadow(QFrame.Sunken)
        self.kSeparator1.setFrameShape(QFrame.HLine)
        DeviceDetailLayout.addMultiCellWidget(self.kSeparator1,5,5,0,7)

        self.uploadjava = QPushButton(self.centralWidget(),"uploadjava")
        DeviceDetailLayout.addWidget(self.uploadjava,6,0)
	
        self.iSet = QLabel(self.centralWidget(),"iSet")
        DeviceDetailLayout.addMultiCellWidget(self.iSet,6,6,1,2)
	
        spacer2 = QSpacerItem(40,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        DeviceDetailLayout.addItem(spacer2,6,2)
	
        self.sz16 = QCheckBox(self.centralWidget(),"sz16")
        DeviceDetailLayout.addWidget(self.sz16,6,3)
	self.sz16.setChecked(True)

        self.sz32 = QCheckBox(self.centralWidget(),"sz32")
        DeviceDetailLayout.addWidget(self.sz32,6,4)

        self.sz64 = QCheckBox(self.centralWidget(),"sz64")
        DeviceDetailLayout.addWidget(self.sz64,6,5)

        self.javaSize = QCheckBox(self.centralWidget(),"javaSize")
        DeviceDetailLayout.addMultiCellWidget(self.javaSize,6,6,6,7)
	QToolTip.add(self.javaSize, '16x16 and 64x64 title icons are available');
	
	
        self.ping = QPushButton(self.centralWidget(),"ping")
        DeviceDetailLayout.addWidget(self.ping,7,0)
        self.testat = QPushButton(self.centralWidget(),"testat")
        DeviceDetailLayout.addWidget(self.testat,7,1)
	
        spacer2 = QSpacerItem(40,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        DeviceDetailLayout.addItem(spacer2,7,2)

        self.close = QPushButton(self.centralWidget(),"Close")
        DeviceDetailLayout.addWidget(self.close,7,6)
        self.ok = QPushButton(self.centralWidget(),"Ok")
        DeviceDetailLayout.addWidget(self.ok,7,7)

        self.languageChange()

        self.resize(QSize(450,200).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)
        
	self.connect(self.choose,     SIGNAL("clicked()"),self.chooseAction)
	self.connect(self.ping,       SIGNAL("clicked()"),self.pingAction)
        self.connect(self.testat,     SIGNAL("clicked()"),self.testatAction)
        self.connect(self.uploadjava, SIGNAL("clicked()"),self.uploadjAction)
        self.connect(self.close,      SIGNAL("clicked()"),self.closeAction)
        self.connect(self.ok,         SIGNAL("clicked()"),self.okAction)
        
	self.connect(self.runWhen,    SIGNAL("toggled(bool)"),self.runWhenChecked)
	
	self.connect(self.sz16,     SIGNAL("toggled(bool)"),self.clicked_sz16)
	self.connect(self.sz32,     SIGNAL("toggled(bool)"),self.clicked_sz32)
	self.connect(self.sz64,     SIGNAL("toggled(bool)"),self.clicked_sz64)
	self.connect(self.javaSize, SIGNAL("toggled(bool)"),self.clicked_bti)

	self.deviceNameValue.setText(self.model)
	self.btAddressValue.setText(self.btAddr)
	self.devName.setText(self.dname);
	
	if self.cfile == '':
	   self.fileWhen.setEnabled(False)
	   self.choose.setEnabled(False)
	else:
	   self.fileWhen.setEnabled(True)
	   self.fileWhen.setText(self.cfile)
	   self.runWhen.setChecked(True)
	   self.choose.setEnabled(True)
	
	if not os.path.isdir(self.midletDir): 
	    self.uploadjava.setEnabled(False)
	    self.javaSize.setEnabled(False)
	    QToolTip.add(self.uploadjava, 'It needs to install anyremote-J2ME-client package first');

 	bt = btVerify(self,False)
	if bt == 'NOK':
	    if debug:
	         print 'DeviceDetail: Bluetooth not active'
	    self.ping.setEnabled(False)
	    self.testat.setEnabled(False)
	    self.uploadjava.setEnabled(False)
	    self.javaSize.setEnabled(False)
	    QToolTip.add(self.ping, 'Bluetooth service is not active');
	    QToolTip.add(self.testat, 'Bluetooth service is not active');


    def runWhenChecked(self,w):
	if self.runWhen.isChecked():
	   self.fileWhen.setEnabled(True)
	   self.choose.setEnabled(True)
	else:
	   self.fileWhen.setEnabled(False)
	   self.fileWhen.setText('')
	   self.choose.setEnabled(False)

    def clicked_sz16(self,w):
        if not self.sz16.isChecked():
           self.sz16.setChecked(True)   # do not allow to reset
           self.sz32.setChecked(False)
           self.sz64.setChecked(False)

    def clicked_sz32(self,w):
        if self.sz32.isChecked():
           self.sz16.setChecked(True)
        else:
           self.sz64.setChecked(False)

    def clicked_sz64(self,w):
        if self.sz64.isChecked():
           self.sz16.setChecked(True)
           self.sz32.setChecked(True)
           self.javaSize.setChecked(True)

    def clicked_bti(self,w):
        if not self.javaSize.isChecked():
           self.sz64.setChecked(False)
    
    def chooseAction(self):
    	global chooserWin
	chooserWin = Chooser()
	chooserWin.show()

    def close(self,arg):
        self.closeAction()

    def closeAction(self):
        self.hide()
    
    def sendReRead(self):
    	global browserWin
	sendEvent(browserWin,30000," ") 
    
    def okAction(self):
    	global bt_devices

	for k, v in bt_devices.iteritems():
	    
	    row = bt_devices[k]
	    addr = row[0]
	    
	    if self.btAddr == addr:

	    	if self.devName.text() != row[2]:
	            row[2] = self.devName.text()
		    
	    	if self.model != row[1]:
	           row[1] = self.model

		cf = self.fileWhen.text()
	    	if cf != row[3]:
	            row[3] = cf
		
		self.sendReRead()
		self.hide()
		return

	bt_devices[self.btAddr] = [self.btAddr,self.model,str(self.devName.text()),str(self.fileWhen.text()),'Available']

	self.sendReRead()
        self.hide()
    
    def testatAction(self):
        global debug
	if debug: print 'Queue test AT'
	    
	stopPBar() 
	pbar = runPBar('Wait other operations to finish',30)
	queueBT('test_at',self.btAddr)
    
    def uploadjAction(self):
        global debug
	if debug: print 'Queue push request'
	
	sz = '16'
	if self.sz32.isChecked():
	   sz = '32'
	if self.sz64.isChecked():
	   sz = '64'
	if self.javaSize.isChecked():
	   sz = sz+'b'
	stopPBar() 
	pbar = runPBar('Wait other operations to finish',20)
	queueBT('push'+sz,self.btAddr)
    
    def pingAction(self):
        global debug
	if debug: print 'Queue ping request'

	stopPBar() 
	pbar = runPBar('Wait ping results',20)
	queueBT('ping',self.btAddr)
	
    def setStatustext(self,text):
        global debug
        if debug: print 'DeviceDetail.setStatustext ' + text
        self.statusBar().clear()
        self.statusBar().message(text)

    def customEvent(self,event):
        if event.type() == 31000:
	    self.cfile = event.data()
	    self.fileWhen.setText(self.cfile)

    def languageChange(self):
        self.setCaption(self.__tr("Device Parameters"))
        self.deviceNameValue.setText(QString.null)
        self.btAddress.setText(self.__tr("BT address:"))
        self.btAddressValue.setText(QString.null)
        self.deviceName.setText(self.__tr("Device Name:"))
        self.specifyName.setText(self.__tr("Specify Name:"))
        self.iSet.setText(self.__tr(" with icon set "))
        self.runWhen.setText(self.__tr("Run anyRemote when discovered."))
        self.javaSize.setText(self.__tr("use big title icon"))
        self.sz16.setText(self.__tr("16x16"))
        self.sz32.setText(self.__tr("32x32"))
        self.sz64.setText(self.__tr("64x64"))
        self.choose.setText(self.__tr("Choose"))
        self.ping.setText(self.__tr("Ping"))
        self.uploadjava.setText(self.__tr("Upload Java"))
        self.testat.setText(self.__tr("Test AT"))
        self.close.setText(self.__tr("Close"))
        self.ok.setText(self.__tr("Ok"))

    def __tr(self,s,c = None):
        return qApp.translate("DeviceDetail",s,c)

##################################################################################
#
# Configuration checker
#
##################################################################################
class CfgChecker(QMainWindow):

    def __init__(self,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)

        if not name: self.setName("CfgChecker")

        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        CfgCheckerLayout = QGridLayout(self.centralWidget(),1,1,11,6,"CfgCheckerLayout")

        self.treeview = QListView(self.centralWidget(),"treeview")
        self.treeview.addColumn(self.__tr("Package"))
        self.treeview.addColumn(self.__tr("Status"))

        CfgCheckerLayout.addWidget(self.treeview,0,0)

        self.closeAction   = QAction(self,"closeAction")

        self.MenuBar = QMenuBar(self,"MenuBar")

        self.fileMenu = QPopupMenu(self)
        self.closeAction.addTo  (self.fileMenu)
        self.MenuBar.insertItem(QString(""),self.fileMenu,1)

        self.languageChange()

        self.resize(QSize(300,200).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

        self.connect(self.closeAction,  SIGNAL("activated()"),self.closeAct)
	
	self.treeview.setColumnWidthMode (0,QListView.Maximum) 
	self.treeview.setColumnWidthMode (1,QListView.Maximum) 
	
	self.treeview.setMultiSelection(False)
	self.treeview.setSortColumn(0)
	
    	pbs = 'Not installed'
	if pybluez: pbs = 'Installed'
	
        ars = isInstalled('anyremote')
        if ars == 'NOK':
	    ars = 'Not installed'
        else:
            ars = 'Installed'

        bus = isInstalled('sdptool')
        if bus == 'NOK':
	    bus = 'Not installed'
        else:
            bus = 'Installed'

        ajs = getJ2MEPath()
        if ajs == '':
	    ajs = 'Not installed'
        else:
            ajs = 'Installed'

        ahs = isInstalled('anyremote2html')
        if ahs == 'NOK':
	    ahs = 'Not installed'
        else:
            ahs = 'Installed'
    
        lvi = QListViewItem(self.treeview)
        lvi.setText(0,"anyRemote")       
        lvi.setText(1,ars)
	
        lvi = QListViewItem(self.treeview)
        lvi.setText(0,"Bluez utilities")       
        lvi.setText(1,bus)

        lvi = QListViewItem(self.treeview)
        lvi.setText(0,"PyBluez")       
        lvi.setText(1,pbs)

        lvi = QListViewItem(self.treeview)
        lvi.setText(0,"anyremote-J2ME-client")       
        lvi.setText(1,ajs)

        lvi = QListViewItem(self.treeview)
        lvi.setText(0,"anyremote2html")       
        lvi.setText(1,ahs)
 
    def languageChange(self):
        self.setCaption(self.__tr("kAnyRemote configuration checker"))
        self.treeview.header().setLabel(0,self.__tr("Package"))
        self.treeview.header().setLabel(1,self.__tr("Status"))
        self.treeview.clear()
        item = QListViewItem(self.treeview,None)

        self.closeAction.setText(self.__trUtf8("Close"))
        self.closeAction.setMenuText(self.__trUtf8("Close"))
        self.closeAction.setAccel(QString.null)
        if self.MenuBar.findItem(1):
            self.MenuBar.findItem(1).setText(self.__tr("&File"))
	
	self.cfgChkWin = None
	self.selected = None

    def closeAct(self):
        self.hide()

    def __tr(self,s,c = None):
        return qApp.translate("CfgChecker",s,c)

    def __trUtf8(self,s,c = None):
        return qApp.translate("CfgChecker",s,c,QApplication.UnicodeUTF8)

##################################################################################
#
# Choose app. to manage when phone is discovered
#
##################################################################################

class Chooser(QMainWindow):

    def __init__(self,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)

        if not name:
            self.setName("Choose application")

        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        Form1Layout = QGridLayout(self.centralWidget(),1,1,11,6,"Form1Layout")

        self.listView1 = QListView(self.centralWidget(),"listView1")
        self.listView1.addColumn(self.__tr("Application"))
        self.listView1.addColumn(self.__tr("Mode"))
        self.listView1.addColumn(self.__tr("F"))

	self.listView1.setColumnWidthMode (0,QListView.Maximum) 
	self.listView1.setColumnWidthMode (1,QListView.Maximum) 
	self.listView1.setColumnWidthMode (2,QListView.Manual) 
	
	self.listView1.setMultiSelection(False)
	self.listView1.setSortColumn(0)
	self.listView1.hideColumn(2)
	
        Form1Layout.addMultiCellWidget(self.listView1,0,0,0,1)

        self.cancel = QPushButton(self.centralWidget(),"cancel")
        Form1Layout.addWidget(self.cancel,1,1)

        self.ok = QPushButton(self.centralWidget(),"ok")

        Form1Layout.addWidget(self.ok,1,0)

        self.languageChange()

        self.resize(QSize(350,400).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

	self.connect(self.cancel, SIGNAL("clicked()"),self.cancelAction)
	self.connect(self.ok,     SIGNAL("clicked()"),self.okAction)
	
	self.populateChooseList()
    
    def populateChooseList(self):
        global appData
	
    	for k, v in appData.iteritems():
	    lvi = QListViewItem(self.listView1)
	    lvi.setPixmap(0,v[1])
	    lvi.setText(0,v[0])	  
	    lvi.setText(1,v[7])
	    lvi.setText(2,str(k))
	    	
    def cancelAction(self):
        self.hide()

    def okAction(self):
        global appData

	item = self.listView1.selectedItem()
    	if item == None:
	    return

	try:
	    idx = int(str(item.text(2)))
	except ValueError:
	    return
	try:
	    row = appData[idx]
	except KeyError:
	    return
	
	sendEvent(dwin,31000,appData[idx][5]) 
        self.hide()

    def languageChange(self):
        self.setCaption(self.__tr("Choose application"))
        self.listView1.header().setLabel(0,self.__tr("Application"))
        self.listView1.header().setLabel(1,self.__tr("Mode"))
        self.listView1.clear()
        item = QListViewItem(self.listView1,None)

        self.cancel.setText(self.__tr("Cancel"))
        self.ok.setText(self.__tr("Ok"))

    def __tr(self,s,c = None):
        return qApp.translate("Form1",s,c)


##################################################################################
#
# Progress bar window
#
##################################################################################
class PBar(QProgressDialog):
    def __init__(self, text, steps):
        QProgressDialog.__init__(self, text, '', steps)

	self.setCancelButton(None)
	self.setAutoReset(True)
	self.setAutoClose(False)
	self.show()
	

def runPBar(text,time):
    global pbar, pbarTimer

    pbar = PBar(text,time)
    timerPBar()

def stopPBar():
    global pbar, pbarTimer

    try:
        pbarTimer.stop()
    except AttributeError:
        pass
	
    try:
        pbar.cancel()
	pbar = None
    except AttributeError, NameError:
        pass
	
def writePBar(txt):
    global pbar
    try:
        pbar.setLabelText(txt)
    except AttributeError, NameError:
        pass
	
def timerPBar():
    global pbar, pbarTimer

    if not quitFlag:
    	try:
    	    pbar.setProgress(pbar.progress()+1)
    	except AttributeError, NameError:
    	    return
    	pbarTimer = QTimer.singleShot(1000,timerPBar)
	
##################################################################################
#
# BT communication thread
#
##################################################################################

# Beware:
# Can not run more than one command on BT adapter at once, since it could hungs 

class BtComm(threading.Thread):

    def __init__(self, jDir):
	threading.Thread.__init__(self) 
	self.midletDir = jDir

    def run(self):
        global debug, bt_devices, cmd_array
	
	self.keepRun = True
	
	if debug:
	    print 'BtComm: run'
	
	while self.keepRun:
	
	    ctype = ''
	    cdata = ''

	    try:
                item = cmd_array[0]
	        del cmd_array[0] 
	        ctype = item[0]
	        cdata = item[1]
 	    except NameError:
	        pass
 	    except TypeError:
	        pass
	    except IndexError:
	        pass

	    
	    if debug and ctype != '':
	        print 'BtComm: (#',len(cmd_array),') got command',ctype,cdata
	 
	    if ctype == 'scan':
	        self.doScan()
	    elif ctype == 'ping':
	        self.doPing(cdata)
	    elif ctype.startswith('push'):
	        self.doPush(cdata,ctype[4:])
	    elif ctype == 'info':
	        self.doInfo(cdata)
	    elif ctype == 'test_at':
	        self.doAT(cdata)
	    else:
	        time.sleep(1)
		
    def setStatus(self, address, status):
        global debug, bt_devices
        
	if debug:
            print 'set for',address,status

	for k, v in bt_devices.iteritems():
 
            if address == v[0]:
                if status != v[4]:
        	    v[4] = status
		
		needRun = v[3]  
		if status == 'Available' and needRun != '':
		    if debug: 
		        print 'run anyRemote with',needRun
			
		    startAnyRemote(needRun, False)
		    
		try:
	    	    if browserWin != None:
			sendEvent(browserWin,30000," ") 
   		except AttributeError, NameError:
	    	    pass

    	        return

    def doScan(self):
	global debug
	if debug:
	    print 'BtComm: scan devices'
	existing = getDevSet()
	
	# Search new devices
	nearby_devices = []
	try:
	    nearby_devices = bluetooth.discover_devices(lookup_names = True)
	except bluetooth.BluetoothError,msg:
	    if debug:
	        print "BtComm: BluetoothError"
	    
	    # sleep additional 5 sec
	    t2 = 0
	    while self.keepRun and t2 < 5:
	    	time.sleep(0.1)
		t2 = t2 + 0.1
	
	if debug:
	    print "BtComm: found %d devices" % len(nearby_devices)

	availSet = getAvailableSet()
	
	for addr,name in nearby_devices:
	    if debug:
		print "  %s - %s" % (addr, name)
	
	    if addr not in existing:
	        showDetailsWin(addr, name, name, '', True)
	    else:
		if addr in availSet:
		    availSet.discard(addr)
		else:
		    self.setStatus(addr,'Available')
	    
	for rest in availSet:
	    self.setStatus(rest, '')
	
	if debug:
	    print 'BtComm: verify done'

    def doPing(self, data):
	global debug, dwin
	if debug: print 'BtComm: ping device'
	
	dwin.setStatustext('')
	writePBar('Connecting to device')
	
	os.system('killall -9 hcitool')
	if debug: print 'hcitool name '+data
	ret = getResult('hcitool name '+data,'browser')
	
	stopPBar()
	if (ret == ''):
	    dwin.setStatustext('Ping failed !')
	else:
	    dwin.setStatustext('Ping OK !')

    def doPush(self, data, size):
	global debug, dwin
	if debug: print 'BtComm: obex push'

	dwin.setStatustext('')
	stopPBar()   
	
	if not os.path.exists(self.midletDir):       
	    dwin.setStatustext('Can not find anyRemote data directory !')
	    return
	
	midlet = 'anyRemote-' + size + '.jar'
	path = self.midletDir + os.sep + midlet
	if not os.path.isfile(path):
	    dwin.setStatustext('Can not find anyremote-J2ME-client installation !')
	    return
		     
	sender = ''    
	if (isInstalled('gnome-obex-send') == 'OK'):
	    sender = 'gnome-obex-send -d '+data
	elif (isInstalled('bluetooth-sendto') == 'OK'):
	    sender = 'bluetooth-sendto --dest='+data
	elif (isInstalled('kbtobexclient') == 'OK'):
	    sender = 'kbtobexclient'
	else:
	    dwin.setStatustext('None of gnome-obex-send, bluetooth-sendto and kbtobexclient are installed !')
	    return
	
	ret = getResult(sender+' '+path+' &','browser')
	
    def doInfo(self,data):
	global debug
	if debug: print 'BtComm: get info'

	writePBar('Connecting to device')
	
	services = bluetooth.find_service(address=data)

	if len(services) > 0:
            print "found %d services on %s" % (len(services), data)
            print
	else:
            print "no services found"

	for svc in services:
	    print "Service Name: %s"    % svc["name"]
	    print "    Host:        %s" % svc["host"]
	    print "    Description: %s" % svc["description"]
	    print "    Provided By: %s" % svc["provider"]
	    print "    Protocol:    %s" % svc["protocol"]
	    print "    channel/PSM: %s" % svc["port"]
	    print "    svc classes: %s "% svc["service-classes"]
	    print "    profiles:    %s "% svc["profiles"]
	    print "    service id:  %s "% svc["service-id"]
	    print

    def getSerialPort(self,addr):
	services = bluetooth.find_service(address=addr)
	for svc in services:
	    try:
	        if svc["name"] == 'Serial Port' or svc["name"].startswith('COM ') or svc["name"].startswith('Dial-up'):
	            return svc["port"]
            except AttributeError, NameError:
    	        pass
	return None
	
    def send_at(self,sock,cmd):
	global debug
	if len(cmd) == 0: 
	    return ''
	
	data = cmd+'\r'
	if debug: print "send",cmd
	
	sock.send(cmd+'\r')
	time.sleep(0.5)
	data = sock.recv(1024)

	if debug: print "got",data
	return data

    def doAT(self,data):
        global debug, dwin
	if debug: print 'BtComm: doAT'
	    
	dwin.setStatustext('')
	writePBar('Connecting to device')	
    	port = self.getSerialPort(data)
	if debug: print 'BtComm: port',port
        
	if port == None:
	    dwin.setStatustext('Can not get port to connect. Are device available ?')
	    pass
	else:
	    sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
	    try:
	        sock.connect((data, port))
 	    except bluetooth.BluetoothError,msg:
		d = str(msg)
		print d
		stopPBar()
	        if d.startswith('(111,'):
		    dwin.setStatustext('Connection refused')
	        return

  	    ret = self.send_at(sock,"ATZ")
  	    ret = self.send_at(sock,"ATE0")
  	    ret = self.send_at(sock,"AT+CMER=?")
	    
	    status = '' 
	    if ret.find('ERROR') == -1:
	        ret = ret[ret.index('+CMER'):]
	        ret = (ret.split('\n'))[0]
	    
	        AT_CMER=ret.replace(' ','').replace('\r','')
	    
	        #+CMER: (0,3),(0),(0),(0,1,2),(0)	<- bad
		#+CMER: (0,3),(0,1,2),(0),(0,1,2),(0)	<- OK
		s1 = (AT_CMER.split('('))[2]
		s2 = (s1.split(')'))[0]
		
		status = AT_CMER
		if s2 == '0':
		    status = 'AT mode does not supported by phone ('+status+')'
		else:
		    status ='AT mode could be supported by phone ('+status+')'
	    else:
	    	status = 'AT mode does not supported by phone (ERROR response)'
		
            dwin.setStatustext(status)
            sock.close()

	stopPBar()
   
    def stop(self):
        global debug
	if debug: print 'BtComm stop'
	self.keepRun = False

##################################################################################
#
# Application status updater
#
##################################################################################
class StatusUpdater(threading.Thread):

    def __init__(self, rcvr, timeout):
	threading.Thread.__init__(self) 
	self.tmout    = timeout
	self.receiver = rcvr

    def run(self):
        global debug, appData
	
	if debug: print 'StatusUpdater.run',self.tmout
	self.runUpdater = True
	
	while self.runUpdater:
	    timer = 0
	    
	    # catch stop event without waiting full timeout
	    while self.runUpdater and timer < self.tmout:
	        time.sleep(0.1)
		timer = timer + 0.1
	    
	    if debug: print 'StatusUpdater: verify'
	    
	    for k, v in appData.iteritems():
	        if not self.runUpdater:
		    break
		
		aRun = v[3]
	        if aRun != '':
	    	    isRun  = getResult(aRun,'updater')
		    
		    if isRun != v[4]:
		        v[4] = isRun
		        sendEvent(self.receiver, 20006, [k,v[6],isRun])	

    def stop(self):
        global debug
	if debug: print 'StatusUpdater.stop'
        self.runUpdater = False
	   
##################################################################################
#
# Frontend to anyRemote
#
##################################################################################

class FrontEnd(threading.Thread):
    def __init__(self, receiver):
        global debug
	threading.Thread.__init__(self)        
        self.receiver = receiver
    	if debug: print 'FrontEnd init'

    def stop(self):
        global debug
    	if debug: print 'FrontEnd stop'
    	self.isRun = False

    def run(self):
    	global port, cmdToSend, debug
	if debug: print 'FrontEnd thread is running'

    	self.isRun = True
    	s = None
    	for res in socket.getaddrinfo('localhost', port, socket.AF_INET, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    	    af, socktype, proto, canonname, sa = res
    	    
    	    try:
    		s = socket.socket(af, socktype, proto)
    		s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    		s.setblocking(0)
    	    except socket.error, msg:
    		s = None
    		continue
	    if debug: print 'FrontEnd socket created'
    		
    	    try:
    		s.bind(sa)
    		s.listen(1)
	    except socket.error, msg:
    		s.close()
    		s = None
    		continue
    	    if debug: print 'FrontEnd socket after listen'
	    break
    	    
    	if s is None:
	    if debug: print 'FrontEnd could not open socket'
	    sys.exit(1)

    	while self.isRun:
    	    while self.isRun:

    		try:
    		    conn, addr = s.accept()
    		    if debug: print 'accept', addr
    		    break
    		except socket.error,msg:
    		    time.sleep(0.1)
    	   
	    if self.isRun:
    	        self.processOneConnection(conn, addr)
    	
    	if debug: print 'Close server socket' 
    	s.close()
	    
    def processOneConnection(self,conn,addr):
	global cmdToSend, debug
    	
	if debug: print 'FrontEnd processOneConnection', addr
    
        self.isConn = True
    	while self.isRun and self.isConn:
    	
    	    conn.setblocking(0)
    
    	    if debug: print 'FrontEnd.Connected by', addr
    	
    	    sendEvent(self.receiver,20003,'')
    	
    	    while self.isRun and self.isConn:
    	    	
    	    	time.sleep(0.2)
    	
    	    	data = ''
    	    	try:
    	    	    data = conn.recv(512)
    	    	    if debug: print 'Got from backend ', data
    	    	
		    if self.isRun:
		        sendEvent(self.receiver,10000,data)
    	    	
    	    	    if not data: 
    	    		if debug: print 'FrontEnd anyRemote die?'
    	    	    
		        if self.isRun:
		            sendEvent(self.receiver,20000,'') 
    	    		    self.isConn = False
    	    		break

    	    	except socket.error,msg:
    	    	    pass
    	    	
    	    	try:
    	    	    if cmdToSend:
    	    		if debug: print 'Send to backend '+cmdToSend + "\n"
    	    		conn.sendall(cmdToSend)
    	    		cmdToSend = '';
    	    	except socket.error, NameError:
    	    	    print 'FrontEnd.processOneConnection exception'
    	    	    pass
    	
    	    if debug: print 'Close connection' 
	    sendEvent(self.receiver,20012,'')  
    	    conn.close()

##################################################################################
#
# Edit window
#
##################################################################################

class EditWin(QMainWindow):
    def __init__(self,efile,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,None,name,fl)
        #self.statusBar()
	
	self.eFile = efile

        if not name:
            self.setName("Edit File")

        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        EditWinLayout = QGridLayout(self.centralWidget(),1,1,11,6,"EditWinLayout")
       
        self.closeEditor = QPushButton(self.centralWidget(),"closeEditor")

        EditWinLayout.addWidget(self.closeEditor,1,1)

        self.textEdit1 = KTextEdit(self.centralWidget(),"textEdit1")

        EditWinLayout.addMultiCellWidget(self.textEdit1,0,0,0,1)

        self.saveEditor = QPushButton(self.centralWidget(),"saveEditor")

        EditWinLayout.addWidget(self.saveEditor,1,0)

        self.languageChange()

        self.resize(QSize(581,558).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)
	
        self.connect (self.saveEditor, SIGNAL ("clicked ()"), self.save_clicked)
        self.connect (self.closeEditor,SIGNAL ("clicked ()"), self.cancel_clicked)
	
	self.loadEditFile()
	
    def loadEditFile(self):
    
        infile = open(self.eFile, "r")
        if infile:
            string = infile.read()
            infile.close()
            self.textEdit1.setText(string)
	else:
	    self.eFile = ""

    def languageChange(self):
        self.setCaption(self.__tr("Edit cfg file"))
        self.closeEditor.setText(self.__tr("&Cancel"))
        self.closeEditor.setAccel(QKeySequence(self.__tr("Alt+C")))
        self.saveEditor.setText(self.__tr("&Save"))
        self.saveEditor.setAccel(QKeySequence(self.__tr("Alt+S")))


    def save_clicked(self):
	f=open(self.eFile, 'w')
	if f:
	    f.write(str(self.textEdit1.text()))
	    f.close()
	    
            self.destroy()   

    def cancel_clicked(self):
        self.destroy()   

    def __tr(self,s,c = None):
        return qApp.translate("EditWin",s,c)
	
##################################################################################
#
# Preferences window
#
##################################################################################

class Preferences(QMainWindow):
    def __init__(self,mainWin,cfgReader,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)

        if not name:
            self.setName("Preferences")

        self.setMinimumSize(QSize(709,429))

        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        PreferencesLayout = QGridLayout(self.centralWidget(),1,1,11,6,"PreferencesLayout")

        self.textLabel1 = QLabel(self.centralWidget(),"textLabel1")
        self.textLabel1.setAlignment(QLabel.AlignCenter)
        self.textLabel1.setIndent(-2)
        PreferencesLayout.addMultiCellWidget(self.textLabel1,0,0,1,7)
 	
        self.dirView = QListView(self.centralWidget(),"dirView")
        self.dirView.addColumn(self.__tr("Directories"))
        self.dirView.header().setClickEnabled(0,self.dirView.header().count() - 1)
	self.dirView.setResizeMode(QListView.LastColumn)
        PreferencesLayout.addMultiCellWidget(self.dirView,1,1,0,8)

	self.addButton = QPushButton(self.centralWidget(),"addButton")
        PreferencesLayout.addWidget(self.addButton,2,0)
        self.delButton = QPushButton(self.centralWidget(),"delButton")
        PreferencesLayout.addWidget(self.delButton,2,1)

        ###
        self.jdirLabel = QLabel(self.centralWidget(),"jdirLabel")
        PreferencesLayout.addMultiCellWidget(self.jdirLabel,3,3,0,1)
        self.javaDir = QLineEdit(self.centralWidget(),"javaDir")
        PreferencesLayout.addMultiCellWidget(self.javaDir,3,3,2,7)
        self.jDir = QPushButton(self.centralWidget(),"jDir")
        PreferencesLayout.addWidget(self.jDir,3,8)
	
        ###
        self.line10 = QFrame(self.centralWidget(),"line10")
        self.line10.setFrameShape(QFrame.HLine)
        self.line10.setFrameShadow(QFrame.Sunken)
        self.line10.setFrameShape(QFrame.HLine)
        PreferencesLayout.addMultiCellWidget(self.line10,4,4,0,8)

        self.textLabel3 = QLabel(self.centralWidget(),"textLabel3")
        PreferencesLayout.addMultiCellWidget(self.textLabel3,5,5,0,1)
        self.appl = QCheckBox(self.centralWidget(),"appl")
        PreferencesLayout.addMultiCellWidget(self.appl,5,5,2,4)
        self.custom = QCheckBox(self.centralWidget(),"custom")
        PreferencesLayout.addWidget(self.custom,5,5)
        self.examples = QCheckBox(self.centralWidget(),"examples")
        PreferencesLayout.addMultiCellWidget(self.examples,5,5,6,8)
	
        self.srv = QCheckBox(self.centralWidget(),"srv")
        PreferencesLayout.addWidget(self.srv,6,5)
        self.bem = QCheckBox(self.centralWidget(),"bem")
        PreferencesLayout.addMultiCellWidget(self.bem,6,6,6,8)
        self.at = QCheckBox(self.centralWidget(),"at")
        PreferencesLayout.addMultiCellWidget(self.at,6,6,2,4)
        self.all = QCheckBox(self.centralWidget(),"all")
        PreferencesLayout.addMultiCellWidget(self.all,6,6,0,1)
	
        self.line12 = QFrame(self.centralWidget(),"line12")
        self.line12.setFrameShape(QFrame.HLine)
        self.line12.setFrameShadow(QFrame.Sunken)
        self.line12.setFrameShape(QFrame.HLine)
        PreferencesLayout.addMultiCellWidget(self.line12,7,7,0,8)
	
        self.textLabel4 = QLabel(self.centralWidget(),"textLabel4")
        PreferencesLayout.addMultiCellWidget(self.textLabel4,8,8,0,2)
        self.tmout = QLineEdit(self.centralWidget(),"tmout")
        PreferencesLayout.addWidget(self.tmout,8,3)
	QToolTip.add(self.tmout, 'Empty field means no update')
        self.textLabel5 = QLabel(self.centralWidget(),"textLabel5")
        PreferencesLayout.addWidget(self.textLabel5,8,4)
 	self.autoGnome = QCheckBox(self.centralWidget(),"autoGnome")
        PreferencesLayout.addWidget(self.autoGnome,8,6)
        self.textLabel6 = QLabel(self.centralWidget(),"textLabel6")
        PreferencesLayout.addWidget(self.textLabel6,8,5)
        self.autoKDE = QCheckBox(self.centralWidget(),"autoKDE")
        PreferencesLayout.addMultiCellWidget(self.autoKDE,8,8,7,8)

	self.line15 = QFrame(self.centralWidget(),"line15")
        self.line15.setFrameShape(QFrame.HLine)
        self.line15.setFrameShadow(QFrame.Sunken)
        self.line15.setFrameShape(QFrame.HLine)
        PreferencesLayout.addMultiCellWidget(self.line15,9,9,0,8)
		
        self.textLabel7 = QLabel(self.centralWidget(),"textLabel7")
        PreferencesLayout.addMultiCellWidget(self.textLabel7,10,10,0,4)
        self.deviceOver = QLineEdit(self.centralWidget(),"deviceOver")
        PreferencesLayout.addWidget(self.deviceOver,10,5)
        self.auto_reconnect = QCheckBox(self.centralWidget(),"auto_reconnect")
        PreferencesLayout.addMultiCellWidget(self.auto_reconnect,10,10,6,8)
	
        self.runWeb = QCheckBox(self.centralWidget(),"runWeb")
        PreferencesLayout.addMultiCellWidget(self.runWeb,11,11,0,4)
        self.webParams1 = QLineEdit(self.centralWidget(),"webParams")
        self.webParams1.setReadOnly(True);
        PreferencesLayout.addMultiCellWidget(self.webParams1,11,11,5,5)
        self.webParams = QLineEdit(self.centralWidget(),"webParams")
        PreferencesLayout.addMultiCellWidget(self.webParams,11,11,6,6)

        self.line11 = QFrame(self.centralWidget(),"line11")
        self.line11.setFrameShape(QFrame.HLine)
        self.line11.setFrameShadow(QFrame.Sunken)
        self.line11.setFrameShape(QFrame.HLine)
        PreferencesLayout.addMultiCellWidget(self.line11,12,12,0,8)

        self.labelRunWhen = QLabel(self.centralWidget(),"labelRunWhen")
        PreferencesLayout.addMultiCellWidget(self.labelRunWhen,13,13,0,4)
        self.browseTmout = QLineEdit(self.centralWidget(),"browseTmout")
        PreferencesLayout.addWidget(self.browseTmout,13,5)
	QToolTip.add(self.browseTmout, 'Empty field means no update. Beware: Java client could fails to connect to anyRemote when browsing is in process');

        self.lineBr = QFrame(self.centralWidget(),"lineBr")
        self.lineBr.setFrameShape(QFrame.HLine)
        self.lineBr.setFrameShadow(QFrame.Sunken)
        self.lineBr.setFrameShape(QFrame.HLine)
        PreferencesLayout.addMultiCellWidget(self.lineBr,14,14,0,8)

        self.cancel = QPushButton(self.centralWidget(),"cancel")
        PreferencesLayout.addMultiCellWidget(self.cancel,15,15,6,7)
	self.ok = QPushButton(self.centralWidget(),"ok")
        PreferencesLayout.addWidget(self.ok,15,8)

        self.languageChange()

        self.resize(QSize(710,414).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

        self.connect(self.delButton,SIGNAL("clicked()"),self.delete_clicked)
        self.connect(self.addButton,SIGNAL("clicked()"),self.add_clicked)
        self.connect(self.jDir,     SIGNAL("clicked()"),self.chooseJavaDir)
        self.connect(self.cancel,   SIGNAL("clicked()"),self.cancel_clicked)
        self.connect(self.ok,       SIGNAL("clicked()"),self.ok_clicked)
	
        self.connect(self.all,      SIGNAL("toggled(bool)"),self.showAllAction)
        self.connect(self.appl,     SIGNAL("toggled(bool)"),self.filterChangedAction)
        self.connect(self.custom,   SIGNAL("toggled(bool)"),self.filterChangedAction)
        self.connect(self.examples, SIGNAL("toggled(bool)"),self.filterChangedAction)
        self.connect(self.at,       SIGNAL("toggled(bool)"),self.filterChangedAction)
        self.connect(self.srv,      SIGNAL("toggled(bool)"),self.filterChangedAction)
        self.connect(self.bem,      SIGNAL("toggled(bool)"),self.filterChangedAction)
        self.connect(self.runWeb,  SIGNAL("toggled(bool)"),self.webToggledAction)
	
        self.connect(self.deviceOver,SIGNAL("textChanged(const QString&)"),self.deviceChangedAction)

	self.receiver = mainWin
	self.cReader  = cfgReader

	self.makeGuiSetup()
	
    def makeGuiSetup(self):
	self.all.setChecked(self.cReader.showAll_)
	self.setFilters()
	
	if not self.cReader.showAll_:
	    self.appl.setChecked    (self.cReader.showApps_)
	    self.custom.setChecked  (self.cReader.showCustom_)
	    self.examples.setChecked(self.cReader.showExamples_)
	    self.at.setChecked      (self.cReader.showAt_)
	    self.srv.setChecked     (self.cReader.showSrv_)
	    self.bem.setChecked     (self.cReader.showBm_)
	
	tm = ''
	if self.cReader.updateTmout_ > 0:
	    tm = "%s" % (self.cReader.updateTmout_)
	self.tmout.setText(tm)

	tm = ''
	if self.cReader.browseTmout_ > 0:
	    tm = "%s" % (self.cReader.browseTmout_)
	self.browseTmout.setText(tm)
	
	self.autoGnome.setChecked(os.path.exists(os.environ.get("HOME")+os.sep+'.config'+os.sep+'autostart'+os.sep+'kanyremote.desktop'))
	self.autoKDE.setChecked(os.path.exists(os.environ.get("HOME")+os.sep+'.kde'+os.sep+'Autostart'+os.sep+'kanyremote'))	
	
	self.auto_reconnect.setChecked(self.cReader.autoReconn_)

	self.webParams.setText(self.cReader.webParams_)
	self.deviceOver.setText(self.cReader.device_)
	self.javaDir.setText(self.cReader.javaDir_)
	
	self.setWebParamsActive(self.cReader.runWeb_)
	
	self.runWeb.setChecked(self.cReader.runWeb_ and self.cReader.device_.startswith('socket:'))
	
	self.dirView.clear()
	for d in self.cReader.cfgDirs:
	    if d != '':
        	lvi = QListViewItem(self.dirView)
        	lvi.setText(0,d)
	
	self.addDir      = ''
	self.dirsChanged = False

    def languageChange(self):
        self.setCaption(self.__tr("Preferences"))
        self.textLabel1.setText(self.__tr("Choose directories with cfg. files and add them to the list"))
        self.textLabel3.setText(self.__tr("Show in list"))
	self.jdirLabel.setText(self.__tr("Upload java client from"))
        self.examples.setText(self.__tr("Examples"))
        self.appl.setText(self.__tr("Applications"))
        self.custom.setText(self.__tr("Custom made"))
        self.srv.setText(self.__tr("Server mode"))
        self.bem.setText(self.__tr("Bemused emulation"))
        self.at.setText(self.__tr("AT-mode"))
        self.all.setText(self.__tr("All"))
        self.textLabel4.setText(self.__tr("Update application list every"))
        self.textLabel5.setText(self.__tr("sec."))
        self.textLabel7.setText(self.__tr("Override \"Device=\" parameter with:"))
        self.labelRunWhen.setText(self.__tr("Run device browser with timeout:"))
        self.runWeb.setText(self.__tr("Run web interface with parameters"))
        self.addButton.setText(self.__tr("Add"))
        self.delButton.setText(self.__tr("Delete"))
	self.jDir.setText(self.__tr("Choose"))
        self.auto_reconnect.setText(self.__tr("Auto reconnect in AT mode"))
        self.autoGnome.setText(self.__tr("Gnome session"))
        self.textLabel6.setText(self.__tr("Auto startup with"))
        self.autoKDE.setText(self.__tr("KDE session"))
        self.ok.setText(self.__tr("Ok"))
        self.dirView.header().setLabel(0,self.__tr("Directories"))
        self.cancel.setText(self.__tr("Cancel"))

    def setWebParamsActiveReset(self):
	
	active = (self.runWeb.isChecked() and str(self.deviceOver.text()).startswith('socket:'))
	self.setWebParamsActive(active)

    def setWebParamsActive(self, active):
 
 	self.webParams.setEnabled(active)

	if active:
	    #port   = self.cReader.device_[7:]

	    #tokens = str(self.webParams.text()).split(' ')
	
	    #newparams = ''
	    #next  = 0
	    #found = 0
	    #for item in tokens:
	    #	if item == '':
	    #	   continue
	    #	if next == 1:
	    #	   item  = port
	    #	   next  = 0
	    #	   found = 1
	    #	if item == '-a':
	    #	    next = 1
	    #	    if port == '':
	    #		continue
	    #	newparams = newparams + ' ' + item
	    #if found == 0 and port != '':
	    #	newparams = newparams + ' -a ' + port
	    #	
	    #self.webParams.setText(newparams)
	    self.webParams1.setText(' -a '+self.deviceOver.text()[7:])
	else:   
            self.webParams1.setText('')

    def delete_clicked(self):
	item = self.dirView.selectedItem()
	self.dirView.takeItem(item)

	self.dirsChanged = True

    def add_clicked(self):
	f = QFileDialog().getExistingDirectory(self.addDir)
	self.addDir = os.path.dirname(str(f))
	
	add = True
	item = self.dirView.firstChild() 
        while item != None:
	    if self.addDir == item.text(0):
	        add = False
		break
	    item = item.nextSibling()
	
	if add:
       	    lvi = QListViewItem(self.dirView)
            lvi.setText(0,str(f))

    def chooseJavaDir(self):
	f = QFileDialog().getExistingDirectory(self.addDir)
	self.addDir = os.path.dirname(str(f))
	self.javaDir.setText(self.addDir)

    def deviceChangedAction(self,a0):
        self.device_ = str(self.deviceOver.text()).strip()
	self.setWebParamsActiveReset()

    def webToggledAction(self, w):
        active = self.runWeb.isChecked()
	if active:
	    isInst = isInstalled('anyremote2html')
	    if isInst == 'NOK':
		QMessageBox.warning(self, self.__tr("kAnyRemote"),
	                 self.__tr('anyremote2html is not installed !'),QMessageBox.Ok);
	    else:
		if str(self.deviceOver.text()).startswith('socket:'):
		    self.webParams1.setText(' -a '+self.deviceOver.text()[7:])
		else:
	            self.deviceOver.setText('socket:5000')
	            self.webParams1.setText(' -a 5000')
	            self.webParams.setText(' -w 5550')
		    
	self.webParams1.setEnabled(active)
	self.webParams.setEnabled(active)

    def cancel_clicked(self):
        self.hide()
	self.makeGuiSetup()
        sendEvent(self.receiver,20005,False)

    def ok_clicked(self):
 	self.setAutoStartup("KDE",   self.autoKDE.isChecked())
	self.setAutoStartup("Gnome", self.autoGnome.isChecked())
	
	self.cReader.showApps_     = self.appl.isChecked()
	self.cReader.showCustom_   = self.custom.isChecked()
	self.cReader.showExamples_ = self.examples.isChecked()
	self.cReader.showAll_      = self.all.isChecked()
	self.cReader.showAt_       = self.at.isChecked()
	self.cReader.showSrv_      = self.srv.isChecked()
	self.cReader.showBm_       = self.bem.isChecked()

	self.cReader.autoReconn_   = self.auto_reconnect.isChecked()
	self.cReader.runWeb_       = self.runWeb.isChecked()
	self.cReader.webParams_    = str(self.webParams.text()).strip()
	self.cReader.device_       = str(self.deviceOver.text()).strip()
	self.cReader.javaDir_      = str(self.javaDir.text()).strip()
	
	tm = str(self.tmout.text()).strip()
	if tm == '':
	    tm = '-1'
	if self.cReader.updateTmout_ != int(tm):
	    self.cReader.updateTmout_ = int(tm)
	    if self.cReader.updateTmout_ < 0:
	        self.cReader.updateTmout_ = -1
	    
	    # start/stop browser
	    sendEvent(self.receiver,20010,'')

	tm = str(self.browseTmout.text()).strip()
	if tm == '':
	    tm = '-1'
	if self.cReader.browseTmout_ != int(tm):
	    self.cReader.browseTmout_ = int(tm)
	    if self.cReader.browseTmout_ <= 0:
	        self.cReader.browseTmout_ = -1
	    
	    # start/stop updater
	    sendEvent(self.receiver,20011,'')
        
	self.cReader.cfgDirs = []
	
	item = self.dirView.firstChild() 
        while item != None:
	    self.cReader.cfgDirs.append(str(item.text(0)))
	    item = item.nextSibling()
	
	ret = QMessageBox.Ok
	if self.cReader.cfgDirs == []:
	    ret = QMessageBox.warning(self, self.__tr("kAnyRemote"),
	                 self.__tr("There is no items in the list !\nkAnyRemote will not be able to manage any software !"),QMessageBox.Ok,QMessageBox.Cancel);

	if ret == QMessageBox.Ok:
	    self.cReader.saveConfig() 
	    self.hide()
	    
	    sendEvent(self.receiver,20005,self.dirsChanged)
	    self.dirsChanged = False

    def filterChangedAction(self, w):
    	self.dirsChanged = True

    def showAllAction(self, w):
    	self.dirsChanged = True
	self.setFilters()
	
    def setFilters(self):
	if self.all.isChecked():
    	    self.appl.setChecked(False)
    	    self.custom.setChecked(False)
    	    self.examples.setChecked(False)
    	    self.at.setChecked(False)
    	    self.srv.setChecked(False)
    	    self.bem.setChecked(False)
	    
    	    self.appl.setEnabled(False)
    	    self.custom.setEnabled(False)
    	    self.examples.setEnabled(False)
    	    self.at.setEnabled(False)
    	    self.srv.setEnabled(False)
    	    self.bem.setEnabled(False)
        else:
    	    self.appl.setEnabled(True)
    	    self.custom.setEnabled(True)
    	    self.examples.setEnabled(True)
    	    self.at.setEnabled(True)
    	    self.srv.setEnabled(True)
    	    self.bem.setEnabled(True)

    def setAutoStartup(self, wm, isAuto):
        if wm == 'KDE':
	    autopath = os.environ.get("HOME")+os.sep+'.kde'+os.sep+'Autostart'+os.sep+'kanyremote'
	    if isAuto:
	    	if not os.path.exists(autopath):
		    os.system('ln -s `which kanyremote` '+autopath)
	    else:
	    	os.system('rm -f '+autopath)
	
        elif wm == 'Gnome':		# will work for gnome > 2.14 ?
	    cfgpath  = os.environ.get("HOME")+os.sep+'.config'
	    autopath = cfgpath+os.sep+'autostart'
	    autorun  = autopath+os.sep+'kanyremote.desktop'

    	    if not os.path.isdir(cfgpath):
        	os.mkdir(cfgpath)
    	    if not os.path.isdir(autopath):
        	os.mkdir(autopath)
	    if isAuto:
    	        if not os.path.isfile(autorun):
	            f=open(autorun, 'w')
	            if f:
 	                f.write('[Desktop Entry]\n')
 	                f.write('Encoding=UTF-8\n')
 	                f.write('Name=kAnyRemote\n')
 	                f.write('Exec=kanyremote\n')
 	                f.write('Icon=kanyremote\n')
 	                f.write('Type=Application\n')
 	                f.write('Comment=Remote control through bluetooth or IR connection\n')
 	                f.write('GenericName=Remote control through bluetoth or IR connection\n')
 	                f.write('Categories=Utility;\n')
		        f.close()
            else:
	        os.system('rm -f '+autorun)
	
    def __tr(self,s,c = None):
        return qApp.translate("Preferences",s,c)

    def __trUtf8(self,s,c = None):
        return qApp.translate("Preferences",s,c,QApplication.UnicodeUTF8)

###############################################################################	
#
#	kAnyRemote
#
###############################################################################	

class kAnyRemote(QMainWindow):
    def __init__(self,cfgReader,runWizard,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)

	global debug, guiMode, lastCfgFile
	
	self.cReader = cfgReader

        self.statusBar()
	
	if debug:
	    row = 3
	else:
	    row = 2

	if guiMode == 'simple':
	    row = row - 1
	    
        if not name:
            self.setName("kAnyRemote")


        self.setCentralWidget(QWidget(self,"qt_central_widget"))
        kAnyRemoteLayout = QGridLayout(self.centralWidget(),1,1,11,6,"kAnyRemoteLayout")

        self.close_window = QPushButton(self.centralWidget(),"close_window")
        kAnyRemoteLayout.addMultiCellWidget(self.close_window,row,row,3,4)
        self.stop_button = QPushButton(self.centralWidget(),"stop_button")
        kAnyRemoteLayout.addWidget(self.stop_button,row,2)
        self.run_button = QPushButton(self.centralWidget(),"run_button")
        kAnyRemoteLayout.addWidget(self.run_button,row,1)
        self.rescan_dirs = QPushButton(self.centralWidget(),"rescan_dirs")
        kAnyRemoteLayout.addWidget(self.rescan_dirs,row,0)

        self.listView1 = QListView(self.centralWidget(),"listView1")
        self.listView1.addColumn(self.__tr("Application    "))
        self.listView1.addColumn(self.__tr("Status     "))
        self.listView1.addColumn(self.__tr("Mode    "))
        self.listView1.addColumn(self.__tr("Type"))
        self.listView1.addColumn(self.__tr("F"))
	
        #self.listView1.setResizeMode(QListView.AllColumns)
	self.listView1.setColumnWidthMode (0,QListView.Maximum) 
	self.listView1.setColumnWidthMode (1,QListView.Maximum) 
	self.listView1.setColumnWidthMode (2,QListView.Maximum) 
	self.listView1.setColumnWidthMode (3,QListView.Maximum) 
	self.listView1.setColumnWidthMode (4,QListView.Manual) 
	
	self.listView1.setMultiSelection(False)
	self.listView1.setSortColumn(0)
	#self.listView1.setSpacing(40)
	
	self.listView1.hideColumn(4)
	#self.listView1.setResizeEnabled(False,4) 
	
        kAnyRemoteLayout.addMultiCellWidget(self.listView1,0,0,0,4)

	if guiMode == 'expert':
            self.choose = QPushButton(self.centralWidget(),"choose")
            kAnyRemoteLayout.addWidget(self.choose,1,4)
            self.cfgFile = QLineEdit(self.centralWidget(),"cfgFile")
            kAnyRemoteLayout.addMultiCellWidget(self.cfgFile,1,1,0,3)

	if debug:
            self.command = QLineEdit(self.centralWidget(),"command")
            kAnyRemoteLayout.addMultiCellWidget(self.command,2,2,0,3)
            self.execcmd = QPushButton(self.centralWidget(),"exec")
            kAnyRemoteLayout.addWidget(self.execcmd,2,4)
            self.execcmd.setEnabled(False)


        self.fileExitAction = QAction(self,"fileExitAction")
        self.helpContentsAction = QAction(self,"helpContentsAction")
        self.helpAboutAction = QAction(self,"helpAboutAction")
        self.edit_file = QAction(self,"edit_file")
        self.start = QAction(self,"start")
        self.start.setOn(0)
        self.stop = QAction(self,"stop")
        self.save_prefs = QAction(self,"save_prefs")
        self.properties = QAction(self,"properties")
        self.chkCfg     = QAction(self,"checkConfig")
        self.dbrowser   = QAction(self,"dbrowser")

        self.Menu = QMenuBar(self,"Menu")

        self.fileMenu = QPopupMenu(self)
        self.fileMenu.insertSeparator()
        self.fileMenu.insertSeparator()
        self.edit_file.addTo(self.fileMenu)
        self.start.addTo(self.fileMenu)
        self.stop.addTo(self.fileMenu)
        self.fileExitAction.addTo(self.fileMenu)
        self.Menu.insertItem(QString(""),self.fileMenu,1)

        self.new_menu = QPopupMenu(self)
        self.dbrowser.addTo(self.new_menu)
        self.properties.addTo(self.new_menu)
        self.chkCfg.addTo(self.new_menu)
        self.save_prefs.addTo(self.new_menu)
        self.Menu.insertItem(QString(""),self.new_menu,2)

        self.helpMenu = QPopupMenu(self)
        self.helpContentsAction.addTo(self.helpMenu)
        self.helpAboutAction.addTo(self.helpMenu)
        self.Menu.insertItem(QString(""),self.helpMenu,3)

        self.Menu.insertSeparator(4)

        self.languageChange()

        self.resize(QSize(414,336).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

        self.connect(self.listView1,SIGNAL('clicked(QListViewItem*, const QPoint&, int)'),self.listClicked)
	self.connect(self.listView1,SIGNAL('doubleClicked(QListViewItem*, const QPoint&, int)'), self.listDClicked)
	
        self.connect(self.fileExitAction,SIGNAL("activated()"),self.fileExit)
        self.connect(self.edit_file,     SIGNAL("activated()"),self.edit_file_activated)
        self.connect(self.start,         SIGNAL("activated()"),self.runAction)
        self.connect(self.stop,          SIGNAL("activated()"),self.stopAction)
        
	self.connect(self.dbrowser  ,    SIGNAL("activated()"),showBrowserWin)
	self.connect(self.save_prefs,    SIGNAL("activated()"),self.saveCfg)
        self.connect(self.properties,    SIGNAL("activated()"),self.showConfDialog)
        self.connect(self.chkCfg,        SIGNAL("activated()"),showChkCfgWin)

	self.connect(self.helpContentsAction,SIGNAL("activated()"),self.helpContents)
        self.connect(self.helpAboutAction,   SIGNAL("activated()"),self.helpAbout)
	
	if guiMode == 'expert':
            self.connect(self.choose,  SIGNAL("clicked()"),self.choose_clicked)
        self.connect(self.close_window,SIGNAL("clicked()"),self.close_window_clicked)
        self.connect(self.rescan_dirs, SIGNAL("clicked()"),self.rescan_dirs_clicked)
        self.connect(self.stop_button, SIGNAL("clicked()"),self.stopAction)
        self.connect(self.run_button,  SIGNAL("clicked()"),self.runAction)
	
	h = 500
	if debug:
	    h = 470
            self.connect(self.execcmd,SIGNAL("clicked()"),self.exec_clicked)
	
        self.resize(QSize(600,h).expandedTo(self.minimumSizeHint()))
	
	self.stop.setEnabled(False)
	self.stop_button.setEnabled(False)
	
	if guiMode == 'expert':
	    self.cfgFile.setText(lastCfgFile)

	self.cfgWin        = None
	self.frontEnd      = None
	self.statusUpdater = None		
	
	# will send event to start (if needed) StatusUpdater 
	self.populateCfgFiles()	
	
	# will start device browser (if needed)
	startBtComm()
	
	if runWizard:
	    self.showWizard()

    def languageChange(self):
    	global debug, guiMode
    
        self.setCaption(self.__tr("kAnyRemote"))
        self.listView1.header().setLabel(0,self.__tr("Application"))
        self.listView1.header().setLabel(1,self.__tr("Status"))
        self.listView1.header().setLabel(2,self.__tr("Mode"))
        self.listView1.header().setLabel(3,self.__tr("Type"))
	if guiMode == 'expert':
            self.choose.setText(self.__tr("Choose"))
	if debug:
            self.execcmd.setText(self.__tr("Execute"))
	
        self.close_window.setText(self.__tr("Close Window"))
        self.stop_button.setText(self.__tr("Stop"))
        self.run_button.setText(self.__tr("Run"))
        self.rescan_dirs.setText(self.__tr("Update status"))
        self.fileExitAction.setText(self.__tr("Exit"))
        self.fileExitAction.setMenuText(self.__tr("Exit"))
        self.fileExitAction.setAccel(QString.null)
        
	self.helpContentsAction.setText(self.__tr("&Contents..."))
        self.helpContentsAction.setMenuText(self.__tr("&Contents..."))
        self.helpContentsAction.setAccel(QString.null)
        
	self.helpAboutAction.setText(self.__tr("&About"))
        self.helpAboutAction.setMenuText(self.__tr("&About"))
        self.helpAboutAction.setAccel(QString.null)
        
	self.edit_file.setText(self.__tr("Edit"))
        self.edit_file.setMenuText(self.__tr("Edit"))
        self.edit_file.setToolTip(self.__tr("Edit cfg.file"))
        self.start.setText(self.__tr("Start"))
        self.start.setMenuText(self.__tr("Start"))
        self.stop.setText(self.__tr("Stop"))
        self.stop.setMenuText(self.__tr("Stop"))
        self.stop.setToolTip(self.__tr("Stop anyRemote"))
        self.save_prefs.setText(self.__tr("Save"))
        self.save_prefs.setMenuText(self.__tr("Save"))
        self.properties.setText(self.__tr("Properties"))
        self.properties.setMenuText(self.__tr("Properties"))
        self.chkCfg.setText(self.__tr("Check configuration"))
        self.chkCfg.setMenuText(self.__tr("Check configuration"))
        self.dbrowser.setText(self.__tr("Device Browser"))
        self.dbrowser.setMenuText(self.__tr("Device Browser"))
        if self.Menu.findItem(1):
            self.Menu.findItem(1).setText(self.__tr("&File"))
        if self.Menu.findItem(2):
            self.Menu.findItem(2).setText(self.__tr("&Setup"))
        if self.Menu.findItem(3):
            self.Menu.findItem(3).setText(self.__tr("&Help"))
        if self.Menu.findItem(4):
            self.Menu.findItem(4).setText(self.__tr("Menu"))
  
    def showWizard(self):
   	ret = QMessageBox.information(self, self.__tr("kAnyRemote"),
	             self.__tr("This is the first time kAnyRemote has runned.\nPlease specify directories with anyRemote configuration files."),QMessageBox.Ok);
	self.showConfDialog()

    def showConfDialog(self):
    	if not self.cfgWin:
            self.cfgWin = Preferences(self, self.cReader);
	self.cfgWin.show()
	self.properties.setEnabled(False)
	
    def saveCfg(self):
        self.cReader.saveConfig()

    def getStatus(self,isRun,status):
       if status == 'Managed' and isRun == 'NOK':
           status = 'Available'
       elif status == 'Available' and isRun == 'OK':
           status = 'Running'
       elif status == 'Running' and isRun == 'NOK':
           status = 'Available'
 
       return status

    def addRow(self,rowData):
        #[aName, pbuf, isRun, status, aMode, aType, idx]
       lvi = QListViewItem(self.listView1)
       lvi.setPixmap(0,rowData[1])
       lvi.setText(0,rowData[0])       
       lvi.setText(1,self.getStatus(rowData[2],rowData[3]))
       lvi.setText(2,rowData[4])
       lvi.setText(3,rowData[5])
       lvi.setText(4,str(rowData[6]))

    def listClicked(self, listItem, point, column):
        global lastCfgFile, appData, guiMode
	try:
	    lastCfgFile = appData[int(str(listItem.text(4)))][5]

	    if guiMode == 'expert':
 	        self.cfgFile.setText(lastCfgFile)
	except AttributeError:
	    print 'kAnyRemote.listClicked: AttributeError'
	

    def listDClicked(self, listItem, point, column):
	self.listClicked(listItem, point, column)
	self.runAction()

    def fileExit(self):
    	global app, quitFlag, debug
	
        if debug: print "kAnyRemote.fileExit"
	quitFlag = True
	
	closeDetailsWin()
	closeBrowserWin()
	closeChkCfgWin()
	
	self.stopUpdater()
	stopFrontend()
	stopBtComm()
	
	time.sleep(0.5)
	
	if debug: print "kAnyRemote.fileExit -> app.quit"
	app.quit()

    def helpContents(self):
 	# open web browser on docs page if found ?
	app = 'firefox'
	isInst = isInstalled(app)
	if isInst == 'NOK':
	    app = 'konqueror'
	    isInst = isInstalled(app)
	    
	    if isInst == 'NOK':
	        errorMessage(self, 'Did not find browser to show help !')
		return
		
	docpath = ''
	if os.path.isdir('/usr/share/doc/anyremote/doc-html'):
	    docpath = '/usr/share/doc/anyremote/doc-html'
	elif os.path.isdir('/usr/local/share/doc/anyremote/doc-html'):
	    docpath = '/usr/local/share/doc/anyremote/doc-html'
	elif os.path.isdir('/usr/share/anyremote/doc-html'):
	    docpath = '/usr/share/anyremote/doc-html'
	elif os.path.isdir('/usr/local/share/anyremote/doc-html'):
	    docpath = '/usr/local/share/anyremote/doc-html'
	else:    
	    errorMessage('Can not find documentation !')
	    return
	
	cmd = app + ' ' + docpath + os.sep + 'k-shots.html &'
	os.system(cmd)

    def helpAbout(self):
 	global aboutData
	a = KAboutApplication(aboutData,self,"kAnyRemote",0)
	a.show()

    def edit_file_activated(self):
        global lastCfgFile
	self.eWin = EditWin(lastCfgFile)
	self.eWin.show()

    def choose_clicked(self):
	fileName = QFileDialog.getOpenFileName(self.__tr("Select configuration file"), "");
	self.cfgFile.setText(fileName)

    def rescan_dirs_clicked(self):
	self.populateCfgFiles()

    def close_window_clicked(self):
        self.hide()

    def stopAction(self):
    	global debug
        if debug: print "kAnyRemote.stopAction()"

	self.cReader.saveConfig()
	
	# To avoid socket.error: (98, 'Address already in use') 
	# it needs to close client socket first
        os.system('pkill -f "python .*anyremote2html"')
        os.system('killall -9 anyremote')

	self.setStatusStopped()

    def exec_clicked(self):
    	global cmdToSend, debug
       
	if debug:
            print 'Add to queue ' + self.command.text()
            cmdToSend = self.command.text()

    def runAction(self):
	global port, debug, lastCfgFile

        if debug: print "kAnyRemote.runAction()"
        
	self.cReader.saveConfig()
	
	self.setStatusDisconnected()
	startAnyRemote(lastCfgFile, self.cReader.runWeb_)	
			    
    def restartUpdater(self):
        self.stopUpdater()
	self.startUpdater()

    def startUpdater(self):
        if self.cReader.updateTmout_ > 0:
    	    self.statusUpdater = StatusUpdater(self,self.cReader.updateTmout_)
    	    self.statusUpdater.start()

    def stopUpdater(self):
	try:
	    self.statusUpdater.stop()
	except AttributeError, NameError:
	    pass

	time.sleep(0.5)

    def __tr(self,s,c = None):
        return qApp.translate("kAnyRemote",s,c)

    def __trUtf8(self,s,c = None):
        return qApp.translate("kAnyRemote",s,c,QApplication.UnicodeUTF8)

    def populateCfgFiles(self):
        global debug
	if debug: print 'populateCfgFiles'
	    
	self.stopUpdater()
	
	cfgFileReader = CfgFileReader(self, self.cReader)
	self.listView1.clear()
	cfgFileReader.start()
	
    def setStatustext(self,text):
        self.statusBar().clear()
        self.statusBar().message(text)
	
    def setStatusStopped(self):
        global debug
    
        setIcon("kanyremote_off")
	self.conn_status = 0
	
	self.setStatustext('anyRemote stopped')
        self.stop.setEnabled(False)
	self.start.setEnabled(True)
	self.stop_button.setEnabled(False)
	self.run_button.setEnabled(True)

	if debug:
            self.execcmd.setEnabled(False)

    def setStatusDisconnected(self):
        global debug
    
        setIcon("kanyremote_light")
	self.conn_status = 1
	self.setStatustext('Disconnected from phone')
	
        self.stop.setEnabled(True)
	self.start.setEnabled(False)
	self.stop_button.setEnabled(True)
	self.run_button.setEnabled(False)
	
	if debug:
            self.execcmd.setEnabled(False)

    def setStatusConnected(self):
        global debug
    
        setIcon("kanyremote")
	self.conn_status = 2
	self.setStatustext('Connected to phone')
	if debug:
            self.execcmd.setEnabled(True)
	
    def listUpdate(self, data):
        #print 'listUpdate',data
	st = self.getStatus(data[2],data[1])

	item = self.listView1.firstChild() 
        while item != None:
	    try:
	        if int(item.text(4)) == data[0]:
	            item.setText(1,st)
	            break
            except ValueError:
	        pass   
	    item = item.nextSibling()

    def selectLastInList(self):
        global lastCfgFile
    
        idx = None
    	for k, v in appData.iteritems():
	    if v[5] == lastCfgFile:
		idx = k

	item = self.listView1.firstChild() 
        while item != None:
	    try:
	        if int(str(item.text(4))) == idx:
		    self.listView1.setCurrentItem(item)
	            return
            except ValueError:
	        pass   
	    item = item.nextSibling()
    
    def translateMsg(self, data):
    	global debug
	if debug:
	    print 'translateMsg '+data

	if data == '':
	   return
	elif data == 'Exiting':
	   self.setStatusStopped()
	   return
	elif data == 'Connected':
	   self.setStatusConnected()
	   return
	elif data == 'Disconnected':
	   self.setStatusDisconnected()
	   return
	if data == '(Init)':
	   msg = 'anyRemote initialized'
	else:
	   print 'translateMsg BlinkThread'
	   
	   # Just key press   
    	   self.bTh = BlinkThread(self)
    	   self.bTh.start()
	   if debug:
	       msg = data
	   else:
	       return
	
	self.setStatustext(msg)
	    
    def customEvent(self,event):
        global appData
	
	if event.type() == 20000:
           self.setStatusStopped()
        elif event.type() == 20003:
	   cfgFile = getResult('ps aux |grep anyremote|grep cfg|awk \'{n=split($0,arr);print arr[n];}\'', 'frontend')

	   if cfgFile != '':
		for k, v in appData.iteritems():
	            if appData[k][5] == cfgFile:
		        appData[k][6] = 'Managed'
			self.listUpdate([k,appData[k][6],'OK'])
           self.setStatusDisconnected()
        elif event.type() == 20001:
           setIcon("kanyremote_flash")
        elif event.type() == 20002:
           setIcon("kanyremote")
        elif event.type() == 20004:
           self.addRow(event.data())
        elif event.type() == 20005:
           self.cfgWinClosed(event.data())
        elif event.type() == 20006:
           self.listUpdate(event.data())
        elif event.type() == 20007:
	   self.selectLastInList()
           self.restartUpdater()
        elif event.type() == 20008:
           self.dcopHandleSend(event.data())
        elif event.type() == 20009:
           self.dcopHandleGetMode()
        elif event.type() == 20010:
           self.restartUpdater()
        elif event.type() == 20011:
           restartBtComm()
        elif event.type() == 20012:
	   for k, v in appData.iteritems():
	       if appData[k][6] == 'Managed':
	           aRun = appData[k][3]
		   isRun = ''
	           if aRun != '':
	    	        isRun  = getResult(aRun,'main')
                    
		        if isRun == 'OK':
		            appData[k][6] = 'Running'
		        else:
		            appData[k][6] = 'Available'
		   else:
		        appData[k][6] = '' 

	   	   self.listUpdate([k,appData[k][6],isRun])

        else:
           self.translateMsg(event.data())
           
    def pushTrayIcon(self):
        if self.isShown == 1:
            self.hide()
            self.isShown = 0
        else:
            self.show()
            self.isShown = 1
	    
    def cfgWinClosed(self, isChanged):
        self.properties.setEnabled(True)
	if isChanged:
	    self.populateCfgFiles()
	    
    def dcopHandleSend(self, cmd):
        global cmdToSend
	if debug:
            print 'Add to queue ' + cmd
        cmdToSend = cmd
	
    
###############################################################################	
#
#	Configuration management
#
###############################################################################	

class ConfigReader:
    def saveConfig(self):
    
    	global lastCfgFile
	
    	cfg = os.environ.get("HOME")+os.sep+'.anyRemote'
    	if not os.path.exists(cfg):
	    os.mkdir(cfg)
	    
	f=open(cfg + os.sep + 'anyremote-fe.conf', 'w')
	if f:
 	    f.write('LastCfgFile='+lastCfgFile+'\n')
	    
	    if self.showAll_:
	        f.write('Show=All\n')
	    else:
	    	what = 'Show='
		if self.showApps_:
		    what = what + 'Apps,'
		if self.showCustom_:
		    what = what + 'Custom,'
		if self.showExamples_:
		    what = what + 'Examples,'
		if self.showAt_:
		    what = what + 'AT,'
		if self.showSrv_:
		    what = what + 'Server,'
		if self.showBm_:
		    what = what + 'Bemused,'
	    	
		f.write(what+'\n')

	    ac = '0'
            if self.autoReconn_:
	        ac = '1'
 	    f.write('AutoReconnectAT='+ac+'\n')
	    
	    if self.runWeb_:
	        f.write('WebInterface='+self.webParams_+'\n')

	    if self.device_ != '':
	        f.write('OverrideDevice='+self.device_+'\n')

	    #if self.updateTmout_ != -1:
	    tm = "%s" % (self.updateTmout_)
	    f.write('UpdateTimeout='+tm+'\n')
		
	    dirs = 'CfgDirs='
	    for d in self.cfgDirs:
	    	if d != '':
	            dirs = dirs +d + ';'
 	    f.write(dirs+'\n')
	    
	    if self.browseTmout_ > 0:
	        tm = "%s" % (self.browseTmout_)
	        f.write('DeviceBrowserTimeout='+tm+'\n')
            else:
	        f.write('DeviceBrowserTimeout=-1\n')
	   
	    f.write('JavaDir='+self.javaDir_+'\n')
	    
	    f.close()
	    
	# device browser related part
	f=open(cfg + os.sep + 'anyremote-peers.conf', 'w')
	if f:
	    for k, v in bt_devices.iteritems():

		row = bt_devices[k]
	        v1 = row[0]
	        v2 = row[1]
	        v3 = row[2]
	        v4 = row[3]
		
		f.write('Device='+v1+','+v2+','+v3+','+v4+'\n')

	    f.close()

    def setDefaultConfig(self):
    	global lastCfgFile

	lastCfgFile        = ''
	self.cfgDirs       = []	
	self.javaDir_      = ''	
	self.showApps_     = True
	self.showCustom_   = False
	self.showExamples_ = False
	self.showAt_       = False
	self.showSrv_      = True
	self.showBm_       = False
	self.showAll_      = False
	self.autoReconn_   = False
	self.device_       = ''
	self.runWeb_       = False
	self.webParams_    = ''
	self.updateTmout_  = 60
	self.browseTmout_  = -1
	
    def readConfig(self):
    	global lastCfgFile
	
       	cfg  = os.environ.get("HOME")+os.sep+'.anyRemote' + os.sep + 'anyremote-fe.conf'
	
    	if os.path.exists(cfg) :
	    f=open(cfg, 'r')
	    if f:
	        for line in f:
		    line = line.replace('\n','')
		    os.path.exists(cfg) 
		    if line.startswith('LastCfgFile='):
		        lastCfgFile=line[12:]
		    elif line.startswith('Show='):
		    	#Show=Apps,Custom,Examples|All
			what = line[5:].split(',')
			
			# override defaults
	                self.showApps_ = False
			self.showSrv_  = False
			
			for item in what:
			   if item == 'All':
			      self.showAll_ = True
			   elif item == 'Apps':
			      self.showApps_ = True
			   elif item == 'Custom':
			      self.showCustom_ = True
			   elif item == 'Examples':
			      self.showExamples_ = True
			   elif item == 'AT':
			      self.showAt_ = True
			   elif item == 'Server':
			      self.showSrv_ = True
			   elif item == 'Bemused':
			      self.showBm_ = True
			      
		    elif line.startswith('AutoReconnectAT='):
		        self.autoReconn_ = (line == 'AutoReconnectAT=1')
		    elif line.startswith('OverrideDevice='):
		        self.device_ = line[15:]
		    elif line.startswith('WebInterface='):
		        self.runWeb_    = True
		        self.webParams_ = line[13:]
                    elif line.startswith('CfgDirs='):
		        self.cfgDirs=line[8:].split(';')
                    elif line.startswith('UpdateTimeout='):
		        self.updateTmout_=int(line[14:])
                    elif line.startswith('DeviceBrowserTimeout='):
		        tmt=line[21:]
    	    	        try:
    	    		    self.browseTmout_=int(tmt)
    	    	        except ValueError:
			    self.browseTmout_=-1

			if self.browseTmout_ <= 0:
			    self.browseTmout_=-1
                    elif line.startswith('JavaDir='):
		        self.javaDir_=line[8:]
		    
	    	f.close()
	        
		# Try to search again
		if self.javaDir_ == '':
		    self.javaDir_ = getJ2MEPath()

		
	# device browser related part
       	cfg  = os.environ.get("HOME")+os.sep+'.anyRemote' + os.sep + 'anyremote-peers.conf'
	
    	if os.path.exists(cfg) :
	    f=open(cfg, 'r')
	    if f:
	        for line in f:
		    line = line.replace('\n','')
		    os.path.exists(cfg)
		    
		    if line.startswith('Device='):
		        deviceData=line[7:].split(',')
			
			v1 = deviceData[0]
			v2 = deviceData[1]
			v3 = deviceData[2]
			v4 = deviceData[3]
			
			bt_devices[v1] = [v1,v2,v3,v4,'']
	    	f.close()
	
##################################################################################
#
# Utilities functions
#
##################################################################################

def getMode(cfile):
    global appData
    for k, v in appData.iteritems():
	if appData[k][5] == cfile:
	    return appData[k][7]

    return ''
    
def startAnyRemote(cfile, webIface):
    global debug, cfgReader
    
    os.system('pkill -f "python .*anyremote2html"')
    os.system('killall -9 anyremote')
	
    time.sleep(0.5)

    web = ''
    if webIface:
    	web = ' -http'

    dev = ''
    if cfgReader.device_ != '':
    	dev = ' -s '+ cfgReader.device_

    log = ''
    if debug:
    	log = ' -log'

    useType = getMode(cfile)
    
    rconn = ''
    if cfgReader.autoReconn_ != '' and (useType == 'AT' or useType == ''):
    	    rcomm = ' -a '
    	    
    to_path = os.environ.get("HOME") + os.sep + '.anyRemote' + os.sep

    cmd = 'anyremote -fe ' + port + log + web + ' -f ' + cfile + dev + rconn + ' > '+ to_path + 'anyremote.stdout &'
    if debug: print cmd
    os.system(cmd)
    
    if webIface:
        dd = ''
    	if debug: dd = '-d '
  
        cmd = 'anyremote2html ' + dd + ' -a ' + cfgReader.device_[7:] + ' ' + cfgReader.webParams_ + ' > '+ to_path + 'anyremote2html.stdout &'
        if debug: print cmd
        os.system(cmd)

#####################################################################################    

def sendEvent(receiver, eid, data):
    global quitFlag
    
    if quitFlag:
        return
    
    event = QCustomEvent(eid)
    event.setData(data)
    QThread.postEvent(receiver, event)

def setIcon(iconName):
    global systray, iconsK
    #print 'setIcon',iconName
    systray.setPixmap (iconsK.loadIcon(iconName, KIcon.Small))

def errorMessage(widget, message):
    ret = QMessageBox.warning(widget,"kAnyRemote",message,QMessageBox.Ok);

def infoMessage(widget, message):
    ret = QMessageBox.warning(widget,"kAnyRemote",message,QMessageBox.Ok);

def getJ2MEPath():
    path = ''
    if os.path.exists('/usr/share/anyremote-J2ME-client'):
        path = '/usr/share/anyremote-J2ME-client'
    elif os.path.exists('/usr/local/share/anyremote-J2ME-client'):
        path = '/usr/local/share/anyremote-J2ME-client'
    return path

def isInstalled(app):
    dirs = os.getenv('PATH').split(':')
    for d in dirs:
        if os.path.exists(d+'/'+app):
            return 'OK'
    return 'NOK'
	
def getResult(cmd, suffix):
    #print 'getResult',cmd, suffix

    toFile = os.environ.get("HOME") + os.sep + '.anyRemote' + os.sep + 'kanyremote-' + suffix + '.tmp'
    os.system(cmd + '> ' + toFile)
    line = getLineTmpFile(toFile)
    return line.replace('\n','')

def getLineTmpFile(toFile):
    fd = open(toFile,'r')
    ln = ''
    if fd:
    	ln=fd.readline()
    	fd.close()
    return ln

def btVerify(window,showmsg):
    hcid = getResult('echo \'A=`ps -ef|grep hcid|grep -v grep|grep -v defunct`; if [ "x$A" == "x" ]; then echo NOK; else echo OK; fi\' | bash -f -s','main')
    if showmsg and hcid == 'NOK':
        infoMessage(window,'Bluetooth service is not active')
    return hcid

def initVerify(window):

    tool = isInstalled('anyremote')
    if tool == 'NOK':
        errorMessage(window, 'anyRemote not found !\nPlease install it or correct $PATH')

    tool = isInstalled('sdptool')
    if tool == 'NOK':
        errorMessage(window, 'sdptool not found !\nPlease install bluez-util')

    z = btVerify(window,True)

def showDetailsWin(v1,v2,v3,v4,v5):
    global dwin, cfgReader
    dwin = DeviceDetail(v1, v2, v3, v4, v5, cfgReader.javaDir_)
    dwin.show()
    
def closeDetailsWin():
    global dwin
    try:
        dwin.destroy()
        dwin = None
    except AttributeError, NameError:
	pass

def showBrowserWin():
    global browserWin
    browserWin = DeviceBrowser()
    browserWin.show()

def closeBrowserWin():
    global browserWin
    try:
    	browserWin.destroy()
    	browserWin = None
    except AttributeError, NameError:
    	pass

def showChkCfgWin():
    global chkCfgWin
    chkCfgWin = CfgChecker()
    chkCfgWin.show()

def closeChkCfgWin():
    global chkCfgWin
    try:
    	chkCfgWin.destroy()
    	chkCfgWin = None
    except AttributeError, NameError:
    	pass

def getAvailableSet():
    global bt_devices

    s = []
    for k, v in bt_devices.iteritems():
    	if v[4] == 'Available':
	    s.append(v[0])
    
    return Set(s)

def getDevSet():
    global bt_devices

    s = []
    for k, v in bt_devices.iteritems():
    	s.append(v[0])
    
    return s
    
def browseDevices():
    global cmd_array, debug
    
    if ['scan',''] in cmd_array:
        if debug:
	    print 'Skip device scan'
    else:
	queueBT('scan','')

    return True

def restartBtComm():
    stopBtComm()
    startBtComm()
	
def timerBrowseDevices():
    global cfgReader, quitFlag, browseTimer

    if cfgReader.browseTmout_ > 0 and not quitFlag:
    	browseDevices()
    	browseTimer = QTimer.singleShot(1000*cfgReader.browseTmout_, timerBrowseDevices)

def startBtComm():
    global bt, usepybluez, cfgReader, browseTimer, browseFlag, debug
    if debug: print 'startBtComm'

    if usepybluez == True and bt == None: 
    	bt = BtComm(cfgReader.javaDir_)
    	bt.start()
	
	if cfgReader.browseTmout_ > 0:
	    # give 5 sec. to thread for start
    	    browseTimer = QTimer.singleShot(5000, timerBrowseDevices)

def stopBtComm():
    global bt, browseTimer, debug
    if debug: print 'stopBtComm'
    
    try:
    	bt.stop()
    except AttributeError, NameError:
        print 'Exception: bt.stop()'
    	pass
    time.sleep(0.5)
    bt = None

def queueBT(tag,address):
    global debug

    if debug: print 'queueBT',cmd_array
    i = len(cmd_array)-1
    if i > 0 and cmd_array[i] == ['scan','']:
        cmd_array.insert(i,[tag,address])
    else:
        cmd_array.append([tag,address]) 

def startFrontend(receiver):
    global frontEnd
    frontEnd = FrontEnd(receiver)
    frontEnd.start()

def stopFrontend():
    global debug, frontEnd
    if debug: print 'stopFrontend'

    # To avoid socket.error: (98, 'Address already in use') 
    # it needs to close client socket first
    os.system('pkill -f "python .*anyremote2html"')
    os.system('killall -9 anyremote')

    time.sleep(0.5)

    try:
    	frontEnd.stop()
    except AttributeError, NameError:
    	pass
	
    frontEnd = None

##################################################################################
#
# DCOP
#
##################################################################################

class kAnyRemote_DCOP (DCOPExObj):
    def __init__ (self, rcv, id="anyRemote"):
        DCOPExObj.__init__ (self, id)
        self.receiver = rcv

        self.addMethod ("void sendCommand(QString)", self.sendCommand)
        self.addMethod ("bool isConnected()", self.isConnected)

    def sendCommand(self, cmd):
        sendEvent(self.receiver,20008,cmd)

    def isConnected(self):
        return (self.receiver.conn_status == 2)

##################################################################################
#
# Main function
#
##################################################################################

def main():

    global app, aboutData, systray, iconsK, debug, port, statusUpdater, cmdToSend, guiMode, usepybluez, cfgReader
	
    cmdToSend     = ''
    statusUpdater = ''
    guiMode       = 'simple'
    usepybluez    = True
    
    description = 'KDE GUI front end for anyRemote (bluetooth remote control for PC)'
    version     = "4.9"

    aboutData = KAboutData ("kanyremote", "kanyremote", version, description, KAboutData.License_GPL, "(C) 2007 Mike Fedotov")
    aboutData.addAuthor ("Mike Fedotov", "", "anyremote@mail.ru")

    sys.argv.extend(['--icon', 'kanyremote', '--caption', "kAnyRemote"])
		     
    KCmdLineArgs.init (sys.argv, aboutData)
    KCmdLineArgs.addCmdLineOptions ([("d", "Debug"),("debug", "Debug"),("n", "Do not use PyBluez"),("e", "Expert mode"),("expert", "Expert mode"),("p ", "Port"),("port ", "Port"),("o", "Open window")])
    
    args = KCmdLineArgs.parsedArgs();
    
    if args.isSet("d") | args.isSet("debug"):
	debug   = True
        guiMode = 'expert'
    
    if args.isSet("e") | args.isSet("expert"):
        guiMode = 'expert'
   
    if args.isSet("p"):
	q = args.getOption('p')
	port = q.data()

    if args.isSet('port'):
	q = args.getOption('port')
	port = q.data()
	
    if args.isSet("n"):
        usepybluez = False
    
    if pybluez == False and usepybluez == True:
        print 'Install PyBluez first !\nOr run with --nopybluez option'
	return
	
    print 'Use port ' + port
    if debug:
        print 'Debug Yes'
    else:   
       print 'Debug No'
   
    cfg = os.environ.get("HOME")+os.sep+'.anyRemote'
    if not os.path.exists(cfg):
	os.mkdir(cfg)
	
    app = KApplication()

    needWiz = False
    cfgReader = ConfigReader()
    cfgReader.setDefaultConfig()
    if os.path.exists(cfg+os.sep+'anyremote-fe.conf'):
	cfgReader.readConfig()
    else: 
        cfgSet = False
    
	if os.path.exists('/usr/share/anyremote/cfg-data'):
	    cfgSet = True
	    cfgReader.cfgDirs.append('/usr/share/anyremote/cfg-data')
	elif os.path.exists('/usr/local/share/anyremote/cfg-data'):
	    cfgSet = True
	    cfgReader.cfgDirs.append('/usr/local/share/anyremote/cfg-data/')
	    
	cfgReader.javaDir_ = getJ2MEPath()
	
        if not cfgSet or cfgReader.javaDir_ == '':
            needWiz = True
    
    iconsK = KIconLoader()
	
    mainWindow = kAnyRemote(cfgReader, needWiz, None, "kAnyRemote")
    
    dcop = kAnyRemote_DCOP(mainWindow,'anyRemote')
    
    if args.isSet("o"):
        mainWindow.isShown = 1
        mainWindow.show()
    else:
        mainWindow.isShown = 0
    
    initVerify(mainWindow)

    systray = KSystemTray (mainWindow)
    setIcon("kanyremote_off")
    
    pmenu = systray.contextMenu()

    pmenu.insertItem(QIconSet(iconsK.loadIcon("run",  KIcon.Small)), "Start", mainWindow.runAction,  QKeySequence(),3,3)
    pmenu.insertItem(QIconSet(iconsK.loadIcon("stop", KIcon.Small)), "Stop",  mainWindow.stopAction, QKeySequence(),4,4)

    systray.show ()

    app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
    app.connect(systray, SIGNAL("quitSelected()"), mainWindow.fileExit)
	    
    mainWindow.setStatusStopped()
   
    startFrontend(mainWindow)
    
    app.exec_loop()

if __name__ == "__main__":
    global debug, port, cmdToSend, appData, bt_devices, quitFlag, cmd_array, browserWin, chkCfgWin, dwin, bt, pbarTimer, pbar 

    port       = '5050'
    debug      = False
    appData    = dict()
    bt_devices = dict()
    cmdToSend  = ''
    quitFlag   = False
    cmd_array  = []    
    dwin       = None    
    browserWin = None    
    chkCfgWin  = None    
    bt         = None
    pbarTimer  = None
    pbar       = None
    
    main()
