#!/usr/bin/python
#
# We're using PySide, Nokia's official LGPL bindings.
# You can however easily use PyQt (Riverside Computing's GPL bindings) by commenting these and fixing the appropriate imports.
import sys, os, time, subprocess
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtMaemo5 import QMaemo5InformationBox
import dbus
from dbus.mainloop.qt import DBusQtMainLoop
import re
import urllib2
import socket
import gtk
from struct import pack, unpack
from httplib import HTTP
import sqlite3 as lite
 
# In Qt, everything is a class.
# We can subclass stuff to do whatever we want - it seems a bit strange at first,
# but it keeps all related functionality in one place, which helps to keep you organised.
#
# We're subclassing 'QWidget' here. QWidget is the base class for all graphical elements in Qt.
# You can do all sorts of cool things like drawing your widget yourself, but we won't get into that.
#
# See also:
#   http://doc.trolltech.com/4.6/qwidget.html

####################
# Global variables #
####################
CellNet_InfoVersion = "0.0.1-13"
infoTXT = ""
country_selected = ""
mcc_selected = ""
operator_selected = ""
mnc_selected = ""
proc = ""
CommentChar = '#'
OptionChar =  ' '
Home = os.path.expanduser("~")
Cellnet_CfgDir = Home + '/.config/cellnet-info/'
dbPath = '/opt/cellnet-info/data'
dbFile = 'operator_info.db'
NetWorkAccess = True
LatLongProvider = "google"
openCellID_apikey = ""
secColor = ""

def get_color(logicalcolorname):
    settings = gtk.settings_get_default()
    color_style = gtk.rc_get_style_by_paths(settings, 'GtkButton', \
        'osso-logical-colors', gtk.Button)
    return color_style.lookup_color(logicalcolorname)

def showShortMessage(message):
    ''' Method to display shortly a message to the user. '''

    os.system('run-standalone.sh dbus-send --type=method_call --dest=org.freedesktop.Notifications \
               /org/freedesktop/Notifications \
               org.freedesktop.Notifications.SystemNoteInfoprint \
               string:"%s"' % message)

class MyMainWindow(QMainWindow):
    def __init__(self, parent=None):# first things first, we need to initialise the Qt parent, otherwise it won't work properly.
        #
        super(MyMainWindow, self).__init__(parent)
        self.setAttribute(Qt.WA_Maemo5StackedWindow)
        global Orientation
        global NetWorkAccess
        global LatLongProvider
        global openCellID_apikey
        global secColor

        self.setWindowTitle(self.tr("cellnet-info"))
        secColor = get_color('SecondaryTextColor').to_string()[:7]

        self.form_widget = FormWidget(self)
        self.setCentralWidget(self.form_widget)

        self.setAttribute(Qt.WA_Maemo5AutoOrientation, True)
        ###############
        # Create menu #
        ###############
        aboutAction = QAction( '&About', self)
        self.configAction = QAction(self.tr('&Settings'), self)

        # Create config dir if needed
        if not os.path.exists(Cellnet_CfgDir):
            os.mkdir(Cellnet_CfgDir)

        ###############
        # read config #
        ###############
        settings = QSettings("cellnet-info", "cellnet-info")
        if settings.value('access_internet', type=bool) == "true":
            NetWorkAccess = True
        else: NetWorkAccess = False
        if settings.value('coord_provider') == "opencellid":
            LatLongProvider = "opencellid"
        openCellID_apikey = settings.value('opencellid_apikey')


        ########################
        # create menu from bar #
        ########################
        menubar = self.menuBar()
        mainMenu = menubar.addMenu('&MainMenu')
        mainMenu.addAction(self.configAction)
        mainMenu.addAction(aboutAction)

        ##################
        # Define actions #
        ##################
        self.configAction.triggered.connect(self.slotConfig)
        aboutAction.triggered.connect(self.aboutPushed)

    def slotConfig(self):
        # show config screen
        a = ConfigWindow(self)
#        self.connect(a, SIGNAL("destroyed()"),self.checkIsDim)
        a.show()

    def aboutPushed(self):
        d = QDialog(self)
        vbox = QVBoxLayout()
        verticalLayout = QVBoxLayout()
        d.setWindowTitle(self.tr("About CellNet-Info"))
        verticalLayout.addWidget(QLabel("<center><img src=/opt/usr/share/icons/hicolor/64x64/apps/cellnet-info.png /></center>"),0)
        verticalLayout.addWidget(QLabel("<center><b><big>CellNet-Info <font color="+secColor+">"+CellNet_InfoVersion+"</big></b></center></font>"),1)
        verticalLayout.addWidget(QLabel("<center>Created by Arno Dekker (ade)</center>"),2)
        vbox.addLayout (verticalLayout)
        d.setLayout(vbox)
        d.show()

class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        # Now we start getting into building our interface. The first thing we need to learn about are layouts.
        # Layouts tell Qt where to put widgets, and how they fit with other widgets.
        # Unlike Gtk+, Qt layouts are *not* widgets - important difference to keep in mind.
        #
        # There are many types of layouts (from the complex, like QGridLayout) 
        # to the simple, like what we're using here.
        # See also:
        #   http://doc.trolltech.com/4.6/qlayout.html
        #   http://doc.trolltech.com/4.6/qvboxlayout.html
        self.WindowOpen = False
        # Layout
        self.grid = QGridLayout()
        infoTXT = "<h2>CellNet-Info</h2>"
        self.headerLabel = QLabel(infoTXT)
        self.headerLabel.setStyleSheet(
        "QLabel { font:bold; color: "+ secColor + ";}"
            )
        self.headerLabel.setAlignment(Qt.AlignCenter | Qt.AlignLeft)
        self.headerLabel.setWordWrap(True)
        self.siminfoButton = QPushButton()
        self.siminfoButton.setText("  Operator info")
        self.siminfoButton.setIcon(QIcon("/opt/cellnet-info/images/sim-card.png"))
        self.deviceinfoButton = QPushButton()
        self.deviceinfoButton.setText("  Device info")
        self.deviceinfoButton.setIcon(QIcon.fromTheme("general_call"))
        self.cellinfoButton = QPushButton("Current \ncellular info",self)
        self.cellinfoButton.setIcon(QIcon("/opt/usr/share/icons/hicolor/64x64/apps/cellnet-info.png"))
        self.globalinfoButton = QPushButton("Mobile\nnetworks",self)
        self.globalinfoButton.setIcon(QIcon("/opt/usr/share/icons/hicolor/64x64/apps/cellnet-info.png"))
        self.queryButton = QPushButton("Query mobile\ncode info",self)
        self.queryButton.setIcon(QIcon("/opt/cellnet-info/images/information-icon.png"))
        font = QFont()
        font.setPointSize(24)
        self.siminfoButton.setFont(font)
        self.deviceinfoButton.setFont(font)
        self.cellinfoButton.setFont(font)
        self.globalinfoButton.setFont(font)
        self.queryButton.setFont(font)
        # sizes
        self.headerLabel.setMinimumHeight(64)
        self.deviceinfoButton.setMinimumHeight(138)
        self.siminfoButton.setMinimumHeight(138)
        self.cellinfoButton.setMinimumHeight(138)
        self.globalinfoButton.setMinimumHeight(138)
        self.queryButton.setMinimumHeight(138)
        # signals/slots
        self.connect(self.siminfoButton, SIGNAL("clicked()"),self.siminfoButtonPressed)
        self.connect(self.deviceinfoButton, SIGNAL("clicked()"),self.deviceinfoButtonPressed)
        self.connect(self.cellinfoButton, SIGNAL("clicked()"),self.cellinfoButtonPressed)
        self.connect(self.globalinfoButton, SIGNAL("clicked()"),self.globalinfoButtonPressed)
        self.connect(self.queryButton, SIGNAL("clicked()"),self.queryButtonPressed)
        self.setLayout(self.grid)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.orientationChanged()

    def cellinfoButtonPressed(self):
        if not self.WindowOpen:
            # prevent opening of multiple windows
            self.WindowOpen = True
            widget = cellWindow(self)
            widget.setAttribute(Qt.WA_Maemo5StackedWindow)
            widget.setAttribute(Qt.WA_DeleteOnClose)
            self.connect(widget, SIGNAL("destroyed()"),self.openManWinTrue)
            widget.show()
    
    def siminfoButtonPressed(self):
        if not self.WindowOpen:
            # prevent opening of multiple windows
            self.WindowOpen = True
            # show progress indicator
            self.progress_sign = QMovie("/opt/cellnet-info/images/spinning-wheel.gif", QByteArray(), self)
            self.progress_sign.setCacheMode(QMovie.CacheAll)
            self.progress_sign.setSpeed(100)
            self.headerLabel.setMovie(self.progress_sign)
            self.progress_sign.start()
            # call widget
            widget = simWindow(self)
            widget.setAttribute(Qt.WA_Maemo5StackedWindow)
            widget.setAttribute(Qt.WA_DeleteOnClose)
            self.connect(widget, SIGNAL("destroyed()"),self.openManWinTrue)
            widget.show()
            self.progress_sign.stop()

    def deviceinfoButtonPressed(self):
        if not self.WindowOpen:
            # prevent opening of multiple windows
            self.WindowOpen = True
            widget = deviceWindow(self)
            widget.setAttribute(Qt.WA_Maemo5StackedWindow)
            widget.setAttribute(Qt.WA_DeleteOnClose)
            self.connect(widget, SIGNAL("destroyed()"),self.openManWinTrue)
            widget.show()

    def globalinfoButtonPressed(self):
        if not self.WindowOpen:
            # look for other networks here, as we can't go back one the stackedwindow is opened ?
            # start it in background, as we do not get any response
            global proc
            IsCanceled = False
            ResultReceived = False
            countdown = 24
            progress = QProgressDialog(
                "Please wait ...", "Cancel" , 0, countdown, self)
            proc = subprocess.Popen(['dbus-send' ,'--system', '--type=method_call', '--print-reply', \
                '--reply-timeout=666666', '--dest=com.nokia.phone.net', '/com/nokia/phone/net', \
                'Phone.Net.get_available_network'], stdout=subprocess.PIPE)
            # wait 0.5 seconds
            time.sleep(0.5)
            if proc.poll() is not None:
                # we must have received no celular info
                ResultReceived = True
            else:
                showShortMessage("Please wait while scanning...")

                progress.setWindowTitle("Scanning networks")
                progress.setWindowModality(Qt.WindowModal)
                progress.setAutoClose(True)
                progress.setMinimumDuration(0)
                progress.show()
                for x in range(0,countdown):
                    progress.setValue(x)
                    progress.setLabelText("Approx. <b>" + str((countdown-x)) + "</b> seconds left ...")
                    if proc.poll() is not None:
                        # we have received output
                        ResultReceived = True
                        break
                    if progress.wasCanceled():
                        IsCanceled = True
                        progress.close()
                        break
                    time.sleep(1)

            if not ResultReceived and not IsCanceled:
                # beyond expected time, wait in a loop or until canceled
                QApplication.processEvents() 
                progress.setLabelText("Still waiting ...")
                while (True):
                    QApplication.processEvents() 
                    time.sleep(1)
                    if proc.poll() is not None:
                        # we have received output
                        break
                    if progress.wasCanceled():
                        IsCanceled = True
                        break

            if not IsCanceled:
                # wait if we still have no output
                progress.hide()
                QApplication.processEvents() 
                # prevent opening of multiple windows
                self.WindowOpen = True
                widget = globalinfoWindow(self)
                widget.setAttribute(Qt.WA_Maemo5StackedWindow)
                widget.setAttribute(Qt.WA_DeleteOnClose)
                self.connect(widget, SIGNAL("destroyed()"),self.openManWinTrue)
                widget.show()

    def queryButtonPressed(self):
        if not self.WindowOpen:
            # prevent opening of multiple windows
            self.WindowOpen = True
            widget = queryWindow(self)
            widget.setAttribute(Qt.WA_Maemo5StackedWindow)
            widget.setAttribute(Qt.WA_DeleteOnClose)
            self.connect(widget, SIGNAL("destroyed()"),self.openManWinTrue)
            widget.show()

    def openManWinTrue(self):
        infoTXT = "<h2>CellNet-Info</h2>"
        self.headerLabel.setText(infoTXT)
        self.WindowOpen = False

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape 
            # first remove layout
            self.grid.removeWidget(self.headerLabel)
            self.grid.removeWidget(self.siminfoButton)
            self.grid.removeWidget(self.deviceinfoButton)
            self.grid.removeWidget(self.cellinfoButton)
            self.grid.removeWidget(self.globalinfoButton)
            self.grid.removeWidget(self.queryButton)
            # then add new layout
            self.grid.addWidget(self.headerLabel,0,0)
            self.grid.addWidget(self.siminfoButton,0,1)
            self.grid.addWidget(self.deviceinfoButton,1,0)
            self.grid.addWidget(self.cellinfoButton,1,1)
            self.grid.addWidget(self.globalinfoButton,2,0)
            self.grid.addWidget(self.queryButton,2,1)
        else:
            # portrait
            # first remove layout
            self.grid.removeWidget(self.headerLabel)
            self.grid.removeWidget(self.siminfoButton)
            self.grid.removeWidget(self.deviceinfoButton)
            self.grid.removeWidget(self.cellinfoButton)
            self.grid.removeWidget(self.globalinfoButton)
            self.grid.removeWidget(self.queryButton)
            # add new layout
            self.grid.addWidget(self.headerLabel,0,0)
            self.grid.addWidget(self.siminfoButton,1,0)
            self.grid.addWidget(self.deviceinfoButton,2,0)
            self.grid.addWidget(self.cellinfoButton,3,0)
            self.grid.addWidget(self.globalinfoButton,4,0)
            self.grid.addWidget(self.queryButton,5,0)

