#!/usr/bin/env python
#PPD to XML translator/generator
#Written by David Crosby
version='0.21'

import sys
import os
import time
import datetime
import pygtk
pygtk.require('2.0')
import gtk
from xml.dom import minidom

class PPDtoXML:
    __manufacturerlist__=[
    'Alps', 
    'Anitech', 
    'Apollo', 
    'Apple', 
    'Avery', 
    'Benq', 
    'Brother', 
    'Cltoh', 
    'CalComp',
    'Canon', 
    'Casio', 
    'Citizen', 
    'Compaq', 
    'DEC', 
    'Dell', 
    'Dymo', 
    'Dymo-CoStar', 
    'Epson', 
    'Extech', 
    'FenixImvico', 
    'FujiXerox', 
    'Fujifilm', 
    'Fujitsu', 
    'GCCPrinters', 
    'Gestetner', 
    'Heidelberg', 
    'Hitachi', 
    'HP', 
    'IBM', 
    'Imagen',
    'Imagistics',
    'InfoPrint',
    'Infotec', 
    'Kodak',
    'KONICA MINOLTA', 
    'Kyocera', 
    'Lanier', 
    'LaserMaster', 
    'Lexmark', 
    'Minolta', 
    'Minolta QMS', 
    'Mitsubishi', 
    'NEC', 
    'NRG', 
    'Oce', 
    'Oki',
    'Olivetti', 
    'Olympus', 
    'Panasonic', 
    'PCPI', 
    'Pentax', 
    'Printrex', 
    'QMS', 
    'Raven', 
    'Ricoh', 
    'RisoKagaku', 
    'Samsung', 
    'Savin', 
    'Seiko', 
    'Sharp',
    'SiPix', 
    'Siemens', 
    'Sony', 
    'Star', 
    'Tally', 
    'Tektronix',
    'Texas Instruments',
    'TohokuRicoh', 
    'Toshiba',
    'Xante'
    'Xerox']

    __driverlist__=[
    'ap3250', 
    'appledmp', 
    'bj10', 
    'bj10e', 
    'bj10v', 
    'bj10vh', 
    'bj200', 
    'bj8gc12f.upp', 
    'bj8hg12f.upp', 
    'bj8oh06n.upp', 
    'bj8pa06n.upp', 
    'bj8pp12f.upp', 
    'bj8ts06n.upp', 
    'bjc250gs', 
    'bjc600', 
    'bjc6000a1.upp', 
    'bjc6000b1.upp', 
    'bjc610a0.upp', 
    'bjc610a1.upp', 
    'bjc610a2.upp', 
    'bjc610a3.upp', 
    'bjc610a4.upp', 
    'bjc610a5.upp', 
    'bjc610a6.upp', 
    'bjc610a7.upp', 
    'bjc610a8.upp', 
    'bjc610b1.upp', 
    'bjc610b2.upp', 
    'bjc610b3.upp', 
    'bjc610b4.upp', 
    'bjc610b6.upp', 
    'bjc610b7.upp', 
    'bjc610b8.upp', 
    'bjc800', 
    'bjc800j', 
    'bjc880j', 
    'c2050', 
    'c2070', 
    'cZ11', 
    'cZ11somsom', 
    'capt', 
    'cdj1600', 
    'cdj500', 
    'cdj550', 
    'cdj550.upp', 
    'cdj670', 
    'cdj850', 
    'cdj880', 
    'cdj890', 
    'cdj970', 
    'chp2200', 
    'cjet', 
    'cljet5', 
    'cljet5c', 
    'cp50', 
    'declj250', 
    'deskjet', 
    'dj505j', 
    'djet500', 
    'dnj650c', 
    'drv_x125', 
    'drv_z42', 
    'eplaser', 
    'ep-laser', 
    'eps9high', 
    'eps9mid', 
    'epson', 
    'epsonc', 
    'epsonepl', 
    'escpage', 
    'fmlbp', 
    'fmpr', 
    'foo2hp', 
    'foo2kyo', 
    'foo2lava', 
    'foo2qpdl', 
    'foo2xqx', 
    'foo2zjs', 
    'gdi', 
    'gimp-print', 
    'gutenprint', 
    'gutenprint52', 
    'hl1250', 
    'hl7x0', 
    'hpdj', 
    'hpijs-pcl3', 
    'hpijs-pcl5c',
    'hpijs-pcl5e',
    'hplip',
    'ibmpro', 
    'imagen', 
    'iwhi', 
    'iwlo', 
    'iwlq', 
    'jetp3852', 
    'jj100', 
    'la50', 
    'la70', 
    'la75', 
    'la75plus', 
    'laserjet', 
    'lbp310', 
    'lbp320', 
    'lbp660', 
    'lbp8', 
    'lex5700', 
    'lex7000', 
    'lips2p', 
    'lips3', 
    'lips4', 
    'lips4v', 
    'lj250', 
    'lj4dith', 
    'lj4dithp', 
    'lj5gray', 
    'lj5mono', 
    'ljet2p', 
    'ljet3', 
    'ljet3d', 
    'ljet4', 
    'ljet4d', 
    'ljetplus', 
    'lm1100', 
    'ln03', 
    'lp2000', 
    'lp2563', 
    'lp8000', 
    'lpstyl', 
    'lq850', 
    'lx5000', 
    'lxm3200', 
    'lxm3200-tweaked', 
    'lxm3200x', 
    'lxm3200m', 
    'lxm3200p', 
    'lxm5700m', 
    'lxx74', 
    'lz11-V2', 
    'm2300w', 
    'm2400w', 
    'm8510', 
    'mdx1Mono', 
    'md2k', 
    'md50Eco', 
    'md50Mono', 
    'md5k', 
    'min12xxw', 
    'mj500c', 
    'mj6000c', 
    'mj700v2c', 
    'mj8000c', 
    'ml600', 
    'ml85p', 
    'necp2x.upp', 
    'necp2x6.upp', 
    'necp6', 
    'npdl', 
    'nwp533', 
    'oce9050', 
    'oki182', 
    'oki4drv', 
    'oki4w', 
    'okiibm', 
    'omni', 
    'paintjet', 
    'pbm2l2030', 
    'pbm2l7k', 
    'pbm2lwxl', 
    'pbm2ppa', 
    'pbmtozjs', 
    'pcl3', 
    'pegg', 
    'pentaxpj', 
    'picty180', 
    'pj', 
    'pjetxl', 
    'pjxl', 
    'pjxl300', 
    'PM760p.upp', 
    'PM760pl.upp', 
    'PM820p.upp', 
    'PM820pl.upp', 
    'pnm2ppa', 
    'Postscript',
    'Postscript-Brother',
    'Postscript-Epson',
    'Postscript-Gestetner',
    'Postscript-HP',
    'Postscript-InfoPrint',
    'Postscript-Infotec',
    'Postscript-KONICA_MINOLTA',
    'Postscript-Kyocera',
    'Postscript-Lanier',
    'Postscript-NRG',
    'Postscript-Oce',
    'Postscript-Oki',
    'Postscript-Ricoh',
    'Postscript-Savin',
    'Postscript-Sharp',
    'Postscript-Toshiba',
    'Postscript1',
    'Postscript2-Oce',
    'ppmtocpva', 
    'ppmtomd', 
    'pr150', 
    'pr201', 
    'ptouch', 
    'pxl1010', 
    'pxlcolor',
    'pxlcolor-Gestetner',
    'pxlcolor-InfoPrint',
    'pxlcolor-Infotex',
    'pxlcolor-Lanier',
    'pxlcolor-NRG',
    'pxlcolor-Ricoh',
    'pxlcolor-Savin',
    'pxldpl',
    'pxljr', 
    'pxlmono',
    'pxlmono-Gestetner',
    'pxlmono-InfoPrint',
    'pxlmono-Infotex',
    'pxlmono-Lanier',
    'pxlmono-NRG',
    'pxlmono-Ricoh',
    'pxlmono-Savin',
    'r4081', 
    'ras1.upp', 
    'ras24.upp', 
    'ras3.upp', 
    'ras32.upp', 
    'ras4.upp', 
    'ras8m.upp', 
    'rastertokmXXXXdl', 
    'rpdl', 
    's400a1.upp', 
    's400b1.upp', 
    'sharp.upp', 
    'sipixa6.upp', 
    'slap',
    'sparc',
    'splix', 
    'st640ih.upp', 
    'st640igh.upp', 
    'st640p.upp', 
    'st640pg.upp', 
    'st640pl.upp', 
    'st640plg.upp', 
    'st800', 
    'stc.upp', 
    'stc1520h.upp', 
    'stc2.upp', 
    'stc2_h.upp', 
    'stc2s_h.upp', 
    'stc300.upp', 
    'stc300bl.upp', 
    'stc300bm.upp', 
    'stc500p.upp', 
    'stc500ph.upp', 
    'stc600ih.upp', 
    'stc600p.upp', 
    'stc600pl.upp', 
    'stc640p.upp', 
    'Stc670p.upp', 
    'Stc670pl.upp', 
    'Stc680p.upp', 
    'Stc680pl.upp', 
    'stc740ih.upp', 
    'stc740p.upp', 
    'stc740il.upp', 
    'Stc760p.upp', 
    'Stc760pl.upp', 
    'Stc777p.upp', 
    'Stc777pl.upp', 
    'stc800ih.upp', 
    'stc800p.upp', 
    'stc800pl.upp', 
    'stc_h.upp', 
    'stc_l.upp', 
    'stcany.upp', 
    'stcolor', 
    'Stp720p.upp', 
    'Stp720pl.upp', 
    'Stp870p.upp', 
    'Stp870pl.upp', 
    't4693d2', 
    't4693d4', 
    't4693d8', 
    'tek4696', 
    'xes']

    __mechanismlist__=[
    'Mechanism',
    'laser',
    'inkjet',
    'led',
    'dotmatrix',
    'impact',
    'sublimation',
    'transfer']

    def __init__(self):

        window = gtk.Window()
        window.connect('destroy', lambda w: gtk.main_quit())

        vbox = gtk.VBox()
        vbox.show()       
  
        make_label = gtk.Label('Make')
        vbox.pack_start(make_label)
        make_label.show()


   #This is for the make and model of the printer
        p_make = gtk.Entry()
        p_make.set_text('Make')
        p_make_dropdown = gtk.EntryCompletion()
        self.makelist = gtk.ListStore(str)
        for manufacturer in self.__manufacturerlist__:
            self.makelist.append([manufacturer])
        p_make_dropdown.set_model(self.makelist)
        p_make.set_completion(p_make_dropdown)
        p_make_dropdown.set_text_column(0)
        vbox.pack_start(p_make)
        window.add(vbox)
        p_make.show()

        model_label = gtk.Label('Model')
        vbox.pack_start(model_label)
        model_label.show()

        p_model = gtk.Entry()
        p_model.set_text('Model')
        vbox.pack_start(p_model)
        p_model.show()

     #This is for selecting the printer mechanism
        p_mechanism_combo = gtk.combo_box_new_text()
        for mechanism in self.__mechanismlist__:
            p_mechanism_combo.append_text(mechanism)
        p_mechanism_combo.set_active(0)
        vbox.pack_start(p_mechanism_combo)
        p_mechanism_combo.show()

        hbox_dpi = gtk.HBox()
        vbox.add(hbox_dpi)
        hbox_dpi.show()

    #Select whether the printer is color or not
        p_color = gtk.CheckButton("Color")
        hbox_dpi.pack_start(p_color)
        p_color.show()

        separator1 = gtk.HSeparator()
        hbox_dpi.pack_start(separator1)
        separator1.show()

    #Select the DPI of the printer
        x_dpi_label = gtk.Label('X:')
        hbox_dpi.pack_start(x_dpi_label)
        x_dpi_label.show()

        p_x_dpi = gtk.Entry()
        p_x_dpi.set_width_chars(6)
        hbox_dpi.pack_start(p_x_dpi)
        p_x_dpi.show()

        y_dpi_label = gtk.Label('Y:')
        hbox_dpi.pack_start(y_dpi_label)
        y_dpi_label.show()

        p_y_dpi = gtk.Entry()
        p_y_dpi.set_width_chars(6)
        hbox_dpi.pack_start(p_y_dpi)
        p_y_dpi.show()

    #Text box to enter what consumables are used in the printer (toner/drum/cartridge/blahblahblah)
        consumables_label = gtk.Label('Consumables')
        vbox.pack_start(consumables_label)
        #consumables_label.show()

        p_consumables = gtk.Entry()
        vbox.pack_start(p_consumables)
        #p_consumables.show()

    #The manufacturer URL for the printer
        url_label = gtk.Label('Manufacturer URL')
        vbox.pack_start(url_label)
        url_label.show()

        p_url = gtk.Entry()
        vbox.pack_start(p_url)
        p_url.show()
    
    #LANGUAGES
        hbox_languages = gtk.HBox()
        vbox.add(hbox_languages)
        hbox_languages.show()

    #This part is for determining the printer's PS ability
        p_is_postscript = gtk.CheckButton("Postscript?")
        hbox_languages.pack_start(p_is_postscript)
        p_is_postscript.show()

        p_postscript_level = gtk.Entry()
        p_postscript_level.set_max_length(1)
        p_postscript_level.set_width_chars(1)
        hbox_languages.pack_start(p_postscript_level)

        p_postscript_url = gtk.Entry()
        hbox_languages.pack_start(p_postscript_url)

        ps_ppd_location_button = gtk.Button('Find/Grok:')
        hbox_languages.pack_start(ps_ppd_location_button)
        #ps_ppd_location_button.connect('clicked', self.grok_ppd_file_def, p_make, p_model, p_color, p_is_postscript, p_postscript_level, p_pjl, p_throughput)
        p_is_postscript.connect("toggled", self.postscript_select, p_postscript_level, p_postscript_url, ps_ppd_location_button)

     #This is for determining the printer's PCL ability
        p_is_pcl = gtk.CheckButton("PCL?")
        hbox_languages.pack_start(p_is_pcl)
        p_is_pcl.show()

        p_pcl_level = gtk.Entry()
        p_pcl_level.set_max_length(3)
        p_pcl_level.set_width_chars(3)
        hbox_languages.pack_start(p_pcl_level)

        p_is_pcl.connect("toggled", self.pcl_select, p_pcl_level)

     #For the <tiff> tag
        p_tiff = gtk.CheckButton("TIFF")
        hbox_languages.pack_start(p_tiff)
        p_tiff.show()

     #For the <escp> tag
        p_escp = gtk.CheckButton("ESCP")
        hbox_languages.pack_start(p_escp)
        p_escp.show()

     #For the <hpgl2> tag
        p_hpgl2 = gtk.CheckButton("HPGL/2")
        hbox_languages.pack_start(p_hpgl2)
        p_hpgl2.show()

     #For the <proprietary> tag
        p_proprietary = gtk.CheckButton("Proprietary")
        hbox_languages.pack_start(p_proprietary)
        p_proprietary.show()

        lang_sep = gtk.VSeparator()
        hbox_languages.pack_start(lang_sep)
        lang_sep.show()

      #Print Job Language support
        p_pjl = gtk.CheckButton("PJL")
        hbox_languages.pack_start(p_pjl)
        p_pjl.show()

      #ASCII printing
        p_charset = gtk.CheckButton("US-ASCII")
        hbox_languages.pack_start(p_charset)
        p_charset.show()

    #AUTODETECTION
        autodetect_label = gtk.Label("Autodetection")
        vbox.pack_start(autodetect_label)
        autodetect_label.show()

        hbox_autodetect = gtk.HBox()
        vbox.add(hbox_autodetect)
        hbox_autodetect.show()

      #USB AUTODETECTION
        vbox_autodetect_usb = gtk.VBox()
        hbox_autodetect.add(vbox_autodetect_usb)
        vbox_autodetect_usb.show()
        p_autodetect_usb = gtk.CheckButton("USB?") 
        vbox_autodetect_usb.pack_start(p_autodetect_usb)
        p_autodetect_usb.show()
        usb_ieee1284 = gtk.Entry()
        vbox_autodetect_usb.pack_start(usb_ieee1284)
        usb_manufacturer = gtk.Entry()
        vbox_autodetect_usb.pack_start(usb_manufacturer)
        usb_model = gtk.Entry()
        vbox_autodetect_usb.pack_start(usb_model)
        usb_description = gtk.Entry()
        vbox_autodetect_usb.pack_start(usb_description)
        usb_commandset = gtk.Entry()
        vbox_autodetect_usb.pack_start(usb_commandset)
        p_autodetect_usb.connect("toggled", self.usb_select, usb_ieee1284, usb_manufacturer, usb_model, usb_description, usb_commandset)

      #PARALLEL PORT AUTODETECTION
        vbox_autodetect_parallel = gtk.VBox()
        hbox_autodetect.add(vbox_autodetect_parallel)
        vbox_autodetect_parallel.show()
        p_autodetect_parallel = gtk.CheckButton("Parallel?")
        vbox_autodetect_parallel.pack_start(p_autodetect_parallel)
        p_autodetect_parallel.show()
        parallel_ieee1284 = gtk.Entry()
        vbox_autodetect_parallel.pack_start(parallel_ieee1284)
        parallel_manufacturer = gtk.Entry()
        vbox_autodetect_parallel.pack_start(parallel_manufacturer)
        parallel_model = gtk.Entry()
        vbox_autodetect_parallel.pack_start(parallel_model)
        parallel_commandset = gtk.Entry()
        vbox_autodetect_parallel.pack_start(parallel_commandset)
        p_autodetect_parallel.connect("toggled", self.parallel_select, parallel_ieee1284, parallel_manufacturer, parallel_model, parallel_commandset)

      #SNMP AUTODETECTION
        vbox_autodetect_snmp = gtk.VBox()
        hbox_autodetect.add(vbox_autodetect_snmp)
        vbox_autodetect_snmp.show()
        p_autodetect_snmp = gtk.CheckButton("SNMP?")
        vbox_autodetect_snmp.pack_start(p_autodetect_snmp)
        p_autodetect_snmp.show()
        snmp_description = gtk.Entry()
        vbox_autodetect_snmp.pack_start(snmp_description)
        p_autodetect_snmp.connect("toggled", self.snmp_select, snmp_description)
 
     #Determine the functionality level of the printer
        hbox_functionality = gtk.HBox()
        vbox.add(hbox_functionality)        
        hbox_functionality.show()

        p_functionality_combo = gtk.combo_box_new_text()
        p_functionality_combo.append_text('Functionality')
        p_functionality_combo.append_text('A')
        p_functionality_combo.append_text('B')
        p_functionality_combo.append_text('D')
        p_functionality_combo.append_text('F')
        p_functionality_combo.set_active(0)
        vbox.pack_start(p_functionality_combo)
        p_functionality_combo.show()

     #Now some fancy footwork so other drivers can join the band
        hboxdriverrow = gtk.HBox()
        vbox.add(hboxdriverrow)
        hboxdriverrow.show()       

        vbdrcol1 = gtk.VBox()
        hboxdriverrow.add(vbdrcol1)
        vbdrcol1.show()

        vbdrcol2 = gtk.VBox()
        hboxdriverrow.add(vbdrcol2)
        vbdrcol2.show()

        vbdrcol2row1 = gtk.HBox()
        vbdrcol2.add(vbdrcol2row1)
        vbdrcol2row1.show()

        vbdrcol2row2 = gtk.HBox()
        vbdrcol2.add(vbdrcol2row2)
        vbdrcol2row2.show()

     #The recommended driver for the printer
        p_recommended_driver_label = gtk.Label('Recommended Driver')
        vbdrcol1.pack_start(p_recommended_driver_label)
        p_recommended_driver_label.show()

        p_recommended_driver = gtk.Entry()
        p_recommended_driver.set_width_chars(12)
        vbdrcol1.pack_start(p_recommended_driver)
        p_recommended_driver_dropdown = gtk.EntryCompletion()
        self.driverlistdropdown_r = gtk.ListStore(str)
        for driver in self.__driverlist__:
            self.driverlistdropdown_r.append([driver])
        p_recommended_driver_dropdown.set_model(self.driverlistdropdown_r)
        p_recommended_driver.set_completion(p_recommended_driver_dropdown)        
        p_recommended_driver_dropdown.set_text_column(0)
        p_recommended_driver.show()

    #Now the additional print drivers
        p_extra_drivers_label = gtk.Label('Other drivers')
        vbdrcol2row1.add(p_extra_drivers_label)
        p_extra_drivers_label.show()

        p_extra_drivers_1 = gtk.Entry()
        p_extra_drivers_1.set_width_chars(12)
        vbdrcol2row2.add(p_extra_drivers_1)
        p_extra_drivers_1.show()

        p_extra_drivers_2 = gtk.Entry()
        p_extra_drivers_2.set_width_chars(12)
        vbdrcol2row2.add(p_extra_drivers_2)
        p_extra_drivers_2.show()

        p_extra_drivers_3 = gtk.Entry()
        p_extra_drivers_3.set_width_chars(12)
        vbdrcol2row2.add(p_extra_drivers_3)
        p_extra_drivers_3.show()

        p_extra_drivers_4 = gtk.Entry()
        p_extra_drivers_4.set_width_chars(12)
        vbdrcol2row2.add(p_extra_drivers_4)
        p_extra_drivers_4.show()

     #Text box to enter comments about the printer
        comments_label = gtk.Label('Comments')
        vbox.pack_start(comments_label)
        comments_label.show()

        p_comments = gtk.Entry()
        vbox.pack_start(p_comments)
        p_comments.show()

     #Throughput of the printer
        throughput_label = gtk.Label('Throughput (optional)')
        vbox.pack_start(throughput_label)
        throughput_label.show()

        p_throughput = gtk.Entry()
        vbox.pack_start(p_throughput)
        p_throughput.show()

     #This connect statement here so that things don't get blowed up
        ps_ppd_location_button.connect('clicked', self.grok_ppd_file_def, p_make, p_model, p_color, p_is_postscript, p_postscript_level, p_postscript_url, p_pjl, p_throughput)

     #And now the sexy part of the program - the action buttons
        hbox_buttons = gtk.HBox()
        vbox.add(hbox_buttons)
        hbox_buttons.show()

        grok_configuration_button = gtk.Button("Configuration")
        hbox_buttons.pack_start(grok_configuration_button)
