#!/usr/bin/python2.5

#################################################################
# geopoi is a software to convert geocaching Pocket Query (gpx) #
# files, loc files and comma separated files                    #
# into sqlite3 database format (db) used by Maemo Mapper,       #
# ov2 format used by TomTom navigators,                         #
# Comma Separated Files (csv) and Nokia Landmark files (lmx)    #
#                                                               #
# Author: E Salli                                               #
# Email: es at saunalahti.fi                                    #
#                                                               #
# License: Gnu General Public License                           #     
#                                                               #
# Copyright 2007-2008 E Salli                                   #
#################################################################

#Set useHildon=1 when using on Nokia Internet Tablet
#Set useHildon=0 when using on Ubuntu (or other conventional Linux distribution)
#if autodetection based on the existence of osso and hildon libraries fails

useHildon=1

print "GeoPoi v. 0.3.1 by E. Salli <es at saunalahti.fi>"

if useHildon==0:
 try:
    import pygtk
    pygtk.require('2.0')
 except:
    print "Import of pygtk failed"
try:
   import gtk
except:
   print "Import of gtk failed"
if useHildon==1:
 try:
   import osso
   import hildon
#   import gobject
 except:
   print "Import of osso or hildon failed. Using without Hildon."
   useHildon=0
   try:
      import pygtk
      pygtk.require('2.0')
   except:
      print "Import of pygtk failed"
try:
   import sqlite3
except:
   print "Import of sqlite3 failed"
try:
   import xml.etree.ElementTree
except:
   print "Import of xml failed"
try:
   import struct
except:
   print "Import of struct failed"
try:
   import csv
except:
   print "Import of csv failed"
try:
   import sys
except:
   print "Import of sys failed"
try:
   import traceback
except:
    print "Import of traceback failed"
try:
   import os
except:
   print "Import of os failed"
try:
   import string
except:
   print "Import of string failed"
try:
   import zipfile
except:
   print "Import of zipfile failed"
try:
   import re
except:
    print "Import of re failed"

#################################################
# Function to print exception/debug information #
#################################################

def formatExceptionInfo(maxTBlevel=5):
         cla, exc, trbk = sys.exc_info()
         excName = cla.__name__
         try:
             excArgs = exc.__dict__["args"]
         except KeyError:
             excArgs = "<no args>"
         excTb = traceback.format_tb(trbk, maxTBlevel)
         return (excName, excArgs, excTb)

###########################################################
#Main class of geopoi application                         #
###########################################################

class GeoPoiApp():

#########################################################
#Initialization defines the user interface              # 
#########################################################

  def __init__(self):
    if useHildon==1:
      self.app = hildon.Program()
    try:
     self.osso_c = osso.Context("geopoi", "0.3.1", False)
    except:
     pass
    if useHildon==1:
      hildon.Program.__init__(self.app)