class ConfigWindow(QMainWindow):
    def __init__(self,parent):
        QMainWindow.__init__(self,parent)
        self.setWindowTitle(self.tr("Config CellNet-Info"))
        self.setAttribute(Qt.WA_Maemo5StackedWindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        area = QScrollArea()
        lay = QVBoxLayout()
        lay.addWidget(area)
        self.wg = QWidget()
        area.setWidget(self.wg)
        self.setCentralWidget(area)
        self.grid = QGridLayout(self.wg)
        self.wg.show()
        area.show()
        self.setLayout(self.grid)
        # define checkboxes
        self.netAccessCheckbox = QCheckBox(self.tr("Access internet for location"),self)
        if NetWorkAccess:
            self.netAccessCheckbox.setChecked(True)
        # add groupbox
        self.grid.addWidget(self.createProvGroup(),2,0,1,2)

        self.APITxt = QLabel("OpenCellID API key:")
        self.APITxt.setStyleSheet("QLabel { font:bold; }")
        self.APIURL = QLabel("<a href=\"http://opencellid.org/#&action=database.requestForApiKey\">Register here for OpenCellID API key</a>")
        self.APIURL.setOpenExternalLinks(True)
        self.opencellidAPI_Ed = QLineEdit()
        self.opencellidAPI_Ed.setPlaceholderText(self.tr("API key"))
        self.opencellidAPI_Ed.setText(openCellID_apikey)
        regex = QRegExp("(\\w+)[-](\\w+)[-](\\w+)[-](\\w+)[-](\\w+)")
        validator = QRegExpValidator(regex, self.opencellidAPI_Ed)
        self.opencellidAPI_Ed.setValidator(validator)
        self.APITxt.setMaximumHeight(80)
        self.APIURL.setMaximumHeight(80)
        if LatLongProvider == "opencellid":
            self.opencellidAPI_Ed.setEnabled(True)
        else:
            self.opencellidAPI_Ed.setEnabled(False)

        self.saveConfigButton = QPushButton(self.tr("Done"),self)
        self.saveConfigButton.setMinimumHeight(80)
        self.saveConfigButton.setStyleSheet("QPushButton { font:bold; }")

        # set correct layout
        self.orientationChanged()
        # signals
        self.connect(self.saveConfigButton, SIGNAL("clicked()"),self.saveConfig)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.connect(self.radio_opencellid, SIGNAL("toggled(bool)"), self.disable_edit)

    def disable_edit(self,value):
        if value is True:
            self.opencellidAPI_Ed.setEnabled(True)
        else:
            self.opencellidAPI_Ed.setEnabled(False)

    def createProvGroup(self):
        groupBox = QGroupBox("Coordinates provider:")
        groupBox.setMaximumHeight(200)
        self.radio_google = QRadioButton("&Google")
        self.radio_opencellid = QRadioButton("&OpenCellID")

        if LatLongProvider == "google":
            self.radio_google.setChecked(True)
        else:
            self.radio_opencellid.setChecked(True)
        vbox = QHBoxLayout()
        vbox.addWidget(self.radio_google)
        vbox.addWidget(self.radio_opencellid)
        vbox.addStretch()
        groupBox.setLayout(vbox)


        return groupBox

    def saveConfig(self):
        global NetWorkAccess
        global LatLongProvider
        global openCellID_apikey
        settings = QSettings("cellnet-info", "cellnet-info")
        if self.netAccessCheckbox.isChecked():
            NetWorkAccess = True
        else: NetWorkAccess = False
        if self.radio_google.isChecked():
            LatLongProvider = "google"
        elif self.radio_opencellid.isChecked():
            LatLongProvider = "opencellid"
        settings.setValue('access_internet',NetWorkAccess)
        settings.setValue('coord_provider',LatLongProvider)
        settings.setValue('opencellid_apikey',self.opencellidAPI_Ed.text())
        openCellID_apikey = self.opencellidAPI_Ed.text()
        try:
            settings.sync()
            showShortMessage("Configuration is successfully saved")
        except:
            showShortMessage("Could NOT save Configuration!")
        self.close()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape
            self.wg.resize(780,300)
            self.wg.setMinimumHeight(420)
            self.wg.setMaximumHeight(420)
            # first remove layout
            self.grid.removeWidget(self.netAccessCheckbox)
            self.grid.removeWidget(self.APITxt)
            self.grid.removeWidget(self.APIURL)
            self.grid.removeWidget(self.opencellidAPI_Ed)
            self.grid.removeWidget(self.saveConfigButton)
            # then add again
            self.grid.addWidget(self.netAccessCheckbox,1,0,1,2)
            self.grid.addWidget(self.APITxt,3,0)
            self.grid.addWidget(self.opencellidAPI_Ed,3,1)
            self.grid.addWidget(self.APIURL,4,0,1,2)
            self.grid.addWidget(self.saveConfigButton,9,0,1,2)
        else:
            # portrait
            self.wg.resize(470,680)
            self.wg.setMinimumHeight(740)
            self.wg.setMaximumHeight(740)
            # first remove layout
            self.grid.removeWidget(self.netAccessCheckbox)
            self.grid.removeWidget(self.APITxt)
            self.grid.removeWidget(self.APIURL)
            self.grid.removeWidget(self.opencellidAPI_Ed)
            self.grid.removeWidget(self.saveConfigButton)
            # then add again
            self.grid.addWidget(self.netAccessCheckbox,1,0,1,2)
            self.grid.addWidget(self.APITxt,3,0)
            self.grid.addWidget(self.opencellidAPI_Ed,4,0)
            self.grid.addWidget(self.APIURL,5,0,1,2)
            self.grid.addWidget(self.saveConfigButton,9,0,1,2)

class simWindow(QMainWindow):
    def __init__(self,parent):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle("Operator info")
        global infoTXT
        # layout
        area = QScrollArea()
        lay = QVBoxLayout()
        lay.addWidget(area)
        self.wg = QWidget()
        area.setWidget(self.wg)
        self.setCentralWidget(area)
        grid = QGridLayout(self.wg)
        self.wg.show()
        self.orientationChanged()
        area.show()
        self.setLayout(grid)
        # get info by using dbus
        self.bus = dbus.SystemBus()
        dbus_object = self.bus.get_object('com.nokia.phone.net', '/com/nokia/phone/net',False)
        dbus_interface = dbus.Interface(dbus_object, 'Phone.Net')
        # SIM/network status
        c_status = int(dbus_interface.get_registration_status()[0])
        if (c_status == 0): sim_status = "Normal mode"
        elif (c_status == 3): sim_status = "No SIM card found"
        elif (c_status == 4): sim_status = "Cellular modem \npowering down"
        elif (c_status == 8): sim_status = "Cellular modem \nswitched off"
        elif (c_status == 10): sim_status = "No signal"
        elif (c_status == 11): sim_status = "SIM registration failed"
        else: sim_status = "Unknown"
        dbus_object = self.bus.get_object('com.nokia.phone.SIM', '/com/nokia/phone/SIM',False)
        # IMSI
        siminfo = dbus.Interface(dbus_object, 'Phone.Sim')
        IMSI =  str(siminfo.get_imsi()[0])
        # SIM operator
        SIM_operator =  str(siminfo.get_service_provider_name()[0])
        # IMEI
        dbus_object = self.bus.get_object('com.nokia.phone.SIM', '/com/nokia/phone/SIM/security',False)
        IMEIinfo = dbus.Interface(dbus_object, 'Phone.Sim.Security')
        IMEI = str(IMEIinfo.get_imei()[0])
        # ICCID
        dbus_object = self.bus.get_object('com.nokia.phone.SSC', '/com/nokia/phone/SSC',False)
        ICCIDinfo = dbus.Interface(dbus_object, 'com.nokia.phone.SSC')
        ICCID = str(ICCIDinfo.get_iccid()).replace('f', '')
        ICCID = ''.join([ ICCID[x:x+2][::-1] for x in range(0, len(ICCID), 2) ])
        # MCUSW/DSPSW
        dbus_object = self.bus.get_object('com.nokia.csd.Info', '/com/nokia/csd/info',False)
        MCUSWinfo = dbus.Interface(dbus_object, 'com.nokia.csd.Info')
        MCUSW = str(MCUSWinfo.GetDSPSWVersion())
        # Unconditional Divert
        proc = subprocess.Popen(['dbus-send' ,'--system', '--dest=com.nokia.csd.SS', '--type=method_call', '--print-reply=literal', \
            '/com/nokia/csd/ss', 'com.nokia.csd.SS.DivertCheck', 'uint32:1'], stdout=subprocess.PIPE)
        while (True):
            QApplication.processEvents()
            time.sleep(1)
            if proc.poll() is not None:
                # we have received output
                break
        UncondDivert = proc.stdout.read().decode('UTF8').strip().split()
        if not UncondDivert:
            UncondDivert = "----"
        elif UncondDivert[1] == "true":
            UncondDivert = UncondDivert[2]
        else:
            UncondDivert = "----"
        # Busy divert
        proc = subprocess.Popen(['dbus-send' ,'--system', '--dest=com.nokia.csd.SS', '--type=method_call', '--print-reply=literal', \
            '/com/nokia/csd/ss', 'com.nokia.csd.SS.DivertCheck', 'uint32:2'], stdout=subprocess.PIPE)
        while (True):
            QApplication.processEvents()
            time.sleep(1)
            if proc.poll() is not None:
                # we have received output
                break
        BusyDivert = proc.stdout.read().decode('UTF8').strip().split()
        if not BusyDivert:
            BusyDivert = "----"
        elif BusyDivert[1] == "true":
            BusyDivert = BusyDivert[2]
        else:
            BusyDivert = "----"
        # No reply divert
        proc = subprocess.Popen(['dbus-send' ,'--system', '--dest=com.nokia.csd.SS', '--type=method_call', '--print-reply=literal', \
            '/com/nokia/csd/ss', 'com.nokia.csd.SS.DivertCheck', 'uint32:3'], stdout=subprocess.PIPE)
        while (True):
            QApplication.processEvents()
            time.sleep(1)
            if proc.poll() is not None:
                # we have received output
                break
        NoreplyDivert = proc.stdout.read().decode('UTF8').strip().split()
        if not NoreplyDivert:
            NoreplyDivert = "----"
        elif NoreplyDivert[1] == "true":
            NoreplyDivert = NoreplyDivert[2]
        else:
            NoreplyDivert = "----"
        # Not reachable divert
        proc = subprocess.Popen(['dbus-send' ,'--system', '--dest=com.nokia.csd.SS', '--type=method_call', '--print-reply=literal', \
            '/com/nokia/csd/ss', 'com.nokia.csd.SS.DivertCheck', 'uint32:4'], stdout=subprocess.PIPE)
        while (True):
            QApplication.processEvents()
            time.sleep(1)
            if proc.poll() is not None:
                # we have received output
                break
        NotreachableDivert = proc.stdout.read().decode('UTF8').strip().split()
        if not NotreachableDivert:
            NotreachableDivert = "----"
        elif NotreachableDivert[1] == "true":
            NotreachableDivert = NotreachableDivert[2]
        else:
            NotreachableDivert = "----"
        # network time:
        dbus_object = self.bus.get_object('com.nokia.phone.net', '/com/nokia/phone/net',False)
        networktimeInfo = dbus.Interface(dbus_object, 'Phone.Net')
        networktime = networktimeInfo.get_network_time_info()
        (yy, mm, dd, hh, mi, ss, tz, dl, err) = networktime
        if yy == 100:
            # assuming this means no networktime provided
            networktimeVal = "----"
        else:
            networktimeVal = str(yy)+"/"+str(mm)+"/"+str(dd)+" "+str(hh).zfill(2)+":" \
                +str(mi).zfill(2)+":"+str(ss).zfill(2)+ " UTC"
        # define screen content
        font = QFont()
        font.setPointSize(20)
        line1 = QFrame()
        line1.setLineWidth(3)
        line1.setMidLineWidth(3)
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)
        line2 = QFrame()
        line2.setLineWidth(3)
        line2.setMidLineWidth(3)
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)
        line3 = QFrame()
        line3.setLineWidth(3)
        line3.setMidLineWidth(3)
        line3.setFrameShape(QFrame.HLine)
        line3.setFrameShadow(QFrame.Sunken)
        IMSIlabel = QLabel(IMSI)
        IMSIlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        IMSItxt = QLabel("IMSI")
        IMSItxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        statustxt = QLabel("status")
        statustxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        self.statuslabel = QLabel(sim_status)
        self.statuslabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        ICCIDlabel = QLabel(ICCID)
        ICCIDlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        ICCIDtxt = QLabel("ICCID")
        ICCIDtxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        operatorlabel = QLabel(SIM_operator)
        operatorlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        operatortxt = QLabel("operator")
        operatortxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        unconditionalDivertTxt = QLabel("uncondit divert")
        unconditionalDivertTxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        UncondDivertlabel = QLabel(UncondDivert)
        UncondDivertlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        busyDivertTxt = QLabel("busy divert")
        busyDivertTxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        busyDivertlabel = QLabel(BusyDivert)
        busyDivertlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        noreplyDivertTxt = QLabel("no reply divert")
        noreplyDivertTxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        noreplyDivertlabel = QLabel(NoreplyDivert)
        noreplyDivertlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        notreachableDivertTxt = QLabel("notreach divert")
        notreachableDivertTxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        notreachableDivertlabel = QLabel(NoreplyDivert)
        notreachableDivertlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        networktimeTxt = QLabel("network time")
        networktimeTxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignRight';")
        networktimelabel = QLabel(networktimeVal)
        networktimelabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignRight';")
        # add to layout
        grid.addWidget(line1, 1, 0, 1, 2)
        grid.addWidget(statustxt,8,0)
        grid.addWidget(self.statuslabel,8,1)
        grid.addWidget(operatortxt,9,0)
        grid.addWidget(operatorlabel,9,1)
        grid.addWidget(IMSItxt,10,0)
        grid.addWidget(IMSIlabel,10,1)
        grid.addWidget(ICCIDtxt,11,0)
        grid.addWidget(ICCIDlabel,11,1)
        grid.addWidget(unconditionalDivertTxt,12,0)
        grid.addWidget(UncondDivertlabel,12,1)
        grid.addWidget(busyDivertTxt,13,0)
        grid.addWidget(busyDivertlabel,13,1)
        grid.addWidget(noreplyDivertTxt,14,0)
        grid.addWidget(noreplyDivertlabel,14,1)
        grid.addWidget(notreachableDivertTxt,15,0)
        grid.addWidget(notreachableDivertlabel,15,1)
        grid.addWidget(networktimeTxt,16,0)
        grid.addWidget(networktimelabel,16,1)
        grid.addWidget(line3, 17, 0, 1, 2)
        helpButton = QPushButton("Help",self)
        grid.addWidget(helpButton,18,0,1,2)
        # help text
        infoTXT = "<html><b><u>SIM</u><br>S</b>ubscriber <b>I</b>denity <b>M</b>odule<br>" \
        "An integrated circuit that securely stores the IMSI and the related key used " \
        "to identify and authenticate subscribers on mobile telephony devices (such as mobile phones and computers).<p>" \
        "<html><b><u>IMEI</u><br>I</b>nternational <b>M</b>obile <b>S</b>tation <b>E</b>quipment <b>I</b>dentify<br>" \
        "To uniquely identify the device. It is usually found printed inside the battery compartment of the phone. " \
        "It can also be displayed on the screen of the phone by entering *#06# into the keypad on most phones.<p>" \
        "<b><u>IMSI</u><br>I</b>nternational <b>M</b>obile <b>S</b>ubscriber <b>I</b>dentity<br>" \
        "A unique identification associated with all GSM, UMTS and LTE network SIM cards.<p>" \
        "<b><u>ICCID</u><br>I</b>ntegrated <b>C</b>ircuit <b>C</b>ard <b>Id</b>entifier<br>" \
        "CCIDs are stored in the SIM cards and are also engraved or printed on the SIM card body during a process " \
        "called personalization.<p></html>"
        # act as soon as display goes off
        busobj = self.bus.get_object('com.nokia.mce', '/com/nokia/mce/signal') 
        busiface = dbus.Interface(busobj, 'com.nokia.mce.signal')
        busiface.connect_to_signal('display_status_ind', self.displaystate_change)
        # signals
        self.connect(helpButton, SIGNAL("clicked()"),self.helpButtonPressed)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.bus.add_signal_receiver(self.signal_registration_status_change, dbus_interface = "Phone.Net", signal_name = "registration_status_change")

    def signal_registration_status_change(self, *values):
        c_status = values[0]
        if (c_status == 0): sim_status = "Normal mode"
        elif (c_status == 3): sim_status = "No SIM card found"
        elif (c_status == 4): sim_status = "Cellular modem \npowering down"
        elif (c_status == 8): sim_status = "Cellular modem \nswitched off"
        elif (c_status == 10): sim_status = "No signal"
        elif (c_status == 11): sim_status = "SIM registration failed"
        else: sim_status = "Unknown"
        self.statuslabel.setText(sim_status)

    def displaystate_change(self, state):
        if (state == "off"):
            self.remove_signals()
        elif (state == "on"):
            self.add_signals()

    def closeEvent(self, event):
        self.remove_signals()

    def remove_signals(self):
        # remove the signal receivers at leaving page
        self.bus.remove_signal_receiver(self.signal_registration_status_change, dbus_interface = "Phone.Net", signal_name = "registration_status_change")

    def add_signals(self):
        self.bus.add_signal_receiver(self.signal_registration_status_change, dbus_interface = "Phone.Net", signal_name = "registration_status_change")

    def helpButtonPressed(self):
        widget = helpWindow(self)
        widget.show()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
                # landscape
                self.wg.resize(780,300)
                self.wg.setMinimumHeight(420)
                self.wg.setMaximumHeight(420)
        else:
                # portrait
                self.wg.resize(470,680)
                self.wg.setMinimumHeight(740)
                self.wg.setMaximumHeight(740)