#        grok_configuration_button.connect('clicked', self.grok_configuration)
        grok_configuration_button.connect('clicked', self.choose_directory_drop)
        grok_configuration_button.show()

        open_printer_xml_file_button = gtk.Button("Open printer XML file")
        hbox_buttons.pack_start(open_printer_xml_file_button)
        open_printer_xml_file_button.connect('clicked', self.open_printer_xml_file_def, p_make, p_model, p_x_dpi, p_y_dpi, p_url, p_pjl, p_charset, p_color, p_mechanism_combo, p_comments, p_functionality_combo, p_proprietary, p_recommended_driver, p_is_postscript, p_is_pcl, p_tiff, p_escp, p_hpgl2, p_postscript_level, p_postscript_url, p_pcl_level, p_consumables)
        open_printer_xml_file_button.show()

        #Gives user option to not enter data to printer XML entry
        add_to_driver_check = gtk.CheckButton("Add to driver file?")
 
        write_xml_button = gtk.Button("Write printer XML file")
        hbox_buttons.pack_start(write_xml_button)
        write_xml_button.connect('clicked', self.write_printer_xml_file, p_make, p_model, p_color, p_mechanism_combo, p_x_dpi, p_y_dpi, p_consumables, p_url, p_is_postscript, p_postscript_level, p_postscript_url, p_is_pcl, p_pcl_level, p_tiff, p_escp, p_hpgl2, p_proprietary, p_pjl, p_charset, p_autodetect_usb, usb_ieee1284, usb_manufacturer, usb_model, usb_description, usb_commandset, p_autodetect_parallel, parallel_ieee1284, parallel_manufacturer, parallel_model, parallel_commandset, snmp_description, p_functionality_combo, p_recommended_driver, p_extra_drivers_1, p_extra_drivers_2, p_extra_drivers_3, p_extra_drivers_4, p_comments, p_throughput, add_to_driver_check)
        write_xml_button.show()

        hbox_buttons.pack_start(add_to_driver_check)
        add_to_driver_check.show()

        window.show()
        return

    def open_printer_xml_file_def(self, button, p_make, p_model, p_x_dpi, p_y_dpi, p_url, p_pjl, p_charset, p_color, p_mechanism_combo, p_comments, p_functionality_combo, p_proprietary, p_recommended_driver, p_is_postscript, p_is_pcl, p_tiff, p_escp, p_hpgl2, p_postscript_level, p_postscript_url, p_pcl_level, p_consumables):
      #This is the mechanism to get the XML file
        print "This feature is not %100 complete, but hold tight"
        xml_file_location = ''
        dialog = gtk.FileChooserDialog("Open a printer XML to grok...",
                            None,
                            gtk.FILE_CHOOSER_ACTION_OPEN,
                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                             gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dialog.set_default_response(gtk.RESPONSE_OK)

        filter = gtk.FileFilter()
        filter.set_name("XML Files")
        filter.add_pattern("*.xml")
        filter.add_pattern("*.Xml")
        filter.add_pattern("*.XML")
        dialog.add_filter(filter)

        filter = gtk.FileFilter()
        filter.set_name("All files")
        filter.add_pattern("*")
        dialog.add_filter(filter)

        response = dialog.run()
        if response == gtk.RESPONSE_OK:
           xml_file_location = dialog.get_filename()
        elif response == gtk.RESPONSE_CANCEL:
           xml_file_location = ''
        dialog.destroy()

      #This reads the XML file
        comments_fix = 0
        if xml_file_location is not '':
          xmldoc = minidom.parse(xml_file_location)
          for node in xmldoc.getElementsByTagName('make'):
             xml_make = node.firstChild.data
             p_make.set_text(xml_make)
          for node in xmldoc.getElementsByTagName('model'):
             xml_model = node.firstChild.data
             p_model.set_text(xml_model)
          for node in xmldoc.getElementsByTagName('consumables'):
             if node.firstChild:
                consumables = node.firstChild.data
                p_consumables.set_text(consumables)
          for node in xmldoc.getElementsByTagName('url'):
             if node.firstChild:
                xml_url = node.firstChild.data
                p_url.set_text(xml_url)
      #This is for <mechanism>
          for node in xmldoc.getElementsByTagName('mechanism'):
            for node in xmldoc.getElementsByTagName('color'):
               p_color.set_active(True)
            for node in xmldoc.getElementsByTagName('x'):
               xml_xdpi = node.firstChild.data
               p_x_dpi.set_text(xml_xdpi)
            for node in xmldoc.getElementsByTagName('y'):
               xml_ydpi = node.firstChild.data
               p_y_dpi.set_text(xml_ydpi)
            for node in xmldoc.getElementsByTagName('laser'):
               p_mechanism_combo.set_active(1)
            for node in xmldoc.getElementsByTagName('inkjet'):
               p_mechanism_combo.set_active(2)
            for node in xmldoc.getElementsByTagName('led'):
               p_mechanism_combo.set_active(3)
            for node in xmldoc.getElementsByTagName('dotmatrix'):
               p_mechanism_combo.set_active(4)
            for node in xmldoc.getElementsByTagName('impact'):
               p_mechanism_combo.set_active(5)
            for node in xmldoc.getElementsByTagName('sublimation'):
               p_mechanism_combo.set_active(6)
            for node in xmldoc.getElementsByTagName('transfer'):
               p_mechanism_combo.set_active(7)
       #This is for <lang>
          for node in xmldoc.getElementsByTagName('lang'):
            for node in xmldoc.getElementsByTagName('postscript'):
               p_is_postscript.set_active(True)
               ps_level = node.getAttribute('level')
               p_postscript_level.set_text(ps_level) 
               #if node.firstChild:
               #   for node in xmldoc.getElementsByTageName('ppd'):
               #      ps_url = node.firstChild.data
               #      p_postscript_url(ps_url)
            for node in xmldoc.getElementsByTagName('pcl'):
               p_is_pcl.set_active(True)
               pcl_level = node.getAttribute('level')
               p_pcl_level.set_text(pcl_level)
            for node in xmldoc.getElementsByTagName('tiff'):
               p_tiff.set_active(True)
            for node in xmldoc.getElementsByTagName('escp'):
               p_escp.set_active(True)
            for node in xmldoc.getElementsByTagName('hpgl2'):
               p_hpgl2.set_active(True)
            for node in xmldoc.getElementsByTagName('pjl'):
               p_pjl.set_active(True)
            for node in xmldoc.getElementsByTagName('charset'):
               p_charset.set_active(True)
            for node in xmldoc.getElementsByTagName('proprietary'):
               p_proprietary.set_active(True)            

            for node in xmldoc.getElementsByTagName('driver'):
               xml_recommended_driver = node.firstChild.data
               p_recommended_driver.set_text(xml_recommended_driver)
       #And now for <functionality>
          for node in xmldoc.getElementsByTagName('functionality'):
             xml_functionality = node.firstChild.data
             if xml_functionality == 'A':
               p_functionality_combo.set_active(1)
             if xml_functionality == 'B':
               p_functionality_combo.set_active(2)
             if xml_functionality == 'D':
               p_functionality_combo.set_active(3)
             if xml_functionality == 'F':
               p_functionality_combo.set_active(4)

          for node in xmldoc.getElementsByTagName('comments'):
             for node in xmldoc.getElementsByTagName('en'):
               xml_comments = node.lastChild.data
               p_comments.set_text(xml_comments)

    def choose_directory_drop(self, button):
        dialog = gtk.FileChooserDialog("Select directory that has drivers, opt, PPD, and printers...",
                               None,
                               gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
                               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dialog.set_default_response(gtk.RESPONSE_OK)

        filter = gtk.FileFilter()
        filter.set_name("All files")
        filter.add_pattern("*")
        dialog.add_filter(filter)

        response = dialog.run()
        if response == gtk.RESPONSE_OK:
           main_folder_location = dialog.get_filename()
           directory_drop = main_folder_location
           self.save_configuration_def(directory_drop)
        elif response == gtk.RESPONSE_CANCEL:
           main_folder_location = directory_drop.get_text()
        dialog.destroy()
        #directory_drop.set_text(main_folder_location)

    def save_configuration_def(self, directory_drop):
        #This is the configuration file that is saved as ppdtoxml.conf
        parent_directory = directory_drop
        print parent_directory

        temp = sys.stdout
        sys.stdout = open("ppdtoxml.conf", 'w')

        print "This is the PPD to XML converter translator configuration file. Mess with this how you want, but otherwise just let the GUI do its thing."
        print "FOODIR=%s" %parent_directory        

        sys.stdout.close()
        sys.stdout = temp

    def grok_ppd_file_def(self, button, p_make, p_model, p_color, p_is_postscript, p_postscript_level, p_postscript_url, p_pjl, p_throughput):
       #This is the part which goes through the PPD and grabs the necessary bits for the XML files
        print "This feature is not %100 complete, be sure to double check the XML file and hold tight"

        dialog = gtk.FileChooserDialog("Open a PPD to grok...",
                               None,
                               gtk.FILE_CHOOSER_ACTION_OPEN,
                               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dialog.set_default_response(gtk.RESPONSE_OK)

        filter = gtk.FileFilter()
        filter.set_name("PPD Files")
        filter.add_pattern("*.ppd")
        filter.add_pattern("*.Ppd")
        filter.add_pattern("*.PPD")
        dialog.add_filter(filter)

        filter = gtk.FileFilter()
        filter.set_name("All files")
        filter.add_pattern("*")
        dialog.add_filter(filter)

        response = dialog.run()
        if response == gtk.RESPONSE_OK:
           ppd_file_location = dialog.get_filename()
           p_postscript_url.set_text(ppd_file_location)
        elif response == gtk.RESPONSE_CANCEL:
           ppd_file_location = ''
        dialog.destroy()

        if ppd_file_location is not '':
           for line in open(ppd_file_location):
              if line.find('*PPD-Adobe:') != -1:
                 print line
              if line.find('*Manufacturer:') != -1:
                 line = line.replace('*Manufacturer:', '')
                 p_make.set_text(self.line_cleaner(line))
              if line.find('*ModelName:') != -1:
                 line = line.replace('*ModelName:', '')
                 line = line.replace(p_make.get_text(), '')
                 p_model.set_text(self.line_cleaner(line))      
              if line.find('*Throughput:') != -1:
                 line = line.replace('*Throughput:', '')
                 p_throughput.set_text(self.line_cleaner(line))
              if line.find('*Protocol') != -1:
                 if line.find('PJL') != -1:
                    p_pjl.set_active(True)
              if line.find('*ColorDevice') != -1:
                 if line.find('True' or 'true'):
                    p_color.set_active(True)
                    print "color device true"
                 #if line.find('False' or 'false'):
                 #   p_color.set_active(False)
              if line.find('*LanguageLevel:') != -1:
                 line = line.replace('*LanguageLevel:', '')
                 line = self.line_cleaner(line)
                 p_is_postscript.set_active(True)
                 p_postscript_level.set_text(line)

    def line_cleaner(self, line):
      #line_cleaner properly formats the strings going into the XML file
        line = line.replace('\"', '')
        line = line.replace('\f', '')
        line = line.replace('\r', '')
        line = line.replace(' ', '')
        line = line.replace('\n', '')
        line = line.replace('\t', '')
        return line

    def postscript_select(self, p_is_postscript, p_postscript_level, p_postscript_url, ps_ppd_location_button):
        if p_is_postscript.get_active():
           p_postscript_level.show()
           p_postscript_url.show()
           ps_ppd_location_button.show()
           p_postscript_url.set_text('')
        else:
           p_postscript_level.hide()
           p_postscript_level.set_text('')
           p_postscript_url.hide()
           ps_ppd_location_button.hide()
           p_postscript_url.set_text('')

    def pcl_select(self, p_is_pcl, p_pcl_level):
        if p_is_pcl.get_active():
           p_pcl_level.show()
        else:
           p_pcl_level.hide()
           p_pcl_level.set_text('')

    def usb_select(self, p_autodetect_usb, usb_ieee1284, usb_manufacturer, usb_model, usb_description, usb_commandset):
        if p_autodetect_usb.get_active():
           usb_ieee1284.show()
           usb_ieee1284.set_text('IEEE 1284')
           usb_manufacturer.show()
           usb_manufacturer.set_text('Manufacturer')        
           usb_model.show()
           usb_model.set_text('Model')
           usb_description.show()
           usb_description.set_text('Description')
           usb_commandset.show()
           usb_commandset.set_text('Commandset')
        else:
           usb_ieee1284.hide()
           usb_ieee1284.set_text('')
           usb_manufacturer.hide()
           usb_manufacturer.set_text('')
           usb_model.hide()
           usb_model.set_text('')
           usb_description.hide()
           usb_description.set_text('')
           usb_commandset.hide()
           usb_commandset.set_text('')

    def parallel_select(self, p_autodetect_parallel, parallel_ieee1284, parallel_manufacturer, parallel_model, parallel_commandset):
        if p_autodetect_parallel.get_active():
           parallel_ieee1284.show()
           parallel_ieee1284.set_text('IEEE 1284')
           parallel_manufacturer.show()
           parallel_manufacturer.set_text('Manufacturer')
           parallel_model.show()
           parallel_model.set_text('Model')
           parallel_commandset.show()
           parallel_commandset.set_text('Commandset')
        else:
           parallel_ieee1284.hide()
           parallel_ieee1284.set_text('')
           parallel_manufacturer.hide()
           parallel_manufacturer.set_text('')
           parallel_model.hide()
           parallel_model.set_text('')
           parallel_commandset.hide()
           parallel_commandset.set_text('')

    def snmp_select(self, p_autodetect_snmp, snmp_description):
        if p_autodetect_snmp.get_active():
           snmp_description.show()
           snmp_description.set_text('SNMP description')
        else:
           snmp_description.hide()
           snmp_description.set_text('')

    def special_char_cleanup(self, stringthing):
      #This formats punctuation properly
        stringthing = stringthing.replace('&', '&amp;')
        stringthing = stringthing.replace('<', '&lt;')
        stringthing = stringthing.replace('>', '&gt;')
        stringthing = stringthing.replace('"', '&quot;')
        stringthing = stringthing.replace("'", '&apos;')
        return stringthing

    def write_printer_xml_file(self, button, p_make, p_model, p_color, p_mechanism_combo, p_x_dpi, p_y_dpi, p_consumables, p_url, p_is_postscript, p_postscript_level, p_postscript_url, p_is_pcl, p_pcl_level, p_tiff, p_escp, p_hpgl2, p_proprietary, p_pjl, p_charset, p_autodetect_usb, usb_ieee1284, usb_manufacturer, usb_model, usb_description, usb_commandset, p_autodetect_parallel, parallel_ieee1284, parallel_manufacturer, parallel_model, parallel_commandset, snmp_description, p_functionality_combo, p_recommended_driver, p_extra_drivers_1, p_extra_drivers_2, p_extra_drivers_3, p_extra_drivers_4, p_comments, p_throughput, add_to_driver_check):
  
        make_text = p_make.get_text()
        filename_make = make_text.replace(' ', '_')
        model_text = p_model.get_text()
        filename_model = model_text.replace(' ', '_')

        mechanism_model = p_mechanism_combo.get_model()
        mechanism_active = p_mechanism_combo.get_active()
        mechanism_text = ''
        if mechanism_active:
           mechanism_text = mechanism_model[mechanism_active][0]
           mechanism_text = mechanism_text + '/'
        else:
           mechanism_text = ''
 
        x_dpi_text = p_x_dpi.get_text()
        y_dpi_text = p_y_dpi.get_text()
        consumables_text = p_consumables.get_text()
        consumables_text = self.special_char_cleanup(consumables_text)
        url_text = p_url.get_text()
        url_text = self.special_char_cleanup(url_text)
        postscript_level_text = p_postscript_level.get_text()
        postscript_url_text = p_postscript_url.get_text()
        pcl_level_text = p_pcl_level.get_text()

     #Adds today's date to the XML file
        todaysdate = datetime.date.today()

     #Autodetection variables
        usb_ieee1284_text = usb_ieee1284.get_text()
        usb_manufacturer_text = usb_manufacturer.get_text()
        usb_model_text = usb_model.get_text()
        usb_description_text = usb_description.get_text()
        usb_commandset_text = usb_commandset.get_text()
        parallel_ieee1284_text = parallel_ieee1284.get_text()
        parallel_manufacturer_text = parallel_manufacturer.get_text()
        parallel_model_text = parallel_model.get_text()
        parallel_commandset_text = parallel_commandset.get_text()
        snmp_text = snmp_description.get_text()

        functionality_model = p_functionality_combo.get_model()
        functionality_active = p_functionality_combo.get_active()
        if functionality_active:
           functionality_text = functionality_model[functionality_active][0]
        else:
           print >> sys.stderr, "You need to assign a functionality grade!"
           functionality_text = "!!! NO FUNCTIONALITY SET !!!"

        recommended_driver_text = p_recommended_driver.get_text()
        extra_driver_text_1 = p_extra_drivers_1.get_text() 
        extra_driver_text_2 = p_extra_drivers_2.get_text()
        extra_driver_text_3 = p_extra_drivers_3.get_text()
        extra_driver_text_4 = p_extra_drivers_4.get_text()
 
        comments_text = p_comments.get_text()
        comments_text = self.special_char_cleanup(comments_text)

        throughput_text = p_throughput.get_text()

        foodir = ''     
        if os.path.isfile("ppdtoxml.conf"):
           for line in open("ppdtoxml.conf"):
               if line.find('FOODIR=') != -1:
                  line = line.replace('FOODIR=', '')
                  line = line.replace('\n', '')
                  foodir = line
               else: 
                  pass

        xml_entry_id = 'printer/' + filename_make + '-' + filename_model
        xmlfile_name = foodir + '/' + xml_entry_id + '.xml'
        temp = sys.stdout
        sys.stdout = open(xmlfile_name, 'w')
 
        print "<printer id=\"%s\">" %xml_entry_id
        print "   <make>%s</make>" %make_text
        print "   <model>%s</model>" %model_text
        print "   <mechanism>"
        if p_color.get_active():
           print "   <color />"
        else:
           print "   <!--not \"color\"-->"
        if mechanism_text is not '':
           print "      <%s>" %mechanism_text       
        print "      <resolution>"
        print "         <dpi>"
    
        if x_dpi_text is not "":
           print "            <x>%s</x>" %x_dpi_text
        else:
           print "            <!--x unknown-->"

        if y_dpi_text is not "":
           print "            <y>%s</y>" %y_dpi_text   
        else:
           print "            <!--y unknown-->"

        print "         </dpi>"
        print "      </resolution>"
        print "   </mechanism>"
        print "   <url>%s</url>" %url_text

    #LANGUAGES
        print "   <lang>"

        if p_is_postscript.get_active():
           if postscript_level_text is not "":
              print "      <postscript level=\"%s\" />" %postscript_level_text
  
        if p_is_pcl.get_active():
           print "      <pcl level=\"%s\" />" %pcl_level_text

        if p_tiff.get_active():
           print "      <tiff />"
  
        if p_escp.get_active():
           print "      <escp />"

        if p_hpgl2.get_active():
           print "      <hpgl2 />"

        if p_proprietary.get_active():
           print "      <proprietary />"

        if p_pjl.get_active():
           print "      <pjl />"
        else: 
           print "      <!--no pjl-->"

        if p_charset.get_active():
           print "      <text>"
           print "         <charset>us-ascii</charset>"
           print "      </text>"
        else:
           print "      <!--no \"text\"-->"

        print "   </lang>"

    #AUTODETECT PARAMETERS
        if (p_autodetect_usb.get_active() or p_autodetect_parallel.get_active() or snmp_text is not ""): 
           print "   <autodetect>"
           if p_autodetect_parallel.get_active():
              print "     <parallel>"
              if parallel_ieee1284_text is not '':
                 print "       <ieee1284>%s<ieee1284>" %parallel_ieee1284_text
              if parallel_manufacturer_text is not '':
                 print "       <manufacturer>%s</manufacturer>" %parallel_manufacturer_text
              if parallel_model_text is not '': 
                 print "       <model>%s</model>" %parallel_model_text
              if parallel_commandset_text is not '':
                 print "       <commandset>%s</commandset>" %parallel_commandset_text
              print "     </parallel>"
           if p_autodetect_usb.get_active():
              print "     <usb>"
              if usb_ieee1284_text is not '':
                 print "       <ieee1284>%s</ieee1284>" %usb_ieee1284_text
              if usb_manufacturer_text is not '':
                 print "       <manufacturer>%s</manufacturer>" %usb_manufacturer_text
              if usb_model_text is not '':
                 print "       <model>%s</model>" %usb_model_text
              if usb_description_text is not '':
                 print "       <description>%s</description>" %usb_description_text
              if usb_commandset_text is not '':
                 print "       <commandset>%s</commandset>" %usb_commandset_text
              print "     </usb>"
           if snmp_text is not '':
              print "     <snmp>"
              print "       <description>%s</description>" %snmp_text
              print "     </snmp>"
           print "   </autodetect>"

        print "   <functionality>%s</functionality>" %functionality_text

        if recommended_driver_text is not "":
           print "   <driver>%s</driver>" %recommended_driver_text
           print "   <drivers>"
           print "     <driver>"
           print "       <id>%s</id>" %recommended_driver_text
           if recommended_driver_text.find('Postscript') != -1:
              if postscript_url_text is not "":
                 print "       <ppd>%s</ppd>" %postscript_url_text
           print "     </driver>"
           if extra_driver_text_1 is not "":
              print "     <driver>"
              print "       <id>%s</id>" %extra_driver_text_1
              if extra_driver_text_1.find('Postscript') != -1:
                 if postscript_url_text is not "":
                    print "       <ppd>%s</ppd>" %postscript_url_text
              print "     </driver>" 
           if extra_driver_text_2 is not "":
              print "     <driver>"
              print "       <id>%s</id>" %extra_driver_text_2
              if extra_driver_text_2.find('Postscript') != -1:
                 if postscript_url_text is not "":
                    print "       <ppd>%s</ppd>" %postscript_url_text
              print "     </driver>"
           if extra_driver_text_3 is not "":
              print "     <driver>"
              print "       <id>%s</id>" %extra_driver_text_3
              if extra_driver_text_3.find('Postscript') != -1:
                 if postscript_url_text is not "":
                    print "       <ppd>%s</ppd>" %postscript_url_text
              print "     </driver>"
           if extra_driver_text_4 is not "":
              print "     <driver>"
              print "       <id>%s</id>" %extra_driver_text_4
              if extra_driver_text_4.find('Postscript') != -1:
                 if postscript_url_text is not "":
                    print "       <ppd>%s</ppd>" %postscript_url_text
              print "     </driver>"
           print "   </drivers>"

        print "   <comments>"
        print "      <en>"
        if comments_text is not "":
           print "      %s" %comments_text
           print "      "
        if throughput_text is not "":
           print "      Throughput = %s" %throughput_text
           print "      "
        print "      Foomatic entry made by PPDtoXML T/G %s on %s" % (version, todaysdate)
        print "      </en>"
        print "   </comments>"
        print "</printer>"

        sys.stdout.close()
        sys.stdout = temp

        printer_xmlmade_dialog = gtk.MessageDialog(None,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
                "Printer XML file created at %s." %xmlfile_name)
        printer_xmlmade_dialog.run()
        printer_xmlmade_dialog.destroy()

        if add_to_driver_check.get_active():
     #Now the part where we enter the printer information into the driver XML file
           driver_xml_location = foodir + '/driver/' + recommended_driver_text + '.xml'
           if os.path.exists(driver_xml_location):
              parsed_driver = minidom.parse(driver_xml_location)
              for node in parsed_driver.getElementsByTagName('printers'):
                 printertag = parsed_driver.createElement('printer')
                 node.appendChild(printertag)
                 printeridtag = parsed_driver.createElement('id')
                 printertag.appendChild(printeridtag)
                 txt = parsed_driver.createTextNode(xml_entry_id)
                 printeridtag.appendChild(txt)

            #This rewrites the driver XML file
                 temp = sys.stdout
                 sys.stdout = open(driver_xml_location, 'w')
                 print parsed_driver.toxml()
                 sys.stdout.close()
                 sys.stdout = temp

                 driver_xml_dialog = gtk.MessageDialog(None,
                      gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                      gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
                      "printer ID entered into %s - please correct formatting flaws in the driver XML file until this matter has been fixed" %driver_xml_location)
                 driver_xml_dialog.run()
                 driver_xml_dialog.destroy()

           else:
              driver_xml_dialog = gtk.MessageDialog(None,
                      gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                      gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
                      "driver XML file doesn't exist at %s - can't write information" %driver_xml_location)
              driver_xml_dialog.run()
              driver_xml_dialog.destroy()

def main():
    gtk.main()
    return

if __name__ == "__main__":
    PPDtoXML()
    main()
