pixelocr/pixelocr/gui/glyphdbedit.py
2014-09-19 23:37:24 +02:00

229 lines
6.7 KiB
Python

# Copyright (C) 2014 Andrey Golovizin
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
from collections import defaultdict
from PyQt4.QtCore import (
Qt,
QAbstractTableModel,
QSize,
)
from PyQt4.QtGui import (
QApplication,
QColor,
QFont,
QTableView,
)
from ..glyphdb import GlyphDB
from ..image import Image
class Column(object):
flags = Qt.ItemIsEditable
to_display = str
to_value = str
def __init__(self, document, header, field_name):
self.document = document
self.header = header
self.field_name = field_name
def data(self, glyph_data, role):
if role in [Qt.DisplayRole, Qt.EditRole]:
return self.to_display(getattr(glyph_data, self.field_name))
def setData(self, glyph_data, value, role):
if role == Qt.EditRole:
setattr(glyph_data, self.field_name, self.to_value(value))
def sortKey(self, glyph_data):
return getattr(glyph_data, self.field_name)
class TextColumn(Column):
def data(self, glyph_data, role):
config = self.document.config
if role == Qt.DecorationRole:
return glyph_data.image.qimage
elif role == Qt.FontRole:
font = QFont()
font.setBold(glyph_data.bold)
font.setItalic(glyph_data.italic)
if config.glyph_font_family:
font.setFamily(config.glyph_font_family)
if config.glyph_font_size:
font.setPixelSize(config.glyph_font_size)
return font
elif role == Qt.ForegroundRole:
return glyph_data.qcolor
else:
return super().data(glyph_data, role)
class IntColumn(Column):
to_display = int
to_value = int
class DateColumn(Column):
flags = 0
class CheckBoxColumn(Column):
flags = Qt.ItemIsUserCheckable
def data(self, glyph_data, role):
if role == Qt.CheckStateRole:
value = getattr(glyph_data, self.field_name)
return Qt.Checked if value else Qt.Unchecked
def setData(self, glyph_data, value, role):
if role == Qt.CheckStateRole:
setattr(glyph_data, self.field_name, value == Qt.Checked)
class ColorColumn(Column):
flags = 0
data_type = None
def data(self, glyph_data, role):
r, g, b = getattr(glyph_data, self.field_name)
if role == Qt.DecorationRole:
return QColor(r, g, b)
elif role == Qt.DisplayRole:
return '#{:02x}{:02x}{:02x}'.format(r, g, b)
class GlyphDBModel(QAbstractTableModel):
def __init__(self, document, parent=None):
super().__init__(parent)
self.document = document
self.glyphdb = document.glyphdb
self.columns = self.createColumns()
self.sortColumn = len(self.columns) - 1 # date_add ed
self.sortOrder = Qt.DescendingOrder
self.values = list(self.glyphdb.values())
self.updateData()
def createColumns(self):
return [
TextColumn(self.document, 'Text', 'text'),
IntColumn(self.document, 'Elevation', 'elevation'),
CheckBoxColumn(self.document, 'B', 'bold'),
CheckBoxColumn(self.document, 'I', 'italic'),
ColorColumn(self.document, 'Color', 'color'),
DateColumn(self.document, 'Date added', 'date_added'),
]
def flags(self, index):
column = self.columns[index.column()]
return super().flags(index) | column.flags
def rowCount(self, parent):
return len(self.values)
def columnCount(self, parent):
return len(self.columns)
def headerData(self, section, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.columns[section].header
def data(self, index, role):
column = self.columns[index.column()]
glyph_data = self.values[index.row()]
return column.data(glyph_data, role)
def setData(self, index, value, role):
column = self.columns[index.column()]
glyph_data = self.values[index.row()]
self.glyphdb.remove(glyph_data)
column.setData(glyph_data, value, role)
self.glyphdb.add(glyph_data)
self.updateData()
return True
def removeRows(self, row, count, parent=None):
self.beginRemoveRows(parent, row, row + count - 1)
values = self.values[row: row + count]
for value in values:
self.glyphdb.remove(value)
del self.values[row]
self.endRemoveRows()
return True
def sort(self, column_index, order):
self.sortColumn = column_index
self.sortOrder = order
self.updateData()
def updateData(self):
self.layoutAboutToBeChanged.emit()
column = self.columns[self.sortColumn]
reverse = self.sortOrder == Qt.DescendingOrder
if len(self.values) != len(self.glyphdb.values()):
self.values = self.glyphdb.values()
self.values = sorted(self.values, key=column.sortKey, reverse=reverse)
self.layoutChanged.emit()
class GlyphTableView(QTableView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setSortingEnabled(True)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Delete:
for index in self.selectedIndexes():
self.model().removeRow(index.row())
else:
return super().keyPressEvent(event)
class GlyphDBEdit(GlyphTableView):
def __init__(self, document, *args, **kwargs):
super().__init__(*args, **kwargs)
self.document = document
model = GlyphDBModel(document, parent=self)
self.horizontalHeader().setSortIndicator(model.sortColumn, model.sortOrder)
self.setModel(model)
self.resizeColumnsToContents()
def sizeHint(self):
return QSize(640, 480)
def updateData(self):
self.model().updateData()
def main(argv):
dirname = argv[1]
app = QApplication(argv)
glyphdb = GlyphDB(dirname)
win = GlyphDBEdit(glyphdb)
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main(sys.argv)