#      gobject.GObject.__init__(self.app)
    self.sentences = set()
    if useHildon==1:
      self.window = hildon.Window()
    if useHildon==0:
      self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
      self.window.set_size_request(800,480)
      menu=gtk.Menu()
  
    self.window.set_title("GeoPoi 0.3.1")
      
    self.wpts = gtk.ListStore(float, float, str, str, int, int, str, int)
    self.nwpts = 0
    self.showInNameField=0    

    self.window.connect("destroy", gtk.main_quit)

    if useHildon==1:
      self.app.add_window(self.window)
  
    self.label0a = gtk.Label("GeoPoi to convert POIs")
    self.label0b = gtk.Label("es at saunalahti.fi")
    self.label1 = gtk.Label("Waypoints in memory:")
    self.label2 = gtk.Label("0")
    self.label2.set_label(str(self.nwpts))
    self.vbox1=gtk.VBox()
    self.window.add(self.vbox1)
    self.vbox1.show()
    if useHildon==0:
      menu_bar=gtk.MenuBar()
      self.vbox1.pack_start(menu_bar, False, False, 2)
    self.vbox1.add(self.label1)
    self.vbox1.add(self.label2)
    self.vbox1.add(self.label0a)
    self.vbox1.add(self.label0b)
    menu = gtk.Menu()
    if useHildon==1: 
     self.window.set_menu(menu)
    if useHildon==0:
     menu_item=gtk.MenuItem(label=None)
    itemLoadPQ = gtk.MenuItem("Load Pocket Query (gpx[.zip]):lon,lat,name,desc,cat")
    itemLoadPQFolder = gtk.MenuItem("Batch Load PQ Folder (gpx)")
    itemLoadLoc = gtk.MenuItem("Load Loc File (loc[.zip]):lon,lat,name,desc")
    itemLoadLocFolder = gtk.MenuItem("Batch Load Loc Folder (loc)")
    itemLoadCsv = gtk.MenuItem("Load CSV File (csv[.zip]):lon,lat[,name[,desc[,cat]]]")
    itemLoadCsvFolder = gtk.MenuItem("Batch Load CSV Folder (csv)")
    itemSaveDb = gtk.MenuItem("Save sqlite3 Database (db):lon,lat,name,desc,cat")
    itemSaveOv2 = gtk.MenuItem("Save TomTom File (ov2):lon,lat,name")
    itemSaveCsv = gtk.MenuItem("Save CSV File (csv):lon,lat,name,desc,cat")
    itemSaveNLM = gtk.MenuItem("Save Nokia Landmarks File (lmx):lon,lat,name,url,cat")
    itemSaveNLMS = gtk.MenuItem("Save Separate Nokia Landmarks Files (lmx):lon,lat,name,url,cat")

    itemOptionsName = gtk.RadioMenuItem(None, "Show Name only in Name Field")
    itemOptionsNameDiff = gtk.RadioMenuItem(itemOptionsName, "Show Name and Diff in Name Field")    
    itemOptionsName.set_active(1)

    itemClearMem = gtk.MenuItem("Clear Memory")
    itemClose = gtk.MenuItem("Close")
    importMenu=gtk.Menu()
    itemImportSubmenu = gtk.MenuItem("Load")
    itemImportSubmenu.set_submenu(importMenu)

    exportMenu=gtk.Menu()
    itemExportSubmenu = gtk.MenuItem("Save")
    itemExportSubmenu.set_submenu(exportMenu)

    optionsMenu=gtk.Menu()
    itemOptionsSubmenu = gtk.MenuItem("Options")
    itemOptionsSubmenu.set_submenu(optionsMenu)

    importMenu.append(itemLoadPQ)
    importMenu.append(itemLoadPQFolder)
    importMenu.append(itemLoadLoc)
    importMenu.append(itemLoadLocFolder)
    importMenu.append(itemLoadCsv)
    importMenu.append(itemLoadCsvFolder)
    menu.append(itemImportSubmenu)
    
    exportMenu.append(itemSaveDb)
    exportMenu.append(itemSaveOv2)
    exportMenu.append(itemSaveCsv)
    exportMenu.append(itemSaveNLM)
    exportMenu.append(itemSaveNLMS)
    
#    optionsMenu.append(button)
    optionsMenu.append(itemOptionsName)
    optionsMenu.append(itemOptionsNameDiff)

    menu.append(itemExportSubmenu)
    menu.append(itemOptionsSubmenu)
    
    menu.append(itemClearMem)
    menu.append(itemClose)
    itemLoadPQ.connect('activate', self.filePqChooser)
    itemLoadPQFolder.connect('activate', self.folderPqChooser)
    itemLoadLoc.connect('activate', self.fileLocChooser)
    itemLoadLocFolder.connect('activate', self.folderLocChooser)
    itemLoadCsv.connect('activate', self.fileReadCsvChooser)
    itemLoadCsvFolder.connect('activate', self.folderCsvChooser)
    itemSaveDb.connect('activate', self.fileDbChooser)
    itemSaveOv2.connect('activate', self.fileOv2Chooser)
    itemSaveCsv.connect('activate', self.fileWriteCsvChooser)
    itemSaveNLM.connect('activate', self.fileWriteNokiaLandmarksChooser)
    itemSaveNLMS.connect('activate', self.fileWriteSeparateNokiaLandmarksChooser)
    itemClearMem.connect('activate', self.clearMem)
    itemClose.connect('activate', gtk.main_quit)

    itemOptionsName.connect('activate', self.optionsName)
    itemOptionsName.connect('activate', self.optionsNameDiff)

    menu.show_all()
    if useHildon==0:
      root_menu=gtk.MenuItem("File")
      root_menu.show()
      root_menu.set_submenu(menu)
      menu_bar.append(root_menu)
      menu_bar.show()

  def run(self):
    self.window.show_all()
    gtk.main()
    return True


