287 lines
8.5 KiB
Python
287 lines
8.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from PyQt4 import QtGui, QtCore
|
|
from control_widgets import AddRemoveWidget
|
|
|
|
|
|
def calc_colors(count):
|
|
if count == 1:
|
|
return [QtGui.QColor(0, 255, 0),]
|
|
r = 0
|
|
g = 255
|
|
step = int(512. / (count-1))
|
|
colors = list()
|
|
for i in range(count):
|
|
colors.append(QtGui.QColor(r, g, 0))
|
|
if r < 255:
|
|
r += step
|
|
if r > 255:
|
|
g -= (r - 256)
|
|
r = 255
|
|
g = max(0, g)
|
|
else:
|
|
g -= step
|
|
g = max(0, g)
|
|
return colors
|
|
|
|
|
|
def set_colors(temp_levels):
|
|
colors = calc_colors(len(temp_levels) - 1)
|
|
ix = 0
|
|
for temp_level in temp_levels:
|
|
if not temp_level.is_env:
|
|
temp_level.color = colors[ix]
|
|
ix += 1
|
|
else:
|
|
temp_level.color = QtGui.QColor("black")
|
|
|
|
|
|
class TempLevel(QtCore.QObject):
|
|
def __init__(self, name, temp, is_env=False):
|
|
super(TempLevel, self).__init__()
|
|
self.name = name
|
|
self.temp = temp
|
|
self.is_env = is_env
|
|
self.color = None
|
|
|
|
|
|
def __str__(self):
|
|
return "<TempLevel: name=%r, temp=%r>" % (self.name, self.temp)
|
|
|
|
|
|
def __lt__(self, other):
|
|
return self.temp < other.temp
|
|
|
|
|
|
def __le__(self, other):
|
|
return self.temp <= other.temp
|
|
|
|
|
|
def __eq__(self, other):
|
|
return self.temp == other.temp
|
|
|
|
|
|
def is_between(self, tl1, tl2):
|
|
tmp = [tl1, tl2, self]
|
|
tmp.sort()
|
|
return self == tmp[1]
|
|
|
|
|
|
def set_next(self, temp_level):
|
|
if temp_level is self:
|
|
raise ValueError("same temp_level")
|
|
self.next = temp_level
|
|
|
|
|
|
def __repr__(self):
|
|
return "TempLevel(%r, %r, %r)" % (self.name, self.temp, self.is_env)
|
|
|
|
|
|
class TempLevelModel(QtCore.QAbstractTableModel):
|
|
solder_changed = QtCore.pyqtSignal()
|
|
status_message = QtCore.pyqtSignal(QtCore.QString, int)
|
|
|
|
def __init__(self, parent):
|
|
super(TempLevelModel, self).__init__(parent)
|
|
self._changed = False
|
|
self.temp_levels = list()
|
|
self.headerdata = [u"Name", u"Temperature (°C)"]
|
|
|
|
|
|
def headerData(self, col, orientation, role):
|
|
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
|
|
return QtCore.QVariant(self.headerdata[col])
|
|
return QtCore.QVariant()
|
|
|
|
|
|
def rowCount(self, parent):
|
|
return len(self.temp_levels)
|
|
|
|
|
|
def columnCount(self, parent):
|
|
return 2
|
|
|
|
|
|
def data(self, index, role):
|
|
if not index.isValid():
|
|
return QtCore.QVariant()
|
|
|
|
if role == QtCore.Qt.DisplayRole:
|
|
col = index.column()
|
|
if col == 0:
|
|
return QtCore.QVariant(self.temp_levels[index.row()].name)
|
|
else:
|
|
return QtCore.QVariant(self.temp_levels[index.row()].temp)
|
|
|
|
if index.column() == 0 and role == QtCore.Qt.DecorationRole:
|
|
p = QtGui.QPixmap(10, 10)
|
|
color = self.temp_levels[index.row()].color
|
|
p.fill(color)
|
|
return p
|
|
|
|
return QtCore.QVariant()
|
|
|
|
|
|
def flags(self, index):
|
|
if not index.isValid():
|
|
return 0
|
|
|
|
if index.row() != 0:
|
|
return QtCore.Qt.ItemFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable)
|
|
else:
|
|
return QtCore.Qt.ItemFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable)
|
|
|
|
|
|
def neigbors(self, temp_level):
|
|
ix = self.temp_levels.index(temp_level)
|
|
return self.temp_levels[ix-1], self.temp_levels[ix+1]
|
|
|
|
|
|
def setData(self, index, variant, role):
|
|
if index.isValid() and role == QtCore.Qt.EditRole:
|
|
col = index.column()
|
|
if col == 0:
|
|
self.temp_levels[index.row()].name = unicode(variant.toString())
|
|
elif col == 1:
|
|
temp, res = variant.toInt()
|
|
tl = self.temp_levels[index.row()]
|
|
try:
|
|
tl0 = self.temp_levels[index.row() - 1]
|
|
if tl0.temp >= temp:
|
|
self.status_message.emit(QtCore.QString(u"Error: TempLevel %r cannot be moved across TempLevel %r!" % (tl.name, tl0.name)), 10000)
|
|
return False
|
|
except Exception, e:
|
|
pass
|
|
try:
|
|
tl1 = self.temp_levels[index.row() + 1]
|
|
if tl1.temp <= temp:
|
|
self.status_message.emit(QtCore.QString(u"Error: TempLevel %r cannot be moved across TempLevel %r!" % (tl.name, tl1.name)), 10000)
|
|
return False
|
|
except Exception, e:
|
|
pass
|
|
tl.temp = temp
|
|
|
|
self.solder_changed.emit()
|
|
return True
|
|
return False
|
|
|
|
|
|
def remove_temp_level(self, index):
|
|
tmp = self.temp_levels[index]
|
|
del self.temp_levels[index]
|
|
self.reset()
|
|
self.solder_changed.emit()
|
|
return tmp
|
|
|
|
|
|
def add_temp_level(self, index, temp_level):
|
|
self.temp_levels.insert(index.row() + 1, temp_level)
|
|
set_colors(self.temp_levels)
|
|
self.reset()
|
|
self.solder_changed.emit()
|
|
|
|
|
|
def append_temp_level(self, temp_level):
|
|
self.temp_levels.append(temp_level)
|
|
set_colors(self.temp_levels)
|
|
self.reset()
|
|
self.solder_changed.emit()
|
|
|
|
|
|
def setTempLevels(self, temp_levels):
|
|
assert isinstance(temp_levels, list)
|
|
self.temp_levels = temp_levels
|
|
self.reset()
|
|
|
|
|
|
def clear(self):
|
|
self.temp_levels = list()
|
|
self.reset()
|
|
|
|
|
|
def get_temp_level(self, ix):
|
|
return self.temp_levels[ix]
|
|
|
|
|
|
class TempLevelWidget(QtGui.QWidget):
|
|
temp_level_removed = QtCore.pyqtSignal(TempLevel)
|
|
temp_level_added = QtCore.pyqtSignal(TempLevel, TempLevel)
|
|
solder_changed = QtCore.pyqtSignal()
|
|
|
|
def __init__(self, parent, readonly=False):
|
|
super(TempLevelWidget, self).__init__(parent)
|
|
self.readonly = readonly
|
|
self.temp_level_model = TempLevelModel(self)
|
|
|
|
self.temp_level_view = QtGui.QTableView()
|
|
self.temp_level_view.setModel(self.temp_level_model)
|
|
self.temp_level_view.verticalHeader().setVisible(False)
|
|
self.temp_level_view.resizeColumnsToContents()
|
|
self.temp_level_view.horizontalHeader().setStretchLastSection(True)
|
|
self.temp_level_view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
|
|
|
h = QtGui.QHBoxLayout()
|
|
h.addWidget(self.temp_level_view)
|
|
self.setLayout(h)
|
|
|
|
self.connect(
|
|
self.temp_level_view,
|
|
QtCore.SIGNAL("clicked(QModelIndex)"),
|
|
self.temp_level_selected)
|
|
|
|
if not readonly:
|
|
self.controls = AddRemoveWidget(self)
|
|
h.addWidget(self.controls)
|
|
|
|
self.connect(
|
|
self.controls.add_button,
|
|
QtCore.SIGNAL("clicked()"),
|
|
self.append_temp_level)
|
|
|
|
self.connect(
|
|
self.controls.remove_button,
|
|
QtCore.SIGNAL("clicked()"),
|
|
self.remove_temp_level)
|
|
|
|
self.connect(
|
|
self.temp_level_model,
|
|
QtCore.SIGNAL("solder_changed()"),
|
|
self._solder_changed)
|
|
|
|
def _solder_changed(self):
|
|
self.solder_changed.emit()
|
|
|
|
|
|
def setData(self, solder):
|
|
self.temp_level_model.setTempLevels(solder.temp_levels)
|
|
self.temp_level_view.resizeColumnsToContents()
|
|
self.temp_level_view.setCurrentIndex(self.temp_level_model.index(0, 0))
|
|
|
|
def add_temp_level(self):
|
|
pass
|
|
#new_temp = old_tl.temp + (self.temp_level_model.temp_levels[index.row() + 1].temp - old_tl.temp) / 2
|
|
|
|
|
|
def append_temp_level(self):
|
|
old_tl = self.temp_level_model.temp_levels[-1]
|
|
new_temp = old_tl.temp + 20
|
|
ix = self.temp_level_model.rowCount(None)
|
|
new_tl = TempLevel("new " + str(ix), new_temp)
|
|
self.temp_level_model.append_temp_level(new_tl)
|
|
self.temp_level_view.setCurrentIndex(self.temp_level_model.index(ix, 0))
|
|
self.temp_level_added.emit(old_tl, new_tl)
|
|
|
|
def remove_temp_level(self):
|
|
self.temp_level_removed.emit(
|
|
self.temp_level_model.remove_temp_level(
|
|
self.temp_level_model.rowCount(None) - 1))
|
|
self.solder_changed.emit()
|
|
self.temp_level_view.setCurrentIndex(self.temp_level_model.index(self.temp_level_model.rowCount(None) - 1, 0))
|
|
|
|
|
|
def temp_level_selected(self, index):
|
|
if index.isValid():
|
|
row = index.row()
|
|
if not self.readonly:
|
|
self.controls.remove_button.setEnabled(not self.temp_level_model.temp_levels[row].is_env)
|