class deviceWindow(QMainWindow):
    def __init__(self,parent):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle("Device info")
        global infoTXT
        # layout
        area = QScrollArea()
        lay = QVBoxLayout()
        lay.addWidget(area)
        self.wg = QWidget()
        area.setWidget(self.wg)
        self.setCentralWidget(area)
        grid = QGridLayout(self.wg)
        self.wg.show()
        self.orientationChanged()
        area.show()
        self.setLayout(grid)
        # get info by using dbus
        # IMEI 
        self.bus = dbus.SystemBus()
        dbus_object = self.bus.get_object('com.nokia.phone.SIM', '/com/nokia/phone/SIM/security',False) 
        IMEIinfo = dbus.Interface(dbus_object, 'Phone.Sim.Security') 
        IMEI = str(IMEIinfo.get_imei()[0]) 
        # MCUSW/DSPSW
        dbus_object = self.bus.get_object('com.nokia.csd.Info', '/com/nokia/csd/info',False)
        MCUSWinfo = dbus.Interface(dbus_object, 'com.nokia.csd.Info')
        MCUSW = str(MCUSWinfo.GetMCUSWVersion()).replace("\n", " ").replace("(c) Nokia","")
        # Emergency numbers
        dbus_object = self.bus.get_object('com.nokia.csd.Call', '/com/nokia/csd/call',False)
        EmergencyNbrInfo = dbus.Interface(dbus_object, 'com.nokia.csd.Call')
        EmergencyNbr = EmergencyNbrInfo.GetEmergencyNumbers()
        EmergNbrs = ""
        for index_nr in range (0, len(EmergencyNbr)):
            EmergNbr = ''.join([character for character in EmergencyNbr[index_nr]])
            EmergNbrs = EmergNbrs + EmergNbr + "/"
        EmergNbrs = EmergNbrs.strip("/")
        # Profile
        profile = subprocess.Popen(['dbus-send' , '--dest=com.nokia.profiled', '--type=method_call', '--print-reply=literal', \
            '/com/nokia/profiled', 'com.nokia.profiled.get_profile'], stdout=subprocess.PIPE).stdout.read().strip()
        font = QFont()
        font.setPointSize(20)
        line1 = QFrame()
        line1.setLineWidth(3)
        line1.setMidLineWidth(3)
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)
        line2 = QFrame()
        line2.setLineWidth(3)
        line2.setMidLineWidth(3)
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)
        line3 = QFrame()
        line3.setLineWidth(3)
        line3.setMidLineWidth(3)
        line3.setFrameShape(QFrame.HLine)
        line3.setFrameShadow(QFrame.Sunken)
        IMEIlabel = QLabel(IMEI)
        IMEIlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignCenter';")
        IMEItxt = QLabel("<u>IMEI:</u>")
        IMEItxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignCenter';")
        MCUSWlabel = QLabel(MCUSW)
        MCUSWlabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignCenter';")
        MCUSWtxt = QLabel("<u>MCUSW:</u>")
        MCUSWtxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignCenter';")
        Emergencylabel = QLabel(EmergNbrs)
        Emergencylabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignCenter';")
        Emergencytxt = QLabel("<u>emergency numbers:</u>")
        Emergencytxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignCenter';")
        profilelabel = QLabel(profile)
        profilelabel.setStyleSheet("color: "+ secColor + "; qproperty-alignment: 'AlignCenter|AlignCenter';")
        profiletxt = QLabel("<u>current profile:</u>")
        profiletxt.setStyleSheet("qproperty-alignment: 'AlignCenter|AlignCenter';")
        # add to layout
        grid.addWidget(line1,1,0,1,2)
        grid.addWidget(IMEItxt,2,0,1,2)
        grid.addWidget(IMEIlabel,3,0,1,2)
        grid.addWidget(MCUSWtxt,4,0,1,2)
        grid.addWidget(MCUSWlabel,5,0,1,2)
        grid.addWidget(Emergencytxt,6,0,1,2)
        grid.addWidget(Emergencylabel,7,0,1,2)
        grid.addWidget(profiletxt,8,0,1,2)
        grid.addWidget(profilelabel,9,0,1,2)
        grid.addWidget(line3,10,0,1,2)
        helpButton = QPushButton("Help",self)
        grid.addWidget(helpButton,11,0,1,2)
        # help text
        infoTXT = "<html><b><u>IMEI</u><br>I</b>nternational <b>M</b>obile <b>S</b>tation <b>E</b>quipment <b>I</b>dentify<br>" \
        "To uniquely identify the device. It is usually found printed inside the battery compartment of the phone. " \
        "It can also be displayed on the screen of the phone by entering *#06# into the keypad on most phones.<p>" \
        "<b><u>MCUSW</u></b><br>Micro Controller Software version. Related to the DSP for audio processing (telephony)<p>"
        "</html>"
        # signals
        self.connect(helpButton, SIGNAL("clicked()"),self.helpButtonPressed)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)

    def helpButtonPressed(self):
        widget = helpWindow(self)
        widget.show()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
                # landscape
                self.wg.resize(780,300)
                self.wg.setMinimumHeight(420)
                self.wg.setMaximumHeight(420)
        else:
                # portrait
                self.wg.resize(470,680)
                self.wg.setMinimumHeight(740)
                self.wg.setMaximumHeight(740)


