Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/midi/midiinputmappingtablemodel.cpp

Go to the documentation of this file.
00001 
00002 #include <QtCore>
00003 #include <QLabel>
00004 #include "midimapping.h"
00005 #include "midiinputmappingtablemodel.h"
00006 
00007 MidiInputMappingTableModel::MidiInputMappingTableModel(MidiMapping* mapping) :
00008     QAbstractTableModel(),
00009     m_pMapping(NULL)
00010 
00011 {
00012     setMapping(mapping); //Save the mapping
00013 }
00014 
00015 MidiInputMappingTableModel::~MidiInputMappingTableModel()
00016 {
00017 }
00018 
00019 void MidiInputMappingTableModel::slotInputMappingChanged() {
00020 
00021     // for now ask it to refresh the whole thing -- we can get fancy
00022     // with more complex signals later
00023     reset();
00024 }
00025 
00026 void MidiInputMappingTableModel::setMapping(MidiMapping* mapping)
00027 {
00028     if(m_pMapping != NULL) {
00029         disconnect(m_pMapping, SIGNAL(inputMappingChanged()), this, SLOT(slotInputMappingChanged()));
00030     }
00031     m_pMapping = mapping;
00032     connect(m_pMapping, SIGNAL(inputMappingChanged()), this, SLOT(slotInputMappingChanged()));
00033 }
00034 
00035 QVariant MidiInputMappingTableModel::data(const QModelIndex &index, int role) const
00036  {     
00037      if (!index.isValid())
00038          return QVariant();
00039 
00040      if(!m_pMapping->isInputIndexValid(index.row()))
00041          return QVariant();
00042 
00043      if (role == Qt::DisplayRole || role == Qt::EditRole) {
00044          //This might be super slow, but that's the price of using a map/hash table (which give
00045          //us super fast lookups when MidiMessages come in).
00046          //Also note that QMaps are always sorted by key, whereas QHashes are not sorted and rearrange themselves.
00047 
00048          MidiMessage message = m_pMapping->getInputMidiMessage(index.row());
00049          MixxxControl control = m_pMapping->getInputMixxxControl(message);
00050 
00051          switch (index.column())
00052          {
00053              case MIDIINPUTTABLEINDEX_MIDISTATUS:
00054                  return message.getMidiStatusByte();
00055                  break;
00056 
00057              case MIDIINPUTTABLEINDEX_MIDINO:
00058                  return message.getMidiNo();
00059                  break;
00060 
00061              case MIDIINPUTTABLEINDEX_MIDICHANNEL:
00062                  return message.getMidiChannel();
00063                  break;
00064 
00065              case MIDIINPUTTABLEINDEX_CONTROLOBJECTGROUP:
00066                  return control.getControlObjectGroup();
00067                  break;
00068 
00069              case MIDIINPUTTABLEINDEX_CONTROLOBJECTVALUE:
00070                  return control.getControlObjectValue();
00071                  break;
00072 
00073              case MIDIINPUTTABLEINDEX_MIDIOPTION:
00074                  return control.getMidiOption();
00075                  break;
00076 
00077             case MIDIINPUTTABLEINDEX_CONTROLOBJECTDESCRIPTION:
00078                 return control.getControlObjectDescription();
00079                 break;
00080 
00081              default:
00082                  return QVariant();
00083          }
00084      }
00085 
00086      return QVariant();
00087 }
00088 
00089 Qt::ItemFlags MidiInputMappingTableModel::flags(const QModelIndex &index) const
00090 {
00091      if (!index.isValid())
00092          return Qt::ItemIsEnabled;
00093 
00094      return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
00095 }
00096 
00097 bool MidiInputMappingTableModel::setData(const QModelIndex &index, const QVariant &value,
00098                                          int role)
00099 {
00100     if (index.isValid() && role == Qt::EditRole) {
00101         MidiMessage message = m_pMapping->getInputMidiMessage(index.row());
00102         MixxxControl control = m_pMapping->getInputMixxxControl(message);
00103         
00104         //Now we actually need to remove the mapping we want to operate on,
00105         //because otherwise if we change the status or channel bits, we'll
00106         //end up inserting a new mapping instead of overwriting this one.
00107         //(This is because the mapping datastructure is a hash table that
00108         // hashes on the status byte.)
00109         m_pMapping->clearInputMidiMapping(message);
00110         
00111         switch (index.column())
00112             {
00113                 case MIDIINPUTTABLEINDEX_MIDISTATUS:
00114                     message.setMidiStatusByte((MidiStatusByte)value.toInt());
00115                     break;
00116 
00117                 case MIDIINPUTTABLEINDEX_MIDINO:
00118                     message.setMidiNo(value.toInt());
00119                     break;
00120 
00121                 case MIDIINPUTTABLEINDEX_MIDICHANNEL:
00122                     message.setMidiChannel(value.toInt());
00123                     break;
00124 
00125                 case MIDIINPUTTABLEINDEX_CONTROLOBJECTGROUP:
00126                     control.setControlObjectGroup(value.toString());
00127                     break;
00128 
00129                 case MIDIINPUTTABLEINDEX_CONTROLOBJECTVALUE:
00130                     control.setControlObjectValue(value.toString());
00131                     break;
00132 
00133                 case MIDIINPUTTABLEINDEX_MIDIOPTION:
00134                     control.setMidiOption((MidiOption)value.toInt());
00135                     break;
00136 
00137                 case MIDIINPUTTABLEINDEX_CONTROLOBJECTDESCRIPTION:
00138                     control.setControlObjectDescription(value.toString());
00139                     break;
00140             };
00141 
00142         //Insert the updated control into the map.
00143         m_pMapping->setInputMidiMapping(message, control);
00144 
00145         emit dataChanged(index, index);
00146         return true;
00147     }
00148     return false;
00149 }
00150 
00151 int MidiInputMappingTableModel::rowCount(const QModelIndex& parent) const
00152 {
00153     if (parent != QModelIndex()) //Some weird thing for table-based models.
00154         return 0;
00155     
00156     return m_pMapping->numInputMidiMessages();
00157 }
00158 
00159 int MidiInputMappingTableModel::columnCount(const QModelIndex& parent) const
00160 {
00161     if (parent != QModelIndex()) //Some weird thing for table-based models.
00162         return 0;
00163     return MIDIINPUTTABLEINDEX_NUMCOLS;
00164 }
00165 
00166 QVariant MidiInputMappingTableModel::headerData(int section, Qt::Orientation orientation, int role) const
00167 {
00168     //Column heading labels
00169     if (orientation == Qt::Horizontal)
00170     {
00171         switch (section)
00172         {
00173             case MIDIINPUTTABLEINDEX_MIDISTATUS:
00174                 return QVariant(tr("Midi Status Type"));
00175                 break;
00176 
00177             case MIDIINPUTTABLEINDEX_MIDINO:
00178                 return QVariant(tr("Midi Note"));
00179                 break;
00180 
00181             case MIDIINPUTTABLEINDEX_MIDICHANNEL:
00182                 return QVariant(tr("Midi Channel"));
00183                 break;
00184 
00185             case MIDIINPUTTABLEINDEX_CONTROLOBJECTGROUP:
00186                 return QVariant(tr("Control Group"));
00187                 break;
00188 
00189             case MIDIINPUTTABLEINDEX_CONTROLOBJECTVALUE:
00190                 return QVariant(tr("Control Value"));
00191                 break;
00192 
00193             /*  //WTF, why does the header disappear when I enable this? - Albert (1 AM)
00194             case MIDIINPUTTABLEINDEX_MIDIOPTION:
00195                 return QVariant(tr("Midi Option"));
00196                 break;
00197                 */
00198 
00199             case MIDIINPUTTABLEINDEX_CONTROLOBJECTDESCRIPTION:
00200                 return QVariant(tr("Description"));
00201                 break;
00202         }
00203     }
00204 
00205     return QVariant();
00206 }
00207 
00208 bool MidiInputMappingTableModel::removeRow(int row, const QModelIndex& parent)
00209 {
00210     //DO NOT CALL beginRemoveRows()/endRemoveRows() in this function! You're ONLY supposed to
00211     //do that for removeRows() (plural!!). It causes a bug if you do it here.
00212     
00213     m_pMapping->clearInputMidiMapping(row);
00214 
00215     return true;
00216 }
00217 
00218 bool MidiInputMappingTableModel::removeRows(int row, int count, const QModelIndex& parent)
00219 {
00220     beginRemoveRows(parent, row, row+count);
00221 
00222     m_pMapping->clearInputMidiMapping(row, count);
00223 
00224     //TODO: Should probably handle an invalid selection and return false.
00225 
00226     endRemoveRows();
00227 
00228     return true;
00229 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines