229 lines
6.7 KiB
Python
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)
|