class cellWindow(QMainWindow):
    def __init__(self,parent):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle("Cellular info")
        global infoTXT
        global bus
        # layout
        area = QScrollArea()
        lay = QVBoxLayout()
        lay.addWidget(area)
        self.wg = QWidget()
        area.setWidget(self.wg)
        self.setCentralWidget(area)
        grid = QGridLayout(self.wg)
        self.wg.show()
        self.orientationChanged()
        area.show()
        self.setLayout(grid)
        # dbus
        self.bus = dbus.SystemBus()
        dbus_object = self.bus.get_object('com.nokia.phone.net', '/com/nokia/phone/net',False)
        dbus_interface = dbus.Interface(dbus_object, 'Phone.Net')
        tuple_cellstatus = dbus_interface.get_registration_status()
        (c_status, c_lac, c_id, c_mnc, c_mcc, c_type, c_services, c_err) \
            = tuple_cellstatus
        operator_name = str(dbus_interface.get_operator_name(dbus.Byte(0), c_mnc, c_mcc)[0])
        country_name = ""
        conn = None
        try:
            conn = lite.connect('%s/%s' % (dbPath, dbFile))
            cur = conn.cursor()
            cur.execute('''select country FROM operinfo where mcc = %s ''' %(c_mcc))
            country_name = cur.fetchone()[0]
            cur.close()
        except lite.Error, e:
            print "Error %s" % e.args[0]
        radio_technology = dbus_interface.get_selected_radio_access_technology()[0]
        if (radio_technology == 0): technology = "DUAL"
        elif (radio_technology == 1): technology = "GSM"
        elif (radio_technology == 2): technology = "3G"
        else: technology = "?"
        used_radio_technology = dbus_interface.get_radio_access_technology()[0]
        if (used_radio_technology == 1): used_technology = "GSM"
        elif (used_radio_technology == 2): used_technology = "3G"
        else: used_technology = "?"
        tuple_sigstrength = dbus_interface.get_signal_strength()
        c_sig_perc = int(tuple_sigstrength[0])
        c_sig_dbm = int(tuple_sigstrength[1])
        services = ""
        if (c_services & 0x02): services += 'CS '
        if (c_services & 0x01): services += 'GPRS '
        if (c_services & 0x04): services += 'EGPRS '
        if (c_services & 0x08): services += 'HSDPA '
        if (c_services & 0x10): services += 'HSUPA'
        self.location = "?"
        self.latitude = "?"
        self.longitude = "?"
        # try to fetch internet data
        if LatLongProvider == "opencellid" :
            # use opencellid API
            self.get_cell_id_info(c_mcc,c_mnc,c_id,c_lac)
        else:
            # use google API
            if str(c_id) != "0" and NetWorkAccess:
                self.latitude,self.longitude,validData,message = self.get_location_by_cell(c_id, c_lac, c_mnc, c_mcc)
                print self.latitude,self.longitude,validData,message
                if validData == 'True':
                    # get address
                    self.location = self.get_address_by_coordinates(self.latitude,self.longitude)
                else:
                    self.latitude = "?"
                    self.longitude = "?"
            elif not NetWorkAccess:
                print "Internet access switched off"
                self.location = "blocked"
                self.latitude = "blocked"
                self.longitude = "blocked"
            if self.longitude == "0.0" or self.latitude == "0.0":
                self.location = "unknown"
            
        # add layout
        line1 = QFrame()
        line1.setLineWidth(3)
        line1.setMidLineWidth(3)
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)
        line2 = QFrame()
        line2.setLineWidth(3)
        line2.setMidLineWidth(3)
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)

        grid.addWidget(line1,0,0,1,2)
        self.selectedTechTXT = QLabel()
        self.selectedTechTXT.setText("Phone mode <font color="+secColor+">" + technology)
        grid.addWidget(self.selectedTechTXT,1,0)
        self.usedTechTXT = QLabel()
        self.usedTechTXT.setText("Used mode <font color="+secColor+">" + used_technology)
        grid.addWidget(self.usedTechTXT,1,1)
        grid.addWidget(QLabel("MCC"),2,0)
        self.countryTXT = QLabel()
        self.countryTXT.setText(str(c_mcc)+" ("+country_name.strip()+")")
        self.countryTXT.setStyleSheet("color: "+ secColor + ";")
        grid.addWidget(self.countryTXT,2,1)
        grid.addWidget(QLabel("MNC"),3,0)
        self.operTXT = QLabel()
        self.operTXT.setStyleSheet("color: "+ secColor + ";")
        self.operTXT.setText(str(c_mnc)+ " ("+operator_name+")")
        grid.addWidget(self.operTXT,3,1)
        self.LACtxt = QLabel()
        self.LACtxt.setText("LAC <font color="+secColor+">" + str(c_lac))
        grid.addWidget(self.LACtxt,4,0)
        self.CIDtxt = QLabel()
        self.CIDtxt.setText("CID <font color="+secColor+">" + str(c_id & 65535))
        grid.addWidget(self.CIDtxt,4,1)
        self.Lattxt = QLabel()
        self.Lattxt.setText("Lat <font color="+secColor+">" + str(self.latitude)[:11] + u"\u00b0")
        grid.addWidget(self.Lattxt,5,0)
        self.Longtxt = QLabel()
        self.Longtxt.setText("Long <font color="+secColor+">" + str(self.longitude)[:11] + u"\u00b0")
        grid.addWidget(self.Longtxt,5,1)
        self.Loctxt = QLabel()
        self.Loctxt.setText("Loc <font color="+secColor+">" + self.location)
        grid.addWidget(self.Loctxt,6,0,1,2)
        grid.addWidget(QLabel("RNC-ID"),7,0)
        self.RNCtxt = QLabel()
        self.RNCtxt.setText(str(c_id >> 16))
        self.RNCtxt.setStyleSheet("color: "+ secColor + ";")
        grid.addWidget(self.RNCtxt,7,1)
        grid.addWidget(QLabel("Services"),8,0)
        servicestxt = QLabel(services.strip().replace(" ","+"))
        grid.addWidget(servicestxt,8,1)
        servicestxt.setStyleSheet("color: "+ secColor + ";")
        grid.addWidget(QLabel("Signal strength"),9,0)
        self.SignalTxt = QLabel()
        if c_sig_dbm >= 100 or c_sig_dbm == 0:
            dBm_perc = 0
        elif c_sig_dbm <= 50:
            dBm_perc = 100
        else:
            dBm_perc = 2 * -(c_sig_dbm - 100.0)
        self.SignalTxt.setText(str(c_sig_perc) + "%,-" + str(c_sig_dbm) + " dBm ("+str(int(dBm_perc))+"%)")
        self.SignalTxt.setStyleSheet("color: "+ secColor + ";")
        grid.addWidget(self.SignalTxt,9,1)
        helpButton = QPushButton("Help",self)
        grid.addWidget(line2,10,0,1,2)
        grid.addWidget(helpButton,11,0,1,2)
        infoTXT = "<html><b><u>GSM</u></b><br><b>G</b>lobal <b>S</b>ystem for <b>M</b>obile Communications. " \
        "Second generation (2G) digital cellular network. Supported: GSM 850/900/1800/1900<p>" \
        "<b><u>3G</u></b><br>short for third Generation, is a term used to represent the 3rd generation " \
        "of mobile telecommunications technology. Also called Tri-Band 3G. Supported: HSDPA 900/1700/2100<p>" \
        "<b><u>DUAL</u></b><br>Both 2G and 3G<p>" \
        "<b><u>MCC</u><br>M</b>obile <b>C</b>ountry <b>C</b>ode<p>" \
        "<b><u>MNC</u><br>M</b>obile <b>N</b>etwork <b>C</b>ode<br>" \
        "The combination of both (also known as a \"MCC / MNC tuple\") is used to uniquely identify a " \
        "mobile phone operator/carrier using the GSM/LTE, CDMA, iDEN, TETRA and UMTS public land mobile " \
        "networks and some satellite mobile networks.<p>" \
        "<b><u>LAC</u><br>L</b>ocatin <b>A</b>rea <b>C</b>ode<br>" \
        "Used to identify a location area within a GSM PLMN (Public Land Mobile Network)<p>" \
        "<b><u>CID</u><br>C</b>ell <b>ID</b><br>" \
        "A generally unique number used to identify each Base transceiver station (BTS) or sector of " \
        "a BTS within a Location area code (LAC) if not within a GSM network.<p>" \
        "<b><u>RNC-ID</u><br>R</b>adio <b>N</b>etwork <b>C</b>ontroller <b>Id</b>entification<br>" \
        "The Radio Network Controller (or RNC) is a governing element in the UMTS radio access network " \
            "(UTRAN) and is responsible for controlling the Node Bs that are connected to it. " \
        "The RNC carries out radio resource management, some of the mobility management functions and " \
        "is the point where encryption is done before user data is sent to and from the mobile<p>" \
        "<b><u>CS</u><br>C</b>ircuit <b>S</b>witched<br>" \
        "a methodology of implementing a telecommunications network in which two network nodes establish " \
        "a dedicated communications channel (circuit) through the network before the nodes may communicate. " \
        "The circuit guarantees the full bandwidth of the channel and remains connected for the duration of " \
        "the communication session. The circuit functions as if the nodes were physically connected as with " \
        "an electrical circuit.<p>" \
        "<b><u>GPRS</u><br>G</b>eneral <b>P</b>acket <b>R</b>adio <b>S</b>ervice<br>" \
        "a packet oriented mobile data service on the 2G and 3G cellular communication system's " \
        "global system for mobile communications<p>" \
        "<b><u>EGPRS</u><br>E</b>nhanced <b>G</b>eneral <b>P</b>acket <b>R</b>adio <b>S</b>ervice<p>" \
        "<b><u>HSDPA</u><br>H</b>igh <b>S</b>peed <b>D</b>ownlink <b>P</b>acket <b>A</b>ccess<br>" \
        "3G mobile telephony communications protocol for high speed data transfers<p>" \
        "<b><u>HSUPA</u><br>H</b>igh <b>S</b>peed <b>U</b>plink <b>P</b>acket <b>A</b>ccess<br>" \
        "The name HSUPA was created by Nokia. The official 3GPP name for 'HSUPA' is Enhanced Uplink (EUL)<p>" \
        "<b>Lat:</b> The latitude in decimal degrees<br>" \
        "<b>Long:</b> The longitude in decimal degrees<br>" \
        "<b>Loc:</b> The possible postal location of the cell tower<p>" \
        "<u>Percentage behind dBm:</u> based on the assumption that -50 dBm is perfect signal reception<p>" \
        "<i>N.b. an internet connection is needed for location details.</i><br>" \
        "<html>"
        # signals
        self.connect(helpButton, SIGNAL("clicked()"),self.helpButtonPressed)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)

        # act as soon as display goes off
        busobj = self.bus.get_object('com.nokia.mce', '/com/nokia/mce/signal') 
        busiface = dbus.Interface(busobj, 'com.nokia.mce.signal')
        busiface.connect_to_signal('display_status_ind', self.displaystate_change)

        self.bus.add_signal_receiver(self.signal_signal_strength_change, dbus_interface = "Phone.Net", signal_name = "signal_strength_change")
        self.bus.add_signal_receiver(self.signal_cell_info_change, dbus_interface = "Phone.Net", signal_name = "cell_info_change")
        self.bus.add_signal_receiver(self.signal_operator_name_change, dbus_interface = "Phone.Net", signal_name = "operator_name_change")
        #self.bus.add_signal_receiver(self.signal_radio_access_technology_change, dbus_interface = "Phone.Net", signal_name = "radio_access_technology_change")
        self.bus.add_signal_receiver(self.signal_cellular_system_state_change, dbus_interface = "Phone.Net", signal_name = "cellular_system_state_change")

    def fetch_latlong_http(self, query):
        http = HTTP('www.google.com', 80)
        http.putrequest('POST', '/glm/mmap')
        http.putheader('Content-Type', 'application/binary')
        http.putheader('Content-Length', str(len(query)))
        http.endheaders()
        http.send(query)

        code, msg, headers = http.getreply()
        result = http.file.read()
        return result

    def get_location_by_cell(self, cid, lac, mnc=0, mcc=0, country='en'):
        ''' Lookup latitude and longitude using cell info'''
        timeout = 10 # timeout in seconds
        socket.setdefaulttimeout(timeout)
        country = "en"
        device = "Nokia-N900-M5"
        latitude = 0
        longitude = 0
        validData = 'False'
        try:
            b_string = pack('>hqh2sh13sh5sh3sBiiihiiiiii',
                          21, 0,
                          len(country), country,
                          len(device), device,
                          len('1.3.1'), "1.3.1",
                          len('Web'), "Web",
                          27, 0, 0,
                          3, 0, cid, lac,
                          0, 0, 0, 0)
        except:
            message = 'WARNING: Could not construct the http call for fetching the location'
            pass
        else:
            try:
                bytes = self.fetch_latlong_http(b_string)
                (a, b, errorCode, latitude, longitude, c, d, e) = unpack(">hBiiiiih",bytes)
                print 'ErrorCode: ', errorCode
            except:
                message = 'WARNING: Could not get a valid responce from the MMAP API'
                pass
            else:
                latitude = latitude / 1000000.0
                longitude = longitude / 1000000.0
                message = 'INFO: Got the LAT and LON for this cellID.'
                validData = 'True'

        return latitude, longitude, validData, message


    def get_address_by_coordinates(self,latitude,longitude):
        ''' Lookup address info using latitude and longitude '''
        timeout = 10 # timeout in seconds
        socket.setdefaulttimeout(timeout)
        location = "unknown"
        maps_url = "http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + str(latitude) + "," + str(longitude) + "&sensor=false"
        req = urllib2.Request(maps_url)
        try:
            response = urllib2.urlopen(req)
        except:
            showShortMessage("No info from googleapis.com")
        else:
            xml_str = response.read().decode("utf8")
            for line in xml_str.split("\n"):
                if "formatted_address" in line:
                    location=line[line.find(",")+2:line.find("\" ",line.index("</format"))-19]
                    break
        return location


    def get_cell_id_info(self,mcc,mnc,id,lac):
        timeout = 10 # timeout in seconds
        socket.setdefaulttimeout(timeout)
        self.location = "?"
        self.latitude = "?"
        self.longitude = "?"
        if str(id) != "0" and NetWorkAccess:
            # we have CellId info
            cellinf_url = "http://www.opencellid.org/cell/get?key=" + openCellID_apikey + "&mcc=" + str(mcc) + "&mnc=" + str(mnc) + "&cellid=" + str(id) + "&lac=" + str(lac)
            req = urllib2.Request(cellinf_url)
            try:
                response = urllib2.urlopen(req)
            except:
                showShortMessage("opencellid.org: no info or invalid key")
            else:
                xml_str = response.read()
                if "fail" in xml_str:
                    for line in xml_str.split("\n"):
                        if "err info=" in line:
                            err_txt = line[line.find("err info=")+10:line.find("\" ",line.index("err info="))-2]
                    print err_txt
                    if err_txt:
                        showShortMessage(err_txt)
                    else:
                        showShortMessage("cellinfo not found on opencellid.org")
                else:
                    for line in xml_str.split("\n"):
                        if "lat=" in line:
                            self.latitude = line[line.find("lat=")+5:line.find("\" ",line.index("lat="))-2]
                            self.longitude = line[line.find("lon=")+5:line.find("\" ",line.index("lon="))-2]
                    check_location = True
                    float_path = re.compile('^\d*\.\d*$')
                    if re.search(float_path,self.latitude) is None:
                        # illegal latitude
                        check_location = False
                        print "latitude: "+self.latitude
                    if re.search(float_path,self.longitude) is None:
                        # illegal longitude
                        check_location = False
                        print "longitude: "+self.longitude

                    if check_location:
                        maps_url = "http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + self.latitude + "," + self.longitude + "&sensor=false"
                        req = urllib2.Request(maps_url)
                        try:
                            response = urllib2.urlopen(req)
                        except:
                            showShortMessage("No info from googleapis.com")
                        else:
                            xml_str = response.read().decode("utf8")
                            for line in xml_str.split("\n"):
                                if "formatted_address" in line:
                                    self.location=line[line.find(",")+2:line.find("\" ",line.index("</format"))-19]
                                    break
                    else:
                        showShortMessage("Illegal coordinates from opencellid.org")
        elif not NetWorkAccess:
            self.location = "blocked"
            self.latitude = "blocked"
            self.longitude = "blocked"
        if self.longitude == "0.0" or self.latitude == "0.0":
            self.location = "unknown"
            

    def displaystate_change(self, state):
        if (state == "off"):
            self.remove_signals()
        elif (state == "on"):
            self.add_signals()

    def closeEvent(self, event):
        self.remove_signals()

    def remove_signals(self):
        # remove the signal receivers at leaving page
        self.bus.remove_signal_receiver(self.signal_signal_strength_change, dbus_interface = "Phone.Net", signal_name = "signal_strength_change")
        self.bus.remove_signal_receiver(self.signal_cell_info_change, dbus_interface = "Phone.Net", signal_name = "cell_info_change")
        self.bus.remove_signal_receiver(self.signal_operator_name_change, dbus_interface = "Phone.Net", signal_name = "operator_name_change")
    #   self.bus.remove_signal_receiver(self.signal_radio_access_technology_change, dbus_interface = "Phone.Net", signal_name = "radio_access_technology_change")
        self.bus.remove_signal_receiver(self.signal_cellular_system_state_change, dbus_interface = "Phone.Net", signal_name = "cellular_system_state_change")

    def add_signals(self):
        self.bus.add_signal_receiver(self.signal_signal_strength_change, dbus_interface = "Phone.Net", signal_name = "signal_strength_change")
        self.bus.add_signal_receiver(self.signal_cell_info_change, dbus_interface = "Phone.Net", signal_name = "cell_info_change")
        self.bus.add_signal_receiver(self.signal_operator_name_change, dbus_interface = "Phone.Net", signal_name = "operator_name_change")
    #   self.bus.add_signal_receiver(self.signal_radio_access_technology_change, dbus_interface = "Phone.Net", signal_name = "radio_access_technology_change")
        self.bus.add_signal_receiver(self.signal_cellular_system_state_change, dbus_interface = "Phone.Net", signal_name = "cellular_system_state_change")
    
    def signal_signal_strength_change(self, *values):
        if int(values[1]) >= 100 or int(values[1]) == 0:
            dBm_perc = 0
        elif int(values[1]) <= 50:
            dBm_perc = 100
        else:
            dBm_perc = 2 * -(int(values[1]) - 100.0)
        self.SignalTxt.setText(str(int(values[0])) + "%,-" + str(int(values[1])) + " dBm ("+str(int(dBm_perc))+"%)")

    def signal_cell_info_change(self, *values):
        self.LACtxt.setText("LAC <font color="+secColor+">" + str(values[1]))
        self.CIDtxt.setText("CID <font color="+secColor+">" + str(values[2] & 65535))
        self.RNCtxt.setText(str(values[2] >> 16))
        c_mcc = values[4]
        if LatLongProvider == "opencellid" :
            # use opencellid API
            self.get_cell_id_info(values[4],values[3],values[2] & 65535,values[1])
        else:
            # use google API
            if NetWorkAccess:
                self.latitude,self.longitude,validData,message = self.get_location_by_cell(values[2] & 65535, values[1], values[3], values[4])
                if validData == 'True':
                    self.location = self.get_address_by_coordinates(self.latitude,self.longitude)
                else:
                    self.location = "?"
        self.Lattxt.setText("Lat <font color="+secColor+">" + str(self.latitude)[:11] + u"\u00b0")
        self.Longtxt.setText("Long <font color="+secColor+">" + str(self.longitude)[:11] + u"\u00b0")
        self.Loctxt.setText("Loc <font color="+secColor+">" + self.location)
        pattern_code = '[0-9]{1,3} \('
        self.operTXT.setText(re.sub(pattern_code,str(values[3]) + " (",self.operTXT.text()))
        self.countryTXT.setText(re.sub(pattern_code,str(values[4]) + " (",self.countryTXT.text()))
        country_name = ""
        conn = None
        try:
            conn = lite.connect('%s/%s' % (dbPath, dbFile))
            cur = conn.cursor()
            cur.execute('''select country FROM operinfo where mcc = %s ''' %(c_mcc))
            country_name = cur.fetchone()[0]
            cur.close()
        except lite.Error, e:
            print "Error %s" % e.args[0]
        pattern_code = '\(.*\)"'
        self.countryTXT.setText(re.sub(pattern_code, " (" + country_name + ")" ,self.countryTXT.text()))
        dbus_object = self.bus.get_object('com.nokia.phone.net', '/com/nokia/phone/net',False)
        dbus_interface = dbus.Interface(dbus_object, 'Phone.Net')
        radio_technology = dbus_interface.get_selected_radio_access_technology()[0]
        if (radio_technology == 0): technology = "DUAL"
        elif (radio_technology == 1): technology = "GSM"
        elif (radio_technology == 2): technology = "3G"
        else: technology = "?"
        self.selectedTechTXT.setText("Phone mode <font color="+secColor+">" + technology)

    def signal_operator_name_change(self, *values):
        pattern_code = '\(.*\)"'
        self.operTXT.setText(re.sub(pattern_code, " (" + values[1] + ")" ,self.operTXT.text()))

    def signal_cellular_system_state_change(self, *values):
        if (values[0] == 1): used_technology = "GSM"
        elif (values[0] == 2): used_technology = "3G"
        else: used_technology = "?"
        self.usedTechTXT.setText("Used mode <font color="+secColor+">" + used_technology)

    def helpButtonPressed(self):
        widget = helpWindow(self)
        widget.show()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape
            self.wg.resize(780,300)
            self.wg.setMinimumHeight(420)
            self.wg.setMaximumHeight(420)
        else:
            # portrait
            self.wg.resize(470,680)
            self.wg.setMinimumHeight(740)
            self.wg.setMaximumHeight(740)