#########################################################
#Clear Memory from Caches                               #
#########################################################

  def clearMem(self,action):
     self.wpts.clear()
     self.nwpts=0
     self.label2.set_label(str(self.nwpts))        


#########################################################
#Options: show only name in name field                  #
#########################################################

  def optionsName(self,action):
     self.showInNameField=0

#########################################################
#Options: show name  and difficulty in name field        #
#########################################################

  def optionsNameDiff(self,action):
     self.showInNameField=1

##############################################
#File chooser for reading Pocket Query files #
##############################################

  def filePqChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_OPEN)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open Gpx File")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
        filename=dialog.get_filename()
        self.processPq(filename)
   except:
    print "Exception error in filePqChooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0


#####################################
#File chooser for reading Csv files #
#####################################

  def fileReadCsvChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_OPEN)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open Csv File")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
        filename=dialog.get_filename()
        self.processCsv(filename)
   except:
    print "Exception error in fileReadCsvChooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

#####################################
#File chooser for reading Loc files #
#####################################

  def processLocXml(self, data):
    try:
        # remove problematic characters
        data = data.replace("\344","")
        gpx = xml.etree.ElementTree.XML(data)
        for point in gpx.findall("waypoint"):
            coord = point.find("coord")
            try:
              lat = float(coord.attrib['lat'])
              lon = float(coord.attrib['lon'])
            except:
              lat = 0.0
              lon = 0.0
            nameg = point.find("name")
            name = nameg.text
            link = point.find("link").text
            desc = ""
            url2=link
            category = 20 # Default category Others
            if name is None: name = ''
            self.wpts.prepend((lat,lon,name,name,0,0,url2,category))
            self.nwpts=self.nwpts+1
        self.label2.set_label(str(self.nwpts))
                
    except:
        print "Exception error in processLocXml"
        print formatExceptionInfo()

##############################
# Processing of (zipped) LOC #
##############################

  def processLoc(self, filename):
    print "Processing:"+filename
    try:
        data=""
        if zipfile.is_zipfile(filename):
          # if zip file
          print "processing as zipfile"
          file=zipfile.ZipFile(filename,"r")
          for info in file.infolist():
           fname = info.filename
           data = file.read(fname)
           self.processLocXml(data)
        else:
         # if not zip file
         fin = open(filename,"r")
         data = fin.read()
         fin.close()
         self.processLocXml(data)
    except:
        print "Exception error in processLoc"
        print formatExceptionInfo()


###################################
# Processing of (zipped) Pq files #
###################################

  def processPq(self, filename):
    print "Processing:"+filename
    try:
        data=""
        if zipfile.is_zipfile(filename):
          # zipped
          print "processing as zipfile"
          file=zipfile.ZipFile(filename,"r")
          for info in file.infolist():
           fname = info.filename
           data = file.read(fname)
           self.processPqXml(data)
        else:
         #not zipped
         fin = open(filename,"r")
         data = fin.read()
         fin.close()
         self.processPqXml(data)
    except:
        print "Exception error in processPq"
        print formatExceptionInfo()


