/[svn]/qsampler/trunk/src/qsamplerInstrumentList.cpp
ViewVC logotype

Diff of /qsampler/trunk/src/qsamplerInstrumentList.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1558 by capela, Thu Dec 6 09:35:33 2007 UTC revision 2064 by capela, Fri Mar 12 16:02:32 2010 UTC
# Line 1  Line 1 
1  // qsamplerInstrumentList.cpp  // qsamplerInstrumentList.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2003-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2003-2010, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck     Copyright (C) 2007, Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
# Line 24  Line 24 
24  #include "qsamplerInstrumentList.h"  #include "qsamplerInstrumentList.h"
25    
26  #include "qsamplerInstrument.h"  #include "qsamplerInstrument.h"
 #include "qsamplerInstrumentForm.h"  
27    
28  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
29  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
30    
31  #include <QApplication>  #include <QApplication>
 #include <QMessageBox>  
 #include <QMenu>  
 #include <QAction>  
32  #include <QCursor>  #include <QCursor>
 #include <QFileInfo>  
33    
 // Needed for lroundf()  
 #include <math.h>  
   
 #ifndef CONFIG_ROUND  
 static inline long lroundf ( float x )  
 {  
         if (x >= 0.0f)  
                 return long(x + 0.5f);  
         else  
                 return long(x - 0.5f);  
 }  
 #endif  
   
 using namespace QSampler;  