class helpWindow(QWidget):
    def __init__(self,parent):
        super(helpWindow, self).__init__(parent)
        self.wg = QDialog(self)
        self.wg.resize(398, 692)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.wg.sizePolicy().hasHeightForWidth())
        self.wg.setSizePolicy(sizePolicy)
        self.wg.setWindowTitle("Terms explained")
        self.grid = QGridLayout(self.wg)

        termsInfo = QTextBrowser()
        termsInfo.setMinimumSize(QSize(330, 340))
        termsInfo.setHtml( infoTXT )
        font = QFont()
        font.setPointSize(16)
        termsInfo.setFont(font)
        self.grid.addWidget(termsInfo, 0, 0)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.HelpWindowOpen = False
        self.wg.exec_()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() < screenGeometry.height():
            # portrait
            self.wg.resize(398, 692)

class globalinfoWindow(QMainWindow):
    def __init__(self,parent):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle("Mobile networks")
        global infoTXT
        # layout
        area = QScrollArea()
        lay = QVBoxLayout()
        lay.addWidget(area)
        self.wg = QWidget()
        area.setWidget(self.wg)
        self.setCentralWidget(area)
        grid = QGridLayout(self.wg)
        self.wg.show()
        self.orientationChanged()
        area.show()
        self.setLayout(grid)

        infoTXT = "<html><b><u>MCC</u><br>M</b>obile <b>C</b>ountry <b>C</b>ode<p>" \
        "<b><u>MNC</u><br>M</b>obile <b>N</b>etwork <b>C</b>ode<p>" \
        "The combination of both (also known as a \"MCC / MNC tuple\") is used to uniquely identify " \
        "a mobile phone operator/carrier using the GSM/LTE, CDMA, iDEN, TETRA and UMTS public land " \
        "mobile networks and some satellite mobile networks.<p></html>"

        output = proc.stdout.read()
        output = output.splitlines()
        list_MNC = []
        list_MCC = []
        list_Oper = []
        pattern_code = r'"[0-9]{1,3}"'
        pattern_operator = r'"[a-zA-Z]'
        array_count = 0
        for line in output:
            if "array [" in line:
                array_count += 1
            if array_count == 2:
                # MNC list
                if re.search(pattern_code, line):
                    list_MNC.append(re.findall(r'\d+',line))
            if array_count == 3:
                # MCC list
                if re.search(pattern_code, line):
                    list_MCC.append(re.findall(r'\d+',line))
            if array_count == 4:
                # Operator list
                if re.search(pattern_operator, line):
                    pattern = r'"(.*)"'
                    m = re.search(pattern,line)
                    if m is not None:
                        x= m.group().replace('"','')
                        list_Oper.append(x)

        # layout
        line1 = QFrame()
        line1.setLineWidth(3)
        line1.setMidLineWidth(3)
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)
        MCClabel = QLabel("<center><b>MCC</b></center>")
        MCClabel.setStyleSheet("QLabel { background-color : #0000A0; color : white; }")
        MNClabel = QLabel("<center><b>MNC</b></center>")
        MNClabel.setStyleSheet("QLabel { background-color : #0000A0; color : white; }")
        Operlabel = QLabel("<center><b>Operator</b></center>")
        Operlabel.setStyleSheet("QLabel { background-color : #0000A0; color : white; }")
        grid.addWidget(line1,0,0,1,3)
        grid.addWidget(MCClabel,1,0)
        grid.addWidget(MNClabel,1,1)
        grid.addWidget(Operlabel,1,2)
        line2 = QFrame()
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)
        grid.addWidget(line2,2,0,1,3)
        list_MNC = tuple(list_MNC)
        list_MNC = tuple(tuple(x) for x in list_MNC)
        list_MNC = sum(list_MNC,())
        list_MCC = tuple(list_MCC)
        list_MCC = tuple(tuple(x) for x in list_MCC)
        list_MCC = sum(list_MCC,())
        list_Oper = tuple(list_Oper)

        for index_nr in range (0, len(list_Oper)):
            grid.addWidget(QLabel("<center>"+list_MCC[index_nr]+"</center>"),index_nr+3,0)
            grid.addWidget(QLabel("<center>"+list_MNC[index_nr]+"</center>"),index_nr+3,1)
            grid.addWidget(QLabel("<center>"+list_Oper[index_nr]+"</center>"),index_nr+3,2)
        if 'index_nr' in locals():
            # only show of index_nr exists as variable
            showShortMessage(str(index_nr+1) + " operator(s) found...")
