# -*- coding:utf-8

from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4 import QtSql
import sys

class Window(QtGui.QWidget):
    """Classe principale"""
    def __init__(self, parent):
        """Constructeur"""
        super(Window, self).__init__(parent)
        self.setWindowTitle("Exemple de QDataWidgetMapper")

        self.setupModel()

        # Nom
        self.nameLabel=QtGui.QLabel("Nom:")
        self.nameEdit=QtGui.QLineEdit()

        # Adresse        
        self.addressLabel=QtGui.QLabel("Adresse:")
        self.addressEdit=QtGui.QTextEdit()

        # Type
        self.typeComboBox=QtGui.QComboBox()
        self.rel=self.model.relationModel(self.typeIndex)
        self.typeComboBox.setModel(self.rel)
        self.typeComboBox.setModelColumn(self.rel.fieldIndex("description"))

        # Navigation
        self.nextButton=QtGui.QPushButton("Suivant")
        self.previousButton=QtGui.QPushButton("Précédent")

        # Widget de correspondance
        self.mapper=QtGui.QDataWidgetMapper(self)
        self.mapper.setModel(self.model)

        self.mapper.setItemDelegate(QtSql.QSqlRelationalDelegate(self))
        
        self.mapper.addMapping(self.nameEdit, 1)
        self.mapper.addMapping(self.addressEdit, 2)
        self.mapper.addMapping(self.typeComboBox, self.typeIndex)

        # Connexions
        self.connect(self.previousButton, QtCore.SIGNAL("clicked()"),
                     self.toPrevious)
        self.connect(self.nextButton, QtCore.SIGNAL("clicked()"),
                     self.toNext)
        self.connect(self.mapper, QtCore.SIGNAL("currentIndexChanged(int)"),
                     self.updateButtons)

        self.mapper.toFirst() # Nécessaire au premier lancement 
        
        # Layout
        self.createLayout()

    def toPrevious(self):
        self.mapper.toPrevious()
        self.model.submit()

    def toNext(self):
        self.mapper.toNext()
        self.model.submit()

    def setupModel(self):
        """Crée le modèle"""
        self.db=QtSql.QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName(":memory:")
        self.db.open()

        self.setupDatabaseI()

        self.model=QtSql.QSqlRelationalTableModel(self)
        self.model.setTable("person")
        
        self.typeIndex=self.model.fieldIndex("typeid")
        self.model.setRelation(self.typeIndex,
                               QtSql.QSqlRelation("addresstype", "id", "description"))
        self.model.select()
        self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)

    def setupDatabaseI(self):
        query=QtSql.QSqlQuery(self.db)
        query.exec_("""CREATE TABLE IF NOT EXISTS person (id INTEGER, name TEXT, address TEXT, typeid INTEGER)""")
        query.exec_("""CREATE TABLE IF NOT EXISTS addresstype(id INTEGER, description TEXT)""")
        
        contacts=[[1,"Alice","123 Main Street", 101],
                 [2, "Bob", "PO Box 32", 102],
                 [3, "Carol", "The Lighthouse", 103],
                 [4, "Donald", "47388 Park Avenue",101],
                 [5, "Emma", "Research Station", 103]]
        
        for contact in contacts:
            query.prepare("""INSERT INTO person VALUES(:id,:name,:address,:typeid)""")
            query.bindValue(":id", contact[0])
            query.bindValue(":name", contact[1])
            query.bindValue(":address", contact[2])
            query.bindValue(":typeid", contact[3])
            query.exec_()

        types=[[101, "Home"],
               [102, "Work"],
               [103, "Other"]]
        for type_ in types:
            query.prepare("""INSERT INTO addresstype VALUES(:id, :description)""")
            query.bindValue(":id", type_[0])
            query.bindValue(":description", type_[1])
            query.exec_()
        
    def updateButtons(self, index):
        """Met à jour l'état des boutons si nécessaire"""
        self.previousButton.setEnabled(index>0)
        self.nextButton.setEnabled(index<self.model.rowCount()-1)

    def createLayout(self):
        """Positionne les widgets"""
        self.mainLayout=QtGui.QGridLayout(self)
        
        self.mainLayout.addWidget(self.nameLabel, 0,0)
        self.mainLayout.addWidget(self.nameEdit, 0,1)
        
        self.mainLayout.addWidget(self.addressLabel, 1,0, QtCore.Qt.AlignTop)
        self.mainLayout.addWidget(self.addressEdit, 1,1)
        
        self.mainLayout.addWidget(self.typeComboBox, 2,1)
        
        self.mainLayout.addWidget(self.nextButton, 1,2, QtCore.Qt.AlignTop)
        self.mainLayout.addWidget(self.previousButton, 0,2)
        
        self.setLayout(self.mainLayout)            
        
if __name__=="__main__":
    app=QtGui.QApplication(sys.argv)
    window=Window(None)
    window.show()
    sys.exit(app.exec_())