34    
35    namespace QSampler {
36    
37  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
38  // QSampler::MidiInstrumentsModel - data model for MIDI prog mappings  // QSampler::InstrumentListModel - data model for MIDI prog mappings
39  //                                  (used for QTableView)  //
40    
41  MidiInstrumentsModel::MidiInstrumentsModel ( QObject* pParent)  InstrumentListModel::InstrumentListModel ( QObject *pParent )
42          : QAbstractTableModel(pParent)          : QAbstractItemModel(pParent)
43  {  {
44          m_iMidiMap = LSCP_MIDI_MAP_ALL;          m_iMidiMap = LSCP_MIDI_MAP_ALL;
45    
46            QAbstractItemModel::reset();
47  }  }
48    
49    InstrumentListModel::~InstrumentListModel (void)
50    {
51            clear();
52    }
53    
54  int MidiInstrumentsModel::rowCount ( const QModelIndex& /*parent*/) const  
55    int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const
56  {  {
57            int nrows = 0;
58    
59          if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {          if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
60                  int n = 0;                  InstrumentMap::const_iterator itMap = m_instruments.constBegin();
61                  for (InstrumentsMap::const_iterator itMap = m_instruments.begin();                  for ( ; itMap != m_instruments.constEnd(); ++itMap)
62                                  itMap != m_instruments.end(); ++itMap)                          nrows += (*itMap).size();
63                          n += (*itMap).size();          } else {
64                  return n;                  InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
65                    if (itMap != m_instruments.constEnd())
66                            nrows += (*itMap).size();
67          }          }
68          InstrumentsMap::const_iterator itMap = m_instruments.find(m_iMidiMap);  
69          if (itMap == m_instruments.end()) return 0;          return nrows;
         return (*itMap).size();  
70  }  }
71    
72    
73  int MidiInstrumentsModel::columnCount ( const QModelIndex& /*parent*/) const  int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const
74  {  {
75          return 9;          return 9;
76  }  }
77    
78    
79  QVariant MidiInstrumentsModel::data ( const QModelIndex &index, int role ) const  QVariant InstrumentListModel::data (
80            const QModelIndex &index, int role ) const
81  {  {
82          if (!index.isValid())          if (!index.isValid())
83                  return QVariant();                  return QVariant();
84    
85          const Instrument* pInstr = NULL;          const Instrument *pInstr
86                    = static_cast<Instrument *> (index.internalPointer());
87    
88          if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {          if (pInstr && role == Qt::DisplayRole) {
                 int n = 0;  
                 for (InstrumentsMap::const_iterator itMap = m_instruments.begin();  
                                 itMap != m_instruments.end(); ++itMap) {  
                         n += (*itMap).size();  
                         if (index.row() < n) {  
                                 pInstr = &(*itMap)[index.row() + (*itMap).size() - n];  
                                 break;  
                         }  
                 }  
         } else {  
                 // resolve MIDI instrument map  
                 InstrumentsMap::const_iterator itMap = m_instruments.find(m_iMidiMap);  
                 if (itMap == m_instruments.end()) return QVariant();  
                 // resolve instrument in that map  
                 if (index.row() >= (*itMap).size()) return QVariant();  
                 pInstr = &(*itMap)[index.row()];  
         }  
   
         if (!pInstr)  
                 return QVariant();  
   
         if (role == Qt::UserRole)  
                 return QVariant::fromValue((void *) pInstr);  
   
         if (role == Qt::DisplayRole) {  
89                  switch (index.column()) {                  switch (index.column()) {
90                          case 0: return pInstr->name();                          case 0: return pInstr->name();
91                          case 1: return QVariant::fromValue(pInstr->map());                          case 1: return QVariant::fromValue(pInstr->map());
# Line 128  QVariant MidiInstrumentsModel::data ( co Line 97  QVariant MidiInstrumentsModel::data ( co
97                          case 7: return QString::number(pInstr->volume() * 100.0) + " %";                          case 7: return QString::number(pInstr->volume() * 100.0) + " %";
98                          case 8: {                          case 8: {
99                                  switch (pInstr->loadMode()) {                                  switch (pInstr->loadMode()) {
100                                          case 3: return QObject::tr("Persistent");                                          case 3: return tr("Persistent");
101                                          case 2: return QObject::tr("On Demand Hold");                                          case 2: return tr("On Demand Hold");
102                                          case 1: return QObject::tr("On Demand");                                          case 1: return tr("On Demand");
103                                  }                                  }
104                          }                          }
105                          default: return QVariant();                          default:
106                                    break;
107                  }                  }
108          }          }
109    
# Line 141  QVariant MidiInstrumentsModel::data ( co Line 111  QVariant MidiInstrumentsModel::data ( co
111  }  }
112    
113    
114  QVariant MidiInstrumentsModel::headerData (  QModelIndex InstrumentListModel::index (
115          int section, Qt::Orientation orientation, int role ) const          int row, int col, const QModelIndex& /*parent*/ ) const
116  {  {
117          if (orientation != Qt::Horizontal || role != Qt::DisplayRole)          const Instrument *pInstr = NULL;
                 return QVariant();  
118    
119          switch (section) {          if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
120                  case 0: return tr("Name");                  int nrows = 0;
121                  case 1: return tr("Map");                  InstrumentMap::const_iterator itMap = m_instruments.constBegin();
122                  case 2: return tr("Bank");                  for ( ; itMap != m_instruments.constEnd(); ++itMap) {
123                  case 3: return tr("Prog");                          const InstrumentList& list = *itMap;
124                  case 4: return tr("Engine");                          nrows += list.size();
125                  case 5: return tr("File");                          if (row < nrows) {
126                  case 6: return tr("Nr");                                  pInstr = list.at(row + list.size() - nrows);
127                  case 7: return tr("Vol");                                  break;
128                  case 8: return tr("Mode");                          }
129                  default: return QVariant();                  }
130            } else {
131                    // Resolve MIDI instrument map...
132                    InstrumentMap::const_iterator itMap     = m_instruments.find(m_iMidiMap);
133                    if (itMap != m_instruments.constEnd()) {
134                            const InstrumentList& list = *itMap;
135                            // resolve instrument in that map
136                            if (row < list.size())
137                                    pInstr = list.at(row);
138                    }
139            }
140    
141            if (pInstr)
142                    return createIndex(row, col, (void *) pInstr);
143            else
144                    return QModelIndex();
145    }
146    
147    
148    QModelIndex InstrumentListModel::parent ( const QModelIndex& child ) const
149    {
150            return QModelIndex();
151    }
152    
153    
154    QVariant InstrumentListModel::headerData (
155            int section, Qt::Orientation orientation, int role ) const
156    {
157            if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
158                    switch (section) {
159                            case 0: return tr("Name");
160                            case 1: return tr("Map");
161                            case 2: return tr("Bank");
162                            case 3: return tr("Prog");
163                            case 4: return tr("Engine");
164                            case 5: return tr("File");
165                            case 6: return tr("Nr");
166                            case 7: return tr("Vol");
167                            case 8: return tr("Mode");
168                    }
169          }          }
170    
171            return QAbstractItemModel::headerData(section, orientation, role);
172    }
173    
174    
175    void InstrumentListModel::setMidiMap ( int iMidiMap )
176    {
177            if (iMidiMap < 0)
178                    iMidiMap = LSCP_MIDI_MAP_ALL;
179    
180            m_iMidiMap = iMidiMap;
181  }  }
182    
183    
184  Instrument* MidiInstrumentsModel::addInstrument (  int InstrumentListModel::midiMap (void) const
185    {
186            return m_iMidiMap;
187    }
188    
189    
190    const Instrument *InstrumentListModel::addInstrument (
191          int iMap, int iBank, int iProg )          int iMap, int iBank, int iProg )
192  {  {
193          // Check it there's already one instrument item          // Check it there's already one instrument item
194          // with the very same key (bank, program);          // with the very same key (bank, program);
195          // if yes, just remove it without prejudice...          // if yes, just remove it without prejudice...
196          for (int i = 0; i < m_instruments[iMap].size(); i++) {          InstrumentList& list = m_instruments[iMap];
197                  if (m_instruments[iMap][i].bank() == iBank &&          for (int i = 0; i < list.size(); ++i) {
198                          m_instruments[iMap][i].prog() == iProg) {                  const Instrument *pInstr = list.at(i);
199                          m_instruments[iMap].removeAt(i);                  if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
200                            delete pInstr;
201                            list.removeAt(i);
202                          break;                          break;
203                  }                  }
204          }          }
205    
206          // Resolve the appropriate place, we keep the list sorted that way ...          // Resolve the appropriate place, we keep the list sorted that way...
207          int i = 0;          int i = 0;
208          for (; i < m_instruments[iMap].size(); ++i) {          for ( ; i < list.size(); ++i) {
209                  if (iBank < m_instruments[iMap][i].bank()                  const Instrument *pInstr = list.at(i);
210                          || (iBank == m_instruments[iMap][i].bank() &&                  if (iBank < pInstr->bank()
211                                  iProg < m_instruments[iMap][i].prog())) {                          || (iBank == pInstr->bank() && iProg < pInstr->prog())) {
212                          break;                          break;
213                  }                  }
214          }          }
215    
216          m_instruments[iMap].insert(i, Instrument(iMap, iBank, iProg));          Instrument *pInstr = new Instrument(iMap, iBank, iProg);
217          Instrument& instr = m_instruments[iMap][i];          if (pInstr->getInstrument()) {
218          if (!instr.getInstrument())                  list.insert(i, pInstr);
219                  m_instruments[iMap].removeAt(i);          } else {
220                    delete pInstr;
221                    pInstr = NULL;
222            }
223    
224          return &instr;          return pInstr;
225  }  }
226    
227    
228  void MidiInstrumentsModel::removeInstrument (  void InstrumentListModel::removeInstrument ( const Instrument *pInstrument )
         const Instrument& instrument )  