#            os.system('run-standalone.sh dbus-send --type=method_call --dest=org.freedesktop.Notifications  \
#                /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint \
#                string:"' + str(index_nr+1) + ' operator(s) found..."')
        else:
            grid.addWidget(QLabel("<h1> </h1> "),3,0,1,3)
            grid.addWidget(QLabel("<h1><center>no result</center</h1>"),4,0,1,3)
            grid.addWidget(QLabel("<h1> </h1> "),5,0,1,3)
            showShortMessage("No operators found...")

        helpButton = QPushButton("Help",self)
        grid.addWidget(helpButton,20,0,1,3)
        # signals
        self.connect(helpButton, SIGNAL("clicked()"),self.helpButtonPressed)
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)

    def helpButtonPressed(self):
        widget = helpWindow(self)
        widget.exec_()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape
            self.wg.resize(780,300)
            self.wg.setMinimumHeight(420)
            self.wg.setMaximumHeight(420)
        else:
            # portrait
            self.wg.resize(470,680)
            self.wg.setMinimumHeight(740)
            self.wg.setMaximumHeight(740)

class queryWindow(QMainWindow):
    def __init__(self,parent):
        QMainWindow.__init__(self, parent)
        global infoTXT
        self.setWindowTitle("Code info")
        # layout
        area = QScrollArea()
        lay = QVBoxLayout()
        lay.addWidget(area)
        self.wg = QWidget()
        area.setWidget(self.wg)
        self.setCentralWidget(area)
        grid = QGridLayout(self.wg)
        self.wg.show()
        self.orientationChanged()
        area.show()
        self.setLayout(grid)
        self.countryButton = QPushButton("Choose country")
        self.operatorButton = QPushButton("Choose operator")
        self.operatorButton.setEnabled(False)
        helpButton = QPushButton("Help",self)
        findButton = QPushButton("mobile code info")
        line1 = QFrame()
        line1.setLineWidth(3)
        line1.setMidLineWidth(3)
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)
        line2 = QFrame()
        line2.setLineWidth(3)
        line2.setMidLineWidth(3)
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)
        line3 = QFrame()
        line3.setLineWidth(3)
        line3.setMidLineWidth(3)
        line3.setFrameShape(QFrame.HLine)
        line3.setFrameShadow(QFrame.Sunken)
        grid.addWidget(line1,0,0)
        grid.addWidget(QLabel("<center><h2>Country:</h2></center>"),1,0)
        grid.addWidget(self.countryButton,2,0)
        grid.addWidget(QLabel("<center><b> </b></center>"),3,0)
        grid.addWidget(line2,4,0)
        grid.addWidget(QLabel("<center><h2>Operator:</h2></center>"),5,0)
        grid.addWidget(self.operatorButton,6,0)
        grid.addWidget(QLabel("<center><b> </b></center>"),7,0)
        grid.addWidget(line3,8,0)
        grid.addWidget(helpButton,9,0)
        self.setLayout(grid)
        infoTXT = "<html><b><u>MCC</u><br>M</b>obile <b>C</b>ountry <b>C</b>ode<p>" \
        "<b><u>MNC</u><br>M</b>obile <b>N</b>etwork <b>C</b>ode<p>" \
        "The combination of both (also known as a \"MCC / MNC tuple\") is used to uniquely " \
        "identify a mobile phone operator/carrier using the GSM/LTE, CDMA, iDEN, TETRA and " \
        "UMTS public land mobile networks and some satellite mobile networks.<p><html>"
        # signals
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.connect(helpButton, SIGNAL("clicked()"),self.helpButtonPressed)
        self.connect(self.countryButton, SIGNAL("clicked()"),self.countryButtonPressed)
        self.connect(self.operatorButton, SIGNAL("clicked()"),self.operatorButtonPressed)

    def helpButtonPressed(self):
        widget = helpWindow(self)
        widget.show()

    def printMsg(self,message,duration):
        box = QMaemo5InformationBox()
        box.information(self, message, duration)
        box.show()

    def countryButtonPressed(self):
        countryPick = countryPickDialog(self)
        countryPick.show()
        if country_selected:
            self.countryButton.setText(country_selected.replace("~","'"))
            self.operatorButton.setEnabled(True)

    def operatorButtonPressed(self):
        operatorPick = operatorPickDialog(self)
        operatorPick.show()
        if operator_selected:
            self.operatorButton.setText(operator_selected)
            conn = None
            try:
                conn = lite.connect('%s/%s' % (dbPath, dbFile))
                cur = conn.cursor()
                cur.execute('''select country_code FROM operinfo where country = '%s' ''' %(country_selected))
                country_code = cur.fetchone()[0]
                cur.close()
            except lite.Error, e:
                print "Error %s" % e.args[0]
            # show info
            self.printMsg("<br><b>Country:</b> " + country_selected + \
            "<br><b>Country code:</b> " + country_code + \
            "<br><b>MCC:</b> " + str(mcc_selected) + \
            "<br><b>Operator:</b> " + operator_selected + \
            "<br><b>MNC:</b> " + str(mnc_selected) + "<br>",0)

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape
            self.wg.resize(780,300)
            self.wg.setMinimumHeight(420)
            self.wg.setMaximumHeight(420)
        else:
            # portrait
            self.wg.resize(470,680)
            self.wg.setMinimumHeight(740)
            self.wg.setMaximumHeight(740)

class countryPickDialog(QWidget):
    def __init__(self,parent):
        super(countryPickDialog, self).__init__(parent)
        # layout
        self.d = QDialog(self)
        self.d.setMinimumHeight(680)
        self.d.setMaximumHeight(680)
        self.d.setWindowTitle("[Choose country]")
        hbox = QGridLayout()
        horizontalLayout = QGridLayout()
        self.countryWidget = QListWidget()

        conn = None
        try:
            conn = lite.connect('%s/%s' % (dbPath, dbFile))
            cur = conn.cursor()
            cur.execute("SELECT distinct country FROM operinfo ORDER BY country")
            countries = cur.fetchall()
            cur.close()
        except lite.Error, e:
            print "Error %s" % e.args[0]

        # fill country list
        for country in countries:
            item = QListWidgetItem(country[0])
            item.setTextAlignment(Qt.AlignCenter)
            self.countryWidget.addItem(item)

        horizontalLayout.addWidget(self.countryWidget,0,0)
        self.d.setLayout(hbox)
        hbox.addLayout (horizontalLayout,0,0)
        # signals
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.connect(self.countryWidget, SIGNAL("itemClicked(QListWidgetItem *)"), self.itemClicked)
        self.d.exec_()

    def itemClicked(self, item):
        global country_selected
        global mcc_selected
        #country_selected = item.text().replace("'","~")
        country_selected = item.text()
        conn = None
        try:
            conn = lite.connect('%s/%s' % (dbPath, dbFile))
            cur = conn.cursor()
            cur.execute('''select mcc FROM operinfo where country = '%s' ''' %(country_selected))
            mcc_selected = cur.fetchone()[0]
            cur.close()
        except lite.Error, e:
            print "Error %s" % e.args[0]
        self.d.close()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape
            self.d.setMinimumHeight(680)
            self.d.setMaximumHeight(680)
            self.countryWidget.scrollToItem(self.countryWidget.currentItem(),QAbstractItemView.PositionAtTop)
        else:
            # portrait
            self.d.resize(680,740)
            self.d.setMinimumHeight(680)
            self.d.setMaximumHeight(680)
            self.countryWidget.scrollToItem(self.countryWidget.currentItem(),QAbstractItemView.PositionAtCenter)

        
