PosesDataModel.py
Go to the documentation of this file.
00001 from copy import copy
00002 
00003 from actions.ActionSequence import ActionSequence
00004 from actions.DefaultAction import DefaultAction
00005 from DoubleSpinBoxDelegate import DoubleSpinBoxDelegate
00006 from IntegerSpinBoxDelegate import IntegerSpinBoxDelegate
00007 
00008 import python_qt_binding.QtBindingHelper #@UnusedImport
00009 from QtCore import QAbstractTableModel, QByteArray, QMimeData, QModelIndex, Qt, Signal
00010 
00011 class PosesDataModel(QAbstractTableModel):
00012 
00013     actions_changed = Signal()
00014     duration_modified = Signal()
00015 
00016     _mime_type = 'application/x-slider-action'
00017 
00018     def __init__(self, editable=False):
00019         super(PosesDataModel, self).__init__()
00020         self._action_sequence = ActionSequence()
00021         self._editable = editable
00022         self._joint_columns = {}
00023 
00024         action = DefaultAction()
00025         self._add_joint(1, action, 'head_pan_joint', 'Hd Turn')
00026         self._add_joint(2, action, 'head_tilt_joint', 'Hd Nod')
00027         self._add_joint(3, action, 'torso_lift_joint', 'Torso', 2)
00028         self._add_joint(4, action, 'l_shoulder_pan_joint', 'Lp1')
00029         self._add_joint(5, action, 'l_shoulder_lift_joint', 'Ll2')
00030         self._add_joint(6, action, 'l_upper_arm_roll_joint', 'Lu3')
00031         self._add_joint(7, action, 'l_elbow_flex_joint', 'Le4')
00032         self._add_joint(8, action, 'l_forearm_roll_joint', 'Lf5')
00033         self._add_joint(9, action, 'l_wrist_flex_joint', 'Lw6')
00034         self._add_joint(10, action, 'l_wrist_roll_joint', 'Lr7')
00035         self._add_joint(11, action, 'l_gripper', 'LGrip', 3)
00036         self._add_joint(12, action, 'r_shoulder_pan_joint', 'Rp1')
00037         self._add_joint(13, action, 'r_shoulder_lift_joint', 'Rl2')
00038         self._add_joint(14, action, 'r_upper_arm_roll_joint', 'Ru3')
00039         self._add_joint(15, action, 'r_elbow_flex_joint', 'Re4')
00040         self._add_joint(16, action, 'r_forearm_roll_joint', 'Rf5')
00041         self._add_joint(17, action, 'r_wrist_flex_joint', 'Rw6')
00042         self._add_joint(18, action, 'r_wrist_roll_joint', 'Rr7')
00043         self._add_joint(19, action, 'r_gripper', 'RGrip', 3)
00044 
00045         # keep reference to delegates to prevent being garbaged
00046         self._delegates = []
00047 
00048     def _add_joint(self, column, action, label, header, precision=None):
00049         info = copy(action.get_joint_info(label))
00050         info['header'] = header
00051         info['decimals'] = precision
00052         self._joint_columns[column] = info
00053 
00054     def set_editable(self, editable):
00055         if self._editable != editable:
00056             self._editable = editable
00057             self.reset()
00058 
00059     def add_action(self, action, index = None):
00060         self._add_action(action, index)
00061         self.actions_changed.emit()
00062         self.duration_modified.emit()
00063 
00064     def _add_action(self, action, index = None):
00065         model_index = QModelIndex()
00066         if index is None or index == len(self._action_sequence.actions()):
00067             rows = len(self._action_sequence.actions())
00068             index = None
00069         else:
00070             assert(index >=0 and index < len(self._action_sequence.actions()))
00071             rows = index
00072 
00073         # insert at model-index of parent-item
00074         self.beginInsertRows(model_index, rows, rows)
00075         self._action_sequence.add_action(action, index)
00076         self.endInsertRows()
00077 
00078     def move_action(self, source_index, destination_index):
00079         assert(source_index >=0 and source_index < len(self._action_sequence.actions()))
00080         assert(destination_index >=0 and destination_index <= len(self._action_sequence.actions()))
00081         action = self._action_sequence.actions()[source_index]
00082         self._remove_action(source_index)
00083         if destination_index > source_index:
00084             destination_index -= 1
00085         self._add_action(action, destination_index)
00086         self.actions_changed.emit()
00087 
00088     def remove_action(self, index):
00089         self._remove_action(index)
00090         self.actions_changed.emit()
00091         self.duration_modified.emit()
00092 
00093     def _remove_action(self, index):
00094         assert(index >=0 and index < len(self._action_sequence.actions()))
00095         # delete at model-index of parent-item
00096         model_index = QModelIndex()
00097         self.beginRemoveRows(model_index, index, index)
00098         self._action_sequence.remove_action(index)
00099         self.endRemoveRows()
00100 
00101     def remove_all_actions(self):
00102         index = QModelIndex()
00103         rows = len(self._action_sequence.actions())
00104         self.beginRemoveRows(index, 0, rows - 1)
00105         self._action_sequence.remove_all_actions()
00106         self.endRemoveRows()
00107         self.actions_changed.emit()
00108         self.duration_modified.emit()
00109 
00110     def action_sequence(self):
00111         return self._action_sequence
00112 
00113     def rowCount(self, parent=None):
00114         return len(self._action_sequence.actions())
00115 
00116     def columnCount(self, parent=None):
00117         if self._editable:
00118             return 1 + len(self._joint_columns)
00119         else:
00120             return 1 + 1
00121 
00122     def data(self, index, role=None):
00123         if role is None:
00124             role = Qt.DisplayRole
00125         if index.row() >= 0 and index.row() < len(self._action_sequence.actions()):
00126             if role == Qt.DisplayRole:
00127                 if index.column() == 0:
00128                     return '%.1f' % self._action_sequence.actions()[index.row()].get_duration()
00129                 elif not self._editable and index.column() == 1:
00130                     return self._action_sequence.actions()[index.row()].to_string()
00131                 elif self._editable and index.column() in self._joint_columns.keys():
00132                     joint_info = self._joint_columns[index.column()]
00133                     try:
00134                         value = self._action_sequence.actions()[index.row()].get_value(joint_info['label'])
00135                         if joint_info['decimals'] is not None:
00136                             value = round(value, joint_info['decimals'])
00137                         else:
00138                             value = int(round(value))
00139                         return value
00140                     except:
00141                         return ''
00142             if role == Qt.EditRole:
00143                 if index.column() == 0:
00144                     return self._action_sequence.actions()[index.row()].get_duration()
00145                 elif self._editable and index.column() in self._joint_columns.keys():
00146                     joint_info = self._joint_columns[index.column()]
00147                     try:
00148                         value = self._action_sequence.actions()[index.row()].get_value(joint_info['label'])
00149                         if joint_info['decimals'] is not None:
00150                             value = round(value, joint_info['decimals'])
00151                         else:
00152                             value = int(round(value))
00153                         return value
00154                     except:
00155                         return ''
00156         return None
00157 
00158     def setData(self, index, value, role):
00159         if role == Qt.EditRole:
00160             if index.column() == 0:
00161                 value = float(value)
00162                 self._action_sequence.actions()[index.row()].set_duration(value)
00163                 self.duration_modified.emit()
00164                 return True
00165             elif self._editable:
00166                 value = float(value)
00167                 try:
00168                     self._action_sequence.actions()[index.row()].update_value(self._joint_columns[index.column()]['label'], value)
00169                 except:
00170                     return False
00171                 return True
00172         return super(PosesDataModel, self).setData(index, value, role)
00173 
00174     def flags(self, index):
00175         f = super(PosesDataModel, self).flags(index)
00176         if index.isValid():
00177             if index.column() == 0:
00178                 f |= Qt.ItemIsEditable
00179             elif self._editable and index.column() in self._joint_columns.keys():
00180                 try:
00181                     # only cell which have real values can be edited
00182                     self._action_sequence.actions()[index.row()].get_value(self._joint_columns[index.column()]['label'])
00183                     f |= Qt.ItemIsEditable
00184                 except:
00185                     pass
00186             f |= Qt.ItemIsDragEnabled
00187         f |= Qt.ItemIsDropEnabled
00188         return f
00189 
00190     def headerData(self, section, orientation, role=None):
00191         if role is None:
00192             role = Qt.DisplayRole
00193         if role == Qt.DisplayRole:
00194             if orientation == Qt.Horizontal:
00195                 if section == 0:
00196                     return 'Time'
00197                 elif not self._editable and section == 1:
00198                     return 'Joints'
00199                 elif self._editable and section in self._joint_columns.keys():
00200                     return self._joint_columns[section]['header']
00201             elif orientation == Qt.Vertical:
00202                 return 'Pose %d' % (section + 1)
00203         return None
00204 
00205     def supportedDropActions(self):
00206         return Qt.CopyAction | Qt.MoveAction
00207 
00208     def mimeTypes(self):
00209         return [self._mime_type]
00210 
00211     def mimeData(self, indexes):
00212         #print 'mimeData()'
00213         row = None
00214         for index in indexes:
00215             if index.isValid():
00216                 if row is None:
00217                     row = index.row()
00218                 if row != index.row():
00219                     row = None
00220                     break
00221 
00222         mimeData = QMimeData()
00223         if row is not None:
00224             mimeData.setData(self._mime_type, QByteArray.number(row))
00225         return mimeData;
00226 
00227     def dropMimeData(self, data, action, row, column, parent):
00228         #print 'dropMimeData()'
00229         if action == Qt.MoveAction:
00230             before_row = None
00231             if row != -1:
00232                 before_row = row
00233             elif parent.isValid():
00234                 before_row = parent.row()
00235             else:
00236                 before_row = self.rowCount()
00237             if data.hasFormat(self._mime_type):
00238                 byte_array = data.data(self._mime_type)
00239                 source_row, is_int = byte_array.toInt()
00240                 if is_int and before_row != source_row + 1:
00241                     #print 'dropMimeData()', source_row, '->', before_row
00242                     self.move_action(source_row, before_row)
00243                     return True
00244         return super(PosesDataModel, self).dropMimeData(data, action, row, column, parent)
00245 
00246     def add_delegates(self, table_view):
00247         for i in self._joint_columns.keys():
00248             joint_info = self._joint_columns[i]
00249             if joint_info['decimals'] is not None:
00250                 delegate = DoubleSpinBoxDelegate()
00251                 delegate.setDecimals(joint_info['decimals'])
00252             else:
00253                 delegate = IntegerSpinBoxDelegate()
00254             delegate.setMinimum(joint_info['min'])
00255             delegate.setMaximum(joint_info['max'])
00256             delegate.setSingleStep(joint_info['single_step'])
00257             table_view.setItemDelegateForColumn(i, delegate)
00258             self._delegates.append(delegate)


slider_gui
Author(s): Dirk Thomas
autogenerated on Wed Aug 26 2015 15:37:50