229  {  {
230          const int iMap  = instrument.map();          const int iMap  = pInstrument->map();
231          const int iBank = instrument.bank();          const int iBank = pInstrument->bank();
232          const int iProg = instrument.prog();          const int iProg = pInstrument->prog();
233          for (int i = 0; i < m_instruments[iMap].size(); i++) {  
234                  if (m_instruments[iMap][i].bank() == iBank &&          if (m_instruments.contains(iMap)) {
235                          m_instruments[iMap][i].prog() == iProg) {                  InstrumentList& list = m_instruments[iMap];
236                          m_instruments[iMap].removeAt(i);                  for (int i = 0; i < list.size(); ++i) {
237                          break;                          const Instrument *pInstr = list.at(i);
238                            if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
239                                    delete pInstr;
240                                    list.removeAt(i);
241                                    break;
242                            }
243                  }                  }
244          }          }
245  }  }
246    
247    
248  // Reposition the instrument in the model (called when map/bank/prg changed)  // Reposition the instrument in the model (called when map/bank/prg changed)
249  void MidiInstrumentsModel::resort ( const Instrument& instrument )  void InstrumentListModel::updateInstrument ( const Instrument *pInstrument )
250  {  {
251          const int iMap  = instrument.map();          const int iMap  = pInstrument->map();
252          const int iBank = instrument.bank();          const int iBank = pInstrument->bank();
253          const int iProg = instrument.prog();          const int iProg = pInstrument->prog();
         // Remove given instrument from its current list  
         removeInstrument(instrument);  
         // Re-add the instrument  
         addInstrument(iMap, iBank, iProg);  
 }  
254    
255            // Remove given instrument from its current list...
256            removeInstrument(pInstrument);
257    
258  void MidiInstrumentsModel::setMidiMap ( int iMidiMap )          // Re-add the instrument...
259  {          addInstrument(iMap, iBank, iProg);
         if (iMidiMap < 0)  
                 iMidiMap = LSCP_MIDI_MAP_ALL;  
   
         m_iMidiMap = iMidiMap;  
260  }  }
261    
262    
263  int MidiInstrumentsModel::midiMap (void) const  void InstrumentListModel::refresh (void)
 {  
         return m_iMidiMap;  
 }  
   
 void MidiInstrumentsModel::refresh (void)  