class operatorPickDialog(QWidget):
    def __init__(self,parent):
        super(operatorPickDialog, self).__init__(parent)
        # layout
        global operator_selected
        operator_selected = ""
        self.d = QDialog(self)
        self.d.setMinimumHeight(680)
        self.d.setMaximumHeight(680)
        self.d.setWindowTitle("[Choose operator]")
        hbox = QGridLayout()
        horizontalLayout = QGridLayout()
        self.operatorWidget = QListWidget()

        conn = None
        try:
            conn = lite.connect('%s/%s' % (dbPath, dbFile))
            cur = conn.cursor()
            cur.execute('''select operator FROM operinfo where country = '%s' ''' %(country_selected))
            operators = cur.fetchall()
            cur.close()
        except lite.Error, e:
            print "Error %s" % e.args[0]

        # add operators for coutry
        for operator in operators:
            item = QListWidgetItem(operator[0])
            item.setTextAlignment(Qt.AlignCenter)
            self.operatorWidget.addItem(item)

        horizontalLayout.addWidget(self.operatorWidget,0,0)

        self.d.setLayout(hbox)
        hbox.addLayout (horizontalLayout,0,0)
        # signals
        self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
        self.connect(self.operatorWidget, SIGNAL("itemClicked(QListWidgetItem *)"), self.itemClicked)
        self.d.exec_()

    def itemClicked(self, item):
        global operator_selected
        global mnc_selected
        operator_selected = item.text()
        conn = None
        try:
            conn = lite.connect('%s/%s' % (dbPath, dbFile))
            cur = conn.cursor()
            cur.execute('''select mnc FROM operinfo where country = '%s' and operator  = '%s' ''' %(country_selected,operator_selected))
            mnc_selected = cur.fetchone()[0]
            cur.close()
        except lite.Error, e:
            print "Error %s" % e.args[0]
        self.d.close()

    def orientationChanged(self):
        screenGeometry = QApplication.desktop().screenGeometry()
        if screenGeometry.width() > screenGeometry.height():
            # landscape
            self.d.setMinimumHeight(680)
            self.d.setMaximumHeight(680)
            self.operatorWidget.scrollToItem(self.operatorWidget.currentItem(),QAbstractItemView.PositionAtTop)
        else:
            # portrait
            self.d.resize(680,740)
            self.d.setMinimumHeight(680)
            self.d.setMaximumHeight(680)
            self.operatorWidget.scrollToItem(self.operatorWidget.currentItem(),QAbstractItemView.PositionAtCenter)


if __name__ == '__main__':
    # QApplication controls things relating to a Qt application, like the main loop.
    # You should always instantiate it before using any QtGui related stuff.
    # See also:
    #   http://doc.trolltech.com/4.6/qapplication.html
    app = QApplication(sys.argv)

    # Create an instance (calling __init__, too, of course) of our window subclassing QWidget
    w = MyMainWindow()
    dbus_loop = DBusQtMainLoop()
    dbus.set_default_main_loop(dbus_loop)     

    # Show our window
    w.show()

    # Main event loop of Qt. This won't return until the program exits.

    #mainloop = DBusQtMainLoop(set_as_default=True)
    #dbus.set_default_main_loop(mainloop)
    #loop = DBusQtMainLoop()
    #dbus.set_default_main_loop(loop)
    app.exec_()
    sys.exit()
