![]() |
Mixxx
|
00001 00002 #include <QtCore> 00003 #include <QLabel> 00004 #include "midimapping.h" 00005 #include "midioutputmappingtablemodel.h" 00006 00007 MidiOutputMappingTableModel::MidiOutputMappingTableModel(MidiMapping* mapping) : 00008 QAbstractTableModel(), 00009 m_pMapping(NULL) 00010 { 00011 setMapping(mapping); //Save the mapping 00012 } 00013 00014 MidiOutputMappingTableModel::~MidiOutputMappingTableModel() 00015 { 00016 } 00017 00018 void MidiOutputMappingTableModel::slotOutputMappingChanged() { 00019 00020 // for now ask it to refresh the whole thing -- we can get fancy 00021 // with more complex signals later 00022 reset(); 00023 } 00024 00025 void MidiOutputMappingTableModel::setMapping(MidiMapping* mapping) 00026 { 00027 if(m_pMapping != NULL) { 00028 disconnect(m_pMapping, SIGNAL(outputMappingChanged()), this, SLOT(slotOutputMappingChanged())); 00029 } 00030 m_pMapping = mapping; 00031 connect(m_pMapping, SIGNAL(outputMappingChanged()), this, SLOT(slotOutputMappingChanged())); 00032 } 00033 00034 QVariant MidiOutputMappingTableModel::data(const QModelIndex &index, int role) const 00035 { 00036 if (!index.isValid()) 00037 return QVariant(); 00038 00039 if(!m_pMapping->isOutputIndexValid(index.row())) 00040 return QVariant(); 00041 00042 if (role == Qt::DisplayRole || role == Qt::EditRole) { 00043 //This might be super slow, but that's the price of using a map/hash table. 00044 //Also note that QMaps are always sorted by key, whereas QHashes are not sorted and rearrange themselves. 00045 00046 MixxxControl control = m_pMapping->getOutputMixxxControl(index.row()); 00047 MidiMessage command = m_pMapping->getOutputMidiMessage(control); 00048 00049 switch (index.column()) 00050 { 00051 case MIDIOUTPUTTABLEINDEX_MIDISTATUS: 00052 return command.getMidiStatusByte(); 00053 break; 00054 00055 case MIDIOUTPUTTABLEINDEX_MIDINO: 00056 return command.getMidiNo(); 00057 break; 00058 00059 case MIDIOUTPUTTABLEINDEX_MIDICHANNEL: 00060 return command.getMidiChannel(); 00061 break; 00062 00063 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTGROUP: 00064 return control.getControlObjectGroup(); 00065 break; 00066 00067 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTVALUE: 00068 return control.getControlObjectValue(); 00069 break; 00070 00071 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTDESCRIPTION: 00072 return control.getControlObjectDescription(); 00073 break; 00074 00075 case MIDIOUTPUTTABLEINDEX_MIDIOPTION: 00076 return control.getMidiOption(); 00077 break; 00078 00079 case MIDIOUTPUTTABLEINDEX_THRESHOLDMIN: 00080 return control.getThresholdMinimum(); 00081 break; 00082 00083 case MIDIOUTPUTTABLEINDEX_THRESHOLDMAX: 00084 return control.getThresholdMaximum(); 00085 break; 00086 00087 default: 00088 return QVariant(); 00089 } 00090 } 00091 00092 return QVariant(); 00093 } 00094 00095 Qt::ItemFlags MidiOutputMappingTableModel::flags(const QModelIndex &index) const 00096 { 00097 if (!index.isValid()) 00098 return Qt::ItemIsEnabled; 00099 00100 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; 00101 } 00102 00103 bool MidiOutputMappingTableModel::setData(const QModelIndex &index, const QVariant &value, 00104 int role) 00105 { 00106 if (index.isValid() && role == Qt::EditRole) { 00107 MixxxControl control = m_pMapping->getOutputMixxxControl(index.row()); 00108 MidiMessage command = m_pMapping->getOutputMidiMessage(control); 00109 00110 //Now we actually need to remove the mapping we want to operate on, 00111 //because otherwise if we change the status or channel bits, we'll 00112 //end up inserting a new mapping instead of overwriting this one. 00113 //(This is because the mapping datastructure is a hash table that 00114 // hashes on the status byte.) 00115 m_pMapping->clearOutputMidiMapping(control); 00116 00117 switch (index.column()) 00118 { 00119 case MIDIOUTPUTTABLEINDEX_MIDISTATUS: 00120 command.setMidiStatusByte((MidiStatusByte)value.toInt()); 00121 break; 00122 00123 case MIDIOUTPUTTABLEINDEX_MIDINO: 00124 command.setMidiNo(value.toInt()); 00125 break; 00126 00127 case MIDIOUTPUTTABLEINDEX_MIDICHANNEL: 00128 command.setMidiChannel(value.toInt()); 00129 break; 00130 00131 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTGROUP: 00132 control.setControlObjectGroup(value.toString()); 00133 break; 00134 00135 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTVALUE: 00136 control.setControlObjectValue(value.toString()); 00137 break; 00138 00139 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTDESCRIPTION: 00140 control.setControlObjectDescription(value.toString()); 00141 break; 00142 00143 case MIDIOUTPUTTABLEINDEX_MIDIOPTION: 00144 control.setMidiOption((MidiOption)value.toInt()); 00145 break; 00146 00147 case MIDIOUTPUTTABLEINDEX_THRESHOLDMIN: 00148 control.setThresholdMinimum((float)value.toDouble()); 00149 break; 00150 00151 case MIDIOUTPUTTABLEINDEX_THRESHOLDMAX: 00152 control.setThresholdMaximum((float)value.toDouble()); 00153 break; 00154 }; 00155 00156 //Insert the updated control into the map. 00157 m_pMapping->setOutputMidiMapping(control, command); 00158 00159 emit dataChanged(index, index); 00160 return true; 00161 } 00162 return false; 00163 } 00164 00165 int MidiOutputMappingTableModel::rowCount(const QModelIndex& parent) const 00166 { 00167 if (parent != QModelIndex()) //Some weird thing for table-based models. 00168 return 0; 00169 return m_pMapping->numOutputMixxxControls(); 00170 } 00171 00172 int MidiOutputMappingTableModel::columnCount(const QModelIndex& parent) const 00173 { 00174 if (parent != QModelIndex()) //Some weird thing for table-based models. 00175 return 0; 00176 return MIDIOUTPUTTABLEINDEX_NUMCOLS; 00177 } 00178 00179 QVariant MidiOutputMappingTableModel::headerData(int section, Qt::Orientation orientation, int role) const 00180 { 00181 //Column heading labels 00182 if (orientation == Qt::Horizontal) 00183 { 00184 switch (section) 00185 { 00186 case MIDIOUTPUTTABLEINDEX_MIDISTATUS: 00187 return QVariant(tr("Midi Status")); 00188 break; 00189 00190 case MIDIOUTPUTTABLEINDEX_MIDINO: 00191 return QVariant(tr("Midi Note")); 00192 break; 00193 00194 case MIDIOUTPUTTABLEINDEX_MIDICHANNEL: 00195 return QVariant(tr("Midi Channel")); 00196 break; 00197 00198 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTGROUP: 00199 return QVariant(tr("Control Group")); 00200 break; 00201 00202 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTVALUE: 00203 return QVariant(tr("Control Value")); 00204 break; 00205 00206 case MIDIOUTPUTTABLEINDEX_CONTROLOBJECTDESCRIPTION: 00207 return QVariant(tr("Description")); 00208 break; 00209 00210 case MIDIOUTPUTTABLEINDEX_THRESHOLDMIN: 00211 return QVariant(tr("Threshold Min")); 00212 break; 00213 00214 case MIDIOUTPUTTABLEINDEX_THRESHOLDMAX: 00215 return QVariant(tr("Threshold Max")); 00216 break; 00217 00218 /* //WTF, why does the header disappear when I enable this? - Albert (1 AM) 00219 case MIDIOUTPUTTABLEINDEX_MIDIOPTION: 00220 return QVariant(tr("Midi Option")); 00221 break; 00222 */ 00223 } 00224 } 00225 00226 return QVariant(); 00227 } 00228 00229 bool MidiOutputMappingTableModel::removeRow(int row, const QModelIndex& parent) 00230 { 00231 m_pMapping->clearOutputMidiMapping(row); 00232 00233 return true; 00234 } 00235 00236 bool MidiOutputMappingTableModel::removeRows(int row, int count, const QModelIndex& parent) 00237 { 00238 beginRemoveRows(parent, row, row+count); 00239 qDebug() << "MidiOutputMappingTableModel::removeRows()"; 00240 00241 m_pMapping->clearOutputMidiMapping(row, count); 00242 00243 //TODO: Should probably handle an invalid selection and return false. 00244 00245 endRemoveRows(); 00246 00247 return true; 00248 } 00249 00250 /* 00251 bool MidiOutputMappingTableModel::insertRow ( int row, const QModelIndex & parent = QModelIndex() ) 00252 { 00253 return insertRows(row, 1, parent); 00254 } 00255 00256 bool MidiOutputMappingTableModel::insertRows ( int row, int count, const QModelIndex & parent = QModelIndex() ) 00257 { 00258 emit beginInsertRows(parent, row, row+count-1); 00259 m_pMapping->setMapping( 00260 emit endInsertRows(); 00261 00262 return true; 00263 }*/