264  {  {
265          m_instruments.clear();          MainForm *pMainForm = MainForm::getInstance();
   
         MainForm* pMainForm = MainForm::getInstance();  
266          if (pMainForm == NULL)          if (pMainForm == NULL)
267                  return;                  return;
268          if (pMainForm->client() == NULL)          if (pMainForm->client() == NULL)
# Line 250  void MidiInstrumentsModel::refresh (void Line 270  void MidiInstrumentsModel::refresh (void
270    
271          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
272    
273            clear();
274    
275          // Load the whole bunch of instrument items...          // Load the whole bunch of instrument items...
276          lscp_midi_instrument_t* pInstrs          lscp_midi_instrument_t *pInstrs
277                  = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);                  = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
278          for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {          for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
279                  const int iMap  = pInstrs[iInstr].map;                  const int iMap  = pInstrs[iInstr].map;
# Line 269  void MidiInstrumentsModel::refresh (void Line 291  void MidiInstrumentsModel::refresh (void
291                  pMainForm->appendMessagesError(                  pMainForm->appendMessagesError(
292                          tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));                          tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
293          }          }
294    }
295    
296    void InstrumentListModel::beginReset (void)
297    {
298    #if QT_VERSION >= 0x040600
299            QAbstractItemModel::beginResetModel();
300    #endif
301    }
302    
303    void InstrumentListModel::endReset (void)
304    {
305    #if QT_VERSION >= 0x040600
306            QAbstractItemModel::endResetModel();
307    #else
308            QAbstractItemModel::reset();
309    #endif
310    }
311    
312    
313    // Map clear.
314    void InstrumentListModel::clear (void)
315    {
316            InstrumentMap::iterator itMap = m_instruments.begin();
317            for ( ; itMap != m_instruments.end(); ++itMap) {
318                    InstrumentList& list = itMap.value();
319                    qDeleteAll(list);
320                    list.clear();
321            }
322    
323          // inform the outer world (QTableView) that our data changed          m_instruments.clear();
         QAbstractTableModel::reset();  
324  }  }
325    
326    
327  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
328  // QSampler::MidiInstrumentsDelegate - table cell renderer for MIDI prog  // QSampler::InstrumentListView - list view for MIDI prog mappings
329  // mappings (doesn't actually do anything ATM, but is already there for a  //
330  // future cell editor widget implementation)  
331    // Constructor.
332    InstrumentListView::InstrumentListView ( QWidget *pParent )
333            : QTreeView(pParent)
334    {
335            m_pListModel = new InstrumentListModel(this);
336    
337            QTreeView::setModel(m_pListModel);
338    }
339    
340    
341  MidiInstrumentsDelegate::MidiInstrumentsDelegate ( QObject* pParent )  // Destructor.
342          : QItemDelegate(pParent)  InstrumentListView::~InstrumentListView (void)
343  {  {
344            delete m_pListModel;
345  }  }
346    
347    
348  QWidget* MidiInstrumentsDelegate::createEditor ( QWidget* pParent,  void InstrumentListView::setMidiMap ( int iMidiMap )
         const QStyleOptionViewItem& option, const QModelIndex& index ) const  
349  {  {
350          return QItemDelegate::createEditor(pParent, option, index);          m_pListModel->setMidiMap(iMidiMap);
 //      return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);  
351  }  }
352    
353    
354  void MidiInstrumentsDelegate::setEditorData ( QWidget */*pEditor*/,  int InstrumentListView::midiMap (void) const
355          const QModelIndex& /*index*/) const  {
356            return m_pListModel->midiMap();
357    }
358    
359    
360    const Instrument *InstrumentListView::addInstrument (
361            int iMap, int iBank, int iProg )
362  {  {
363            m_pListModel->beginReset();
364            const Instrument *pInstrument
365                    = m_pListModel->addInstrument(iMap, iBank, iProg);
366            m_pListModel->endReset();
367    
368            return pInstrument;
369  }  }
370    
371    
372  void MidiInstrumentsDelegate::setModelData ( QWidget */*pEditor*/,  void InstrumentListView::removeInstrument ( const Instrument *pInstrument )
         QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const  
373  {  {
374            m_pListModel->beginReset();
375            m_pListModel->removeInstrument(pInstrument);
376            m_pListModel->endReset();
377  }  }
378    
379    
380  void MidiInstrumentsDelegate::updateEditorGeometry ( QWidget *pEditor,  // Reposition the instrument in the model (called when map/bank/prg changed)
381          const QStyleOptionViewItem& option, const QModelIndex& index) const  void InstrumentListView::updateInstrument ( const Instrument *pInstrument )
382  {  {
383          QItemDelegate::updateEditorGeometry(pEditor, option, index);          m_pListModel->beginReset();
384  //      if (pEditor) pEditor->setGeometry(option.rect);          m_pListModel->updateInstrument(pInstrument);
385            m_pListModel->endReset();}
386    
387    
388    // Refreshener.
389    void InstrumentListView::refresh (void)
390    {
391            m_pListModel->beginReset();
392            m_pListModel->refresh();
393            m_pListModel->endReset();
394  }  }
395    
396    
397    } // namespace QSampler
398    
399    
400  // end of qsamplerInstrumentList.cpp  // end of qsamplerInstrumentList.cpp

Legend:
Removed from v.1558  
changed lines
  Added in v.2064

  ViewVC Help
Powered by ViewVC