####################################
# Processing of (zipped) Csv files #
####################################

  def processCsv(self, filename):
    print "Processing:"+filename
    try:
        data=""
        if zipfile.is_zipfile(filename):
          # zipped
          print "processing as zipfile"
          file=zipfile.ZipFile(filename,"r")
          for info in file.infolist():
           fname = info.filename
           data = file.read(fname)
           self.processCsvData(data)
        else:
         #not zipped
         fin = open(filename,"r")
         data = fin.read()
         fin.close()
         self.processCsvData(data)
    except:
        print "Exception error in processCsv"
        print formatExceptionInfo()

 ########################################
 # Processing of Pocket Query GPX files #
 ########################################

  def processPqXml(self, data):
    try:
        #remove problematic characters
        data = data.replace("\344","")

        gpx = xml.etree.ElementTree.XML(data)
        for point in gpx.findall('.//{http://www.topografix.com/GPX/1/0}wpt'):
            try:
              lat, lon = float(point.attrib['lat'].replace(',', '.')), float(point.attrib['lon'].replace(',', '.'))
            except:
              lat = 0.0
              lon = 0.0
            name = point.find("{http://www.topografix.com/GPX/1/0}urlname").text
            desc = point.find("{http://www.topografix.com/GPX/1/0}desc").text
	    url = point.find("{http://www.topografix.com/GPX/1/0}url").text
            wpcode = point.find("{http://www.topografix.com/GPX/1/0}name").text
	    url2 = "http://www.geocaching.com/seek/cache_details.aspx?wp=" + wpcode
	    category = 20 # Default category Others
            cache=point.find("{http://www.groundspeak.com/cache/1/0}cache")
            try:
              container=cache.find("{http://www.groundspeak.com/cache/1/0}container").text
            except:
              container=""
            try:
              difficulty = int(float(cache.find("{http://www.groundspeak.com/cache/1/0}difficulty").text)*2.0)
              terrain = int(float(cache.find("{http://www.groundspeak.com/cache/1/0}terrain").text)*2.0)
            except:
              difficulty=0
              terrain=0
            categoryname = point.find("{http://www.topografix.com/GPX/1/0}type").text.replace('Geocache|','')
            if categoryname=="Traditional Cache": category=12
            elif categoryname=="Multi-cache": category=13
            elif categoryname=="Unknown Cache": category=14
            elif categoryname=="Letterbox Hybrid": category=15
            elif categoryname=="Webcam Cache": category=16
            elif categoryname=="Virtual Cache": category=17
            elif categoryname=="Earthcache": category=18
            elif categoryname=="Event Cache": category=19
            if name is None: name = ''
            self.wpts.prepend((lat,lon,name,desc+' '+container,difficulty,terrain,url2,category))
            self.nwpts=self.nwpts+1
        self.label2.set_label(str(self.nwpts))        
    except:
      print "Exception error in processPqXml"
      print formatExceptionInfo()
    self.FileChooserDialogActive=0

#################################
#Folder chooser for reading Loc #
#################################

  def folderLocChooser(self, action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open Loc Folder")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
        foldername=dialog.get_filename()
        print foldername
        dirList=os.listdir(foldername)
        for fname in dirList:
            filename = foldername + "/" + fname
            print filename
            self.processLoc(filename)
   except:
    print "Exception error in folderLocChooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

#############################################
# Folder chooser for reading Pocket Queries #
#############################################

  def folderPqChooser(self, action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open PQ Folder")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
        foldername=dialog.get_filename()
        dirList=os.listdir(foldername)
        for fname in dirList:
            filename = foldername + "/" + fname
            print filename
            self.processPq(filename)
    self.FileChooserDialogActive=0
   except:
    print "Exception error in folderPqChooser"
    self.FileChooserDialogActive=0


##################################
# Folder chooser for reading Csv #
##################################

  def folderCsvChooser(self, action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open CSV Folder")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
        foldername=dialog.get_filename()
        dirList=os.listdir(foldername)
        for fname in dirList:
            filename = foldername + "/" + fname
            print filename
            self.processCsv(filename)
   except:
    print "Exception error in folderPqChooser"
   self.FileChooserDialogActive=0


#####################################
#File chooser for reading Loc files #
#####################################

  def fileLocChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_OPEN)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open Loc File")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
        filename=dialog.get_filename()
        self.processLoc(filename)
   except:
    print "Exception error in fileLocChooser"
   self.FileChooserDialogActive=0


################################
# File chooser for reading Csv #
################################

  def fileCsvChooserRead(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
       dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_OPEN)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.set_title("Open Csv File")
    dialog.set_default_response(gtk.RESPONSE_OK)
    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
      filename=dialog.get_filename()
      sniffer = csv.Sniffer()
      file=open(filename,'rb')
      d = sniffer.sniff(file.readline())
      file.seek(0)
      reader=csv.reader(file,d)
      for row in reader:
            lr=len(row)
            lat=0.0
            lon=0.0
            name= ''
            desc= ''
            category = 21
            if lr>1:
              try:
                lat = float(row[0])
                lon = float(row[1])
              except:
                lat = 0.0
                lon = 0.0
            if lr>2:
              name = row[2]
            if lr>3:
              desc = row[3]
            if lr>4:
              try:
                category = int(row[4])
              except:
                category = 21
            if lr>1:
              self.wpts.prepend((lat,lon,name,desc,"",0,0,category))
              self.nwpts=self.nwpts+1
      file.close()
    self.label2.set_label(str(self.nwpts))        
   except:
    print "Exception error in fileCsvChooserRead"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

###########################
# Processing of Csv files #
###########################

  def processCsvData(self,data):
   try:
    if 0==0:
      sniffer = csv.Sniffer()
      splitteddata=data.split("\n")
      d = sniffer.sniff(splitteddata[0])
      reader=csv.reader(splitteddata,d)
      for row in reader:     
            lr=len(row)
            lat=0.0
            lon=0.0
            name= ''
            desc= ''
            category = 21
            if lr>1:
              try:
                lat = float(row[0])
                lon = float(row[1])
              except:
                lat = 0.0
                lon = 0.0
            if lr>2:
              name = row[2]
            if lr>3:
              desc = row[3]
            if lr>4:
              try:
                category = int(row[4])
              except:
                category = 21
            if lr>1:
              self.wpts.prepend((lat,lon,name,desc,"",0,0,category))
              self.nwpts=self.nwpts+1
    self.label2.set_label(str(self.nwpts))        
   except:
    print "Exception error in pricessCsvData"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

############################################
# File chooser for saving sqlite3 db files #
############################################

  def fileDbChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.show_all ()

    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
      filename=dialog.get_filename()
      print "filename"
      print filename
      conn = sqlite3.connect(filename)
      c = conn.cursor()
      c.execute('''create table if not exists category (cat_id integer PRIMARY KEY, label text, desc text, enabled integer)''')
      c.execute("""insert or ignore into category values (12, 'Traditional', 'Traditional Caches', 1)""")
      c.execute("""insert or ignore into category values (13, 'Multi', 'Multi-caches', 1)""")
      c.execute("""insert or ignore into category values (14, 'Unknown', 'Unknown Caches', 1)""")
      c.execute("""insert or ignore into category values (15, 'Letterbox', 'Letterbox Hybrids', 1)""")
      c.execute("""insert or ignore into category values (16, 'Webcam', 'Webcam Caches', 1)""")
      c.execute("""insert or ignore into category values (17, 'Virtual', 'Virtual Caches', 1)""")
      c.execute("""insert or ignore into category values (18, 'Earth', 'Earthcaches', 1)""")
      c.execute("""insert or ignore into category values (19, 'Event', 'Event Caches', 1)""")
      c.execute("""insert or ignore into category values (20, 'Other Caches', 'Other Caches or not specified', 1)""")
      c.execute("""insert or ignore into category values (21, 'CSV Pois', 'Pois from CSV files', 1)""")
      c.execute('''create table if not exists poi (poi_id integer PRIMARY KEY, lat real, lon real, label text, desc text, cat_id integer)''')
      counter=0
      for n in self.wpts:
        err=1
        lat = n[0]
        lon = n[1]
        name = n[2]
        desc = n[3]
        difficulty = n[4]
        terrain = n[5]
        url = n[6]
        category = n[7]
        while err==1:
          err=0
          counter=counter+1
          try:
            namefield=""
            if self.showInNameField==0:
              namefield=name[0:20]
            if self.showInNameField==1:
              namefield=name[0:17]+" "+str(difficulty)+str(terrain)
            c.execute('insert into poi values (?,?,?,?,?,?)',(counter, lat, lon, namefield, desc+" "+url, category))
          except sqlite3.Error,e:
            print "sqlite3 exception error in fileDbChooser:",e.args[0]
            err=1
          except: 
            print "exception error in fileDbChooser"
            print formatExceptionInfo()
      self.FileChooserDialogActive=0
      conn.commit()
      conn.close()
   except sqlite3.Error,e:
    print "sqlite3 exception error in fileDbChooser:",e.args[0]
    self.FileChooserDialogActive=0
   except:
    print "Exception error in fileDbChooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

#####################################
# File chooser for saving ov2 files #
#####################################

  def fileOv2Chooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.show_all ()

    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
      filename=dialog.get_filename()
      print "filename"
      print filename
      ov2file=open(filename,'wb')
      counter=0
      for n in self.wpts:
        lat = n[0]
        lon = n[1]
        name = n[2]
        desc = n[3]
        url = n[6]
        category = n[7]
        leng=1+len(name)
        siz=13+leng
        data=struct.pack('<BIii',2,siz, int(lon*1E5),int(lat*1E5))
        format = '%ds' % leng
        data += struct.pack(format,name)
        ov2file.write(data)
      ov2file.close()
   except:
    print "Exception error in fileOv2Chooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

####################################
# File chooser for saving Pq files #
####################################

  def fileWriteCsvChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.show_all ()

    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
      filename=dialog.get_filename()
      print "filename"
      print filename
      file=open(filename,'wb')
      writer=csv.writer(file)
      counter=0
      for n in self.wpts:
        lat = n[0]
        lon = n[1]
        name = n[2]
        desc = n[3]
        url = n[6]
# remove problematic characters
        name = name.replace("\"","")
        desc = desc.replace("\"","")
        category = n[7]
        if name=='':
          name='NA'
        if desc=='':
          desc='NA'
        item=(lat,lon,name,desc,category)
        writer.writerow(item)
      file.close()
   except:
    print "Exception error in fileWriteCsvChooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0


#################################################
# Fille chooser for saving Nokia Landmarks file #
#################################################

  def fileWriteNokiaLandmarksChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.show_all ()

    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
      filename=dialog.get_filename()
      print "filename"
      print filename
      fout=open(filename,'wb')
      fout.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
      fout.write("<lm:lmx xmlns:lm=\"http://www.nokia.com/schemas/location/landmarks/1/0\"\n")
      fout.write("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n")
      fout.write("xsi:schemaLocation=\"http://www.nokia.com/schemas/location/landmarks/1/0 lmx.xsd\">\n")
      fout.write("<lm:landmarkCollection>\n")

      for n in self.wpts:
        lat = n[0]
        lon = n[1]
        name = n[2]
        desc = n[3]
# remove problematic characters
        name = name.replace("&","&amp;")
        name = name.replace("<","&lt;")
        name = name.replace(">","&gt;")
        desc = desc.replace("&","&amp;")
        desc = desc.replace("<","&lt;")
        desc = desc.replace(">","&gt;")
        url = n[6]
        category = n[7]
        categoryName="CSV Pois"
        if category==12: categoryName="Traditional Cache"
        elif category==13: categoryName="Multi-cache"
        elif category==14: categoryName="Unknown Cache"
        elif category==15: categoryName="Letterbox Hybrid"
        elif category==16: categoryName="Webcam Cache"
        elif category==17: categoryName="Virtual Cache"
        elif category==18: categoryName="Earthcache"
        elif category==19: categoryName="Event Cache"
        elif category==20: categoryName="Other Caches"
       
        if name=='':
          name='NA'
        if desc=='':
          desc='NA'
        fout.write("<lm:landmark>\n")
        fout.write("<lm:name>"+name+"</lm:name>\n")
        fout.write("<lm:coordinates>\n")
        fout.write("<lm:latitude>"+str(lat)+"</lm:latitude>\n")
        fout.write("<lm:longitude>"+str(lon)+"</lm:longitude>\n")
        fout.write("</lm:coordinates>\n")
        fout.write("<lm:mediaLink>\n")
        fout.write("<lm:url>"+url+"</lm:url>\n")
        fout.write("</lm:mediaLink>\n")
        fout.write("<lm:category>\n")
        fout.write("<lm:name>"+categoryName+"</lm:name>\n")
        fout.write("</lm:category>\n")
        fout.write("</lm:landmark>\n")
      fout.write("</lm:landmarkCollection>\n")
      fout.write("</lm:lmx>\n")
      fout.close()
   except:
    print "Exception error in  fileWriteNokiaLandmarksChoose"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0

##########################################################
# Fille chooser for saving separate Nokia Landmarks file #
##########################################################

  def fileWriteSeparateNokiaLandmarksChooser(self,action):
   try:
    self.FileChooserDialogActive=1
    if useHildon==1:
     dialog = hildon.FileChooserDialog (self.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
    if useHildon==0:
     dialog = gtk.FileSelection ()
    dialog.show_all ()

    r = dialog.run()
    dialog.hide()
    if r==gtk.RESPONSE_OK:
      filename=dialog.get_filename()
      print "filename"
      print filename
      for n in self.wpts:
        lat = n[0]
        lon = n[1]
        name = n[2]
        desc = n[3]
        fname= re.sub(r"[^A-Za-z0-9]", "", name) 
        fname= fname.lower()
        dirname=filename + "/" + fname[0]
        if os.path.isdir(dirname):
           pass
        else: 
           os.mkdir(dirname);
        filename2=dirname + "/" + fname
        print filename2
        fout=open(filename2,'wb')
        fout.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
        fout.write("<lm:lmx xmlns:lm=\"http://www.nokia.com/schemas/location/landmarks/1/0\"\n")
        fout.write("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n")
        fout.write("xsi:schemaLocation=\"http://www.nokia.com/schemas/location/landmarks/1/0 lmx.xsd\">\n")
        fout.write("<lm:landmarkCollection>\n")
# remove problematic characters
        name = name.replace("&","&amp;")
        name = name.replace("<","&lt;")
        name = name.replace(">","&gt;")
        desc = desc.replace("&","&amp;")
        desc = desc.replace("<","&lt;")
        desc = desc.replace(">","&gt;")
        url = n[6]
        category = n[7]
        categoryName="CSV Pois"
        if category==12: categoryName="Traditional Cache"
        elif category==13: categoryName="Multi-cache"
        elif category==14: categoryName="Unknown Cache"
        elif category==15: categoryName="Letterbox Hybrid"
        elif category==16: categoryName="Webcam Cache"
        elif category==17: categoryName="Virtual Cache"
        elif category==18: categoryName="Earthcache"
        elif category==19: categoryName="Event Cache"
        elif category==20: categoryName="Other Caches"
        if name=='':
          name='NA'
        if desc=='':
          desc='NA'
        fout.write("<lm:landmark>\n")
        fout.write("<lm:name>"+name+"</lm:name>\n")
        fout.write("<lm:coordinates>\n")
        fout.write("<lm:latitude>"+str(lat)+"</lm:latitude>\n")
        fout.write("<lm:longitude>"+str(lon)+"</lm:longitude>\n")
        fout.write("</lm:coordinates>\n")
        fout.write("<lm:mediaLink>\n")
        fout.write("<lm:url>"+url+"</lm:url>\n")
        fout.write("</lm:mediaLink>\n")
        fout.write("<lm:category>\n")
        fout.write("<lm:name>"+categoryName+"</lm:name>\n")
        fout.write("</lm:category>\n")
        fout.write("</lm:landmark>\n")
        fout.write("</lm:landmarkCollection>\n")
        fout.write("</lm:lmx>\n")
        fout.close()
   except:
    print "Exception error in fileWriteSeparateNokiaLandmarksChooser"
    print formatExceptionInfo()
   self.FileChooserDialogActive=0
app = GeoPoiApp()
app.run()

