# -*- coding: utf-8 -*-

# Copyright (c) 2003 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the handler class for reading an XML project session file.
"""

import codecs
import sys
import os
from types import UnicodeType

from xml.sax.handler import ContentHandler

from qt import qApp, QTranslator

class WizardHandler(ContentHandler):
    """
    Class implementing a sax handler to read an XML project session file.
    
    The wizards configuration file must have a <Wizards></Wizards> entry
    per wizard. Each of these entries must have the following sections.
    
    <Import>: This names the module to be imported.
    <Class>: This names the class.
    <Translations>: This names the basename of the translation files.
    
    Import and Class are mandatory, Translations is optional.

    The value of the Translations section will be combined with the
    location string determined at startup time and be given
    an extension of '.qm' to yield the filename to be loaded
    into a QTranslator object.
    
    An entry of <Separator /> will yield a separator line in the
    Wizards menu.
    """
    def __init__(self, wizards, wizdir, locale):
        self.elements = {
            'Wizard' : (self.startWizard, self.endWizard),
            'Import' : (self.defaultStartElement, self.endImport),
            'Class' : (self.defaultStartElement, self.endClass),
            'Translations' : (self.defaultStartElement, self.endTranslations),
            'Separator' : (self.startSeparator, self.defaultEndElement),
        }
    
        self.wizards = wizards
        self.wizDir = wizdir
        self.locale = locale
        
        self.encoder = codecs.lookup(sys.getdefaultencoding())[0] # encode,decode,reader,writer
        
    def utf8_to_code(self, text):
        if type(text) is not UnicodeType:
            text = unicode(text, "utf-8")
        return self.encoder(text)[0] # result,size
        
    def unescape(self, text):
        return text.replace("&gt;",">").replace("&lt;","<").replace("&amp;","&")
        
    def startDocument(self):
        self.buffer = ""
        
    def startElement(self, name, attrs):
        try:
            self.elements[name][0](attrs)
        except KeyError:
            pass
            
    def endElement(self, name):
        try:
            self.elements[name][1]()
        except KeyError:
            pass
            
    def characters(self, chars):
        self.buffer += chars
        
    ###################################################
    ## below follow the individual handler functions
    ###################################################
    
    def defaultStartElement(self, attrs):
        self.buffer = ""
        
    def defaultEndElement(self):
        pass
        
    def startWizard(self, attrs):
        self.imp = None
        self.cls = None
        self.trans = None
        
    def endWizard(self):
        try:
            exec 'import %s' % self.imp
            exec 'wizard = %s.%s(self.wizards)' % (self.imp, self.cls)
            self.wizards.registeredWizards.append(wizard)
            if self.trans is not None:
                qtrans = QTranslator(None)
                dir, dummy = os.path.splitext('%s.%s' % (self.wizDir, self.imp))
                dir = dir.replace('.', os.sep)
                if qtrans.load(self.trans, dir):
                    self.wizards.registeredTranslators.append(qtrans)
                    qApp.installTranslator(qtrans)
        except:
            print 'Could not bind wizard %s.%s!' % (self.imp, self.cls)
            
    def endImport(self):
        self.imp = self.utf8_to_code(self.buffer)
        
    def endClass(self):
        self.cls = self.utf8_to_code(self.buffer)
        
    def endTranslations(self):
        self.trans = "%s%s" % (self.utf8_to_code(self.buffer), self.locale)
        
    def startSeparator(self, attrs):
        self.wizards.registeredWizards.append(None)
