from common import * import re def editableColourStr(array): return '#%02X%02X%02X (%d)' % tuple(array) NICE_STR_RE = re.compile('^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})\s*(?:\((\d+)\))?$') def colourFromNiceStr(thing): match = NICE_STR_RE.match(thing) try: if match: r,g,b,a = match.groups() return (int(r,16), int(g,16), int(b,16), int(a) if a != None else 255) except: pass return None class KPWorldTableModel(QtCore.QAbstractTableModel): FIELDS = ('Name', 'World ID', 'Track ID', 'FS Text 1', 'FS Text 2', 'FS Hint 1', 'FS Hint 2', 'HUD Text 1', 'HUD Text 2', 'HUD Hue', 'HUD Saturation', 'HUD Lightness') def __init__(self, kpmap, parent=None): QtCore.QAbstractTableModel.__init__(self, parent) self.currentMap = kpmap self.worlds = kpmap.worlds def columnCount(self, parent): return len(self.FIELDS) def headerData(self, section, orientation, role): if orientation == Qt.Horizontal: if role == Qt.DisplayRole: return self.FIELDS[section] else: if role == Qt.DisplayRole: return str(self.worlds[section].uniqueKey) return QtCore.QVariant() def rowCount(self, parent): if parent.isValid(): return 0 else: return len(self.worlds) def data(self, index, role): if index.isValid(): entry = self.worlds[index.row()] col = index.column() if role == Qt.DisplayRole or role == Qt.EditRole: if col == 0: return entry.name elif col == 1: return entry.worldID elif col == 2: return entry.musicTrackID elif col == 3 or col == 4: return editableColourStr(entry.fsTextColours[col - 3]) elif col == 5 or col == 6: return editableColourStr(entry.fsHintColours[col - 5]) elif col == 7 or col == 8: return editableColourStr(entry.hudTextColours[col - 7]) elif col >= 9 and col <= 11: return entry.hudHintTransform[col - 9] if role == Qt.DecorationRole: if col == 3 or col == 4: return QtGui.QColor(*entry.fsTextColours[col - 3]) elif col == 5 or col == 6: return QtGui.QColor(*entry.fsHintColours[col - 5]) elif col == 7 or col == 8: return QtGui.QColor(*entry.hudTextColours[col - 7]) return QtCore.QVariant() def flags(self, index): return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable def setData(self, index, value, role): if index.isValid(): if role == Qt.EditRole: success = False entry = self.worlds[index.row()] col = index.column() if col == 0: entry.name = str(value.toString()) success = True elif col == 1: entry.worldID = str(value.toString()) success = True elif col == 2: v,ok = value.toInt() if ok: entry.musicTrackID = v success = True elif col >= 3 and col <= 8: newCol = colourFromNiceStr(str(value.toString())) if newCol: success = True if col == 3: entry.fsTextColours = (newCol, entry.fsTextColours[1]) elif col == 4: entry.fsTextColours = (entry.fsTextColours[0], newCol) elif col == 5: entry.fsHintColours = (newCol, entry.fsHintColours[1]) elif col == 6: entry.fsHintColours = (entry.fsHintColours[0], newCol) elif col == 7: entry.hudTextColours = (newCol, entry.hudTextColours[1]) elif col == 8: entry.hudTextColours = (entry.hudTextColours[0], newCol) elif col >= 9 and col <= 11: v,ok = value.toInt() if ok: new = list(entry.hudHintTransform) new[col - 9] = v entry.hudHintTransform = new success = True if success: self.dataChanged.emit(index, index) return success return False def addEntryToEnd(self): self.beginInsertRows(QtCore.QModelIndex(), len(self.worlds), len(self.worlds)) entry = KPWorldDef() entry.uniqueKey = self.currentMap.allocateWorldDefKey() self.worlds.append(entry) self.endInsertRows() def removeRows(self, row, count, parent): if not parent.isValid(): if row >= 0 and (row + count) <= len(self.worlds): self.beginRemoveRows(parent, row, row+count-1) for i in xrange(count): del self.worlds[row] self.endRemoveRows() class KPWorldEditor(QtGui.QWidget): def __init__(self, kpmap, parent=None): QtGui.QWidget.__init__(self, parent, Qt.Window) self.setWindowTitle('World Editor') self.dataView = QtGui.QTableView(self) self.addButton = QtGui.QPushButton('Add', self) self.removeButton = QtGui.QPushButton('Remove', self) layout = QtGui.QGridLayout(self) layout.addWidget(self.dataView, 0, 0, 1, 2) layout.addWidget(self.addButton, 1, 0, 1, 1) layout.addWidget(self.removeButton, 1, 1, 1, 1) self.model = KPWorldTableModel(kpmap, self) self.dataView.setModel(self.model) self.addButton.clicked.connect(self.model.addEntryToEnd) self.removeButton.clicked.connect(self.removeCurrentEntry) def removeCurrentEntry(self): what = self.dataView.selectionModel().currentIndex() if what.isValid(): what = what.row() key = self.model.worlds[what].uniqueKey self.model.removeRows(what, 1, QtCore.QModelIndex())