from PyQt5 import QtCore, QtWidgets, QtGui
import sys, re
import model


# ------------------------------------------------------------------------------
class TableView(QtWidgets.QTableView):

    def __init__(self, parent=None):
        super().__init__(parent)

    def keyPressEvent(self, event):
        key = event.key()
        mod = int(event.modifiers())
        if key == QtCore.Qt.Key_Q and mod == QtCore.Qt.CTRL:
            self.close()
            exit()
        super().keyPressEvent(event)

    def closeEditor(self, editor, hint):
        if editor.validate():
            print(f'>> Closing editor')
            super().closeEditor(editor, hint)
        else:
            print(f'>> Not closing editor')


# ------------------------------------------------------------------------------
class Delegate(QtWidgets.QStyledItemDelegate):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.editor = None

    def createEditor(self, parent, option, index):
        self.view = parent.parent()
        self.editor = CellEditor(parent)
        return self.editor

    def setEditorData(self, label, index):
        model = index.model()
        v = model.data(index, QtCore.Qt.EditRole)

    def setModelData(self, label, model, index):
        value = label.text()
        row = index.row()
        col = index.column()
        if label.validate():
            model.setData(index, value, QtCore.Qt.EditRole)
            print(f'>> [setModelData({value})] accepted')
        else:
            label.setFocus()
            self.view.setCurrentIndex(index)
            print(f'>> [setModelData({value})] rejected')

    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)

    def eventFilter(self, target, event):
        if event.type() == QtCore.QEvent.KeyPress:
            key = event.key()
            mod = int(event.modifiers())

            # ASCII input -- add to cell value
            if (
                key >= QtCore.Qt.Key_Space and key <= QtCore.Qt.Key_AsciiTilde and 
                (mod == QtCore.Qt.NoModifier or mod == QtCore.Qt.SHIFT)
            ):
                text = self.editor.text()
                self.editor.setText(text + event.text())
                return True

            # [ctrl-H], Backspace -- delete a character
            elif (
                (key == QtCore.Qt.Key_H and mod == QtCore.Qt.CTRL) or
                (key == QtCore.Qt.Key_Backspace and mod == QtCore.Qt.NoModifier)
            ):
                self.editor.setText(self.editor.text()[:-1])
                return True

        return False


# ------------------------------------------------------------------------------
class CellEditor(QtWidgets.QLabel):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setStyleSheet('font-style: italic; font-weight: bold; color: blue')
        self.setAutoFillBackground(True)

#   def keyPressEvent(self, event):
#       key = event.key()
#       mod = int(event.modifiers())

#       # ASCII input -- add to cell value
#       if (
#           key >= QtCore.Qt.Key_Space and key <= QtCore.Qt.Key_AsciiTilde and 
#           (mod == QtCore.Qt.NoModifier or mod == QtCore.Qt.SHIFT)
#       ):
#           text = self.text()
#           self.setText(text + event.text())

#       # [ctrl-H], Backspace -- delete a character
#       elif (
#           (key == QtCore.Qt.Key_H and mod == QtCore.Qt.CTRL) or
#           (key == QtCore.Qt.Key_Backspace and mod == QtCore.Qt.NoModifier)
#       ):
#           self.setText(self.text()[:-1])

#       else:
#           super().keyPressEvent(event)

    def validate(self):
        return re.fullmatch('\d+', self.text())



# ------------------------------------------------------------------------------
if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    app.setStyle('fusion')

    rowCount = 3
    columnCount = 4
    data = [
        ['foo', 'goo', 'zoo', 'moo'],
        ['bar', 'zar', 'jar', 'gar'],
        ['qux', 'lux', 'mux', 'sux']
        ]

    view = TableView()
    view.resize(550, 160)
    model = model.TableModel(data)
    view.setModel(model)
    view.show()

    delegate = Delegate()
    view.setItemDelegate(delegate)

    sys.exit(app.exec_())
