/[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 1499 by capela, Tue Nov 20 16:48:04 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>  
34    
35  #ifndef CONFIG_ROUND  namespace QSampler {
36  static inline long lroundf ( float x )  
37    //-------------------------------------------------------------------------
38    // QSampler::InstrumentListModel - data model for MIDI prog mappings
39    //
40    
41    InstrumentListModel::InstrumentListModel ( QObject *pParent )
42            : QAbstractItemModel(pParent)
43    {
44            m_iMidiMap = LSCP_MIDI_MAP_ALL;
45    
46            QAbstractItemModel::reset();
47    }
48    
49    InstrumentListModel::~InstrumentListModel (void)
50    {
51            clear();
52    }
53    
54    
55    int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const
56    {
57            int nrows = 0;
58    
59            if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
60                    InstrumentMap::const_iterator itMap = m_instruments.constBegin();
61                    for ( ; itMap != m_instruments.constEnd(); ++itMap)
62                            nrows += (*itMap).size();
63            } else {
64                    InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
65                    if (itMap != m_instruments.constEnd())
66                            nrows += (*itMap).size();
67            }
68    
69            return nrows;
70    }
71    
72    
73    int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const
74    {
75            return 9;
76    }
77    
78    
79    QVariant InstrumentListModel::data (
80            const QModelIndex &index, int role ) const
81    {
82            if (!index.isValid())
83                    return QVariant();
84    
85            const Instrument *pInstr
86                    = static_cast<Instrument *> (index.internalPointer());
87    
88            if (pInstr && role == Qt::DisplayRole) {
89                    switch (index.column()) {
90                            case 0: return pInstr->name();
91                            case 1: return QVariant::fromValue(pInstr->map());
92                            case 2: return QVariant::fromValue(pInstr->bank());
93                            case 3: return QVariant::fromValue(pInstr->prog() + 1);
94                            case 4: return pInstr->engineName();
95                            case 5: return pInstr->instrumentFile();
96                            case 6: return QVariant::fromValue(pInstr->instrumentNr());
97                            case 7: return QString::number(pInstr->volume() * 100.0) + " %";
98                            case 8: {
99                                    switch (pInstr->loadMode()) {
100                                            case 3: return tr("Persistent");
101                                            case 2: return tr("On Demand Hold");
102                                            case 1: return tr("On Demand");
103                                    }
104                            }
105                            default:
106                                    break;
107                    }
108            }
109    
110            return QVariant();
111    }
112    
113    
114    QModelIndex InstrumentListModel::index (
115            int row, int col, const QModelIndex& /*parent*/ ) const
116  {  {
117          if (x >= 0.0f)          const Instrument *pInstr = NULL;
118                  return long(x + 0.5f);  
119            if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
120                    int nrows = 0;
121                    InstrumentMap::const_iterator itMap = m_instruments.constBegin();
122                    for ( ; itMap != m_instruments.constEnd(); ++itMap) {
123                            const InstrumentList& list = *itMap;
124                            nrows += list.size();
125                            if (row < nrows) {
126                                    pInstr = list.at(row + list.size() - nrows);
127                                    break;
128                            }
129                    }
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          else
144                  return long(x - 0.5f);                  return QModelIndex();
145  }  }
 #endif  
146    
 using namespace QSampler;  
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    int InstrumentListModel::midiMap (void) const
185    {
186            return m_iMidiMap;
187    }
188    
 //-------------------------------------------------------------------------  
 // MidiInstrumentsModel - data model for MIDI prog mappings (used for QTableView)  
 //  
189    
190  MidiInstrumentsModel::MidiInstrumentsModel(QObject* parent) : QAbstractTableModel(parent) {  const Instrument *InstrumentListModel::addInstrument (
191      m_iMidiMap = LSCP_MIDI_MAP_ALL;          int iMap, int iBank, int iProg )
192    {
193            // Check it there's already one instrument item
194            // with the very same key (bank, program);
195            // if yes, just remove it without prejudice...
196            InstrumentList& list = m_instruments[iMap];
197            for (int i = 0; i < list.size(); ++i) {
198                    const Instrument *pInstr = list.at(i);
199                    if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
200                            delete pInstr;
201                            list.removeAt(i);
202                            break;
203                    }
204            }
205    
206            // Resolve the appropriate place, we keep the list sorted that way...
207            int i = 0;
208            for ( ; i < list.size(); ++i) {
209                    const Instrument *pInstr = list.at(i);
210                    if (iBank < pInstr->bank()
211                            || (iBank == pInstr->bank() && iProg < pInstr->prog())) {
212                            break;
213                    }
214            }
215    
216            Instrument *pInstr = new Instrument(iMap, iBank, iProg);
217            if (pInstr->getInstrument()) {
218                    list.insert(i, pInstr);
219            } else {
220                    delete pInstr;
221                    pInstr = NULL;
222            }
223    
224            return pInstr;
225  }  }
226    
227  int MidiInstrumentsModel::rowCount(const QModelIndex& /*parent*/) const {  
228      if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {  void InstrumentListModel::removeInstrument ( const Instrument *pInstrument )
229          int n = 0;  {
230          for (InstrumentsMap::const_iterator itMap = instruments.begin(); itMap != instruments.end(); ++itMap)          const int iMap  = pInstrument->map();
231              n += (*itMap).size();          const int iBank = pInstrument->bank();
232          return n;          const int iProg = pInstrument->prog();
233      }  
234      InstrumentsMap::const_iterator itMap = instruments.find(m_iMidiMap);          if (m_instruments.contains(iMap)) {
235      if (itMap == instruments.end()) return 0;                  InstrumentList& list = m_instruments[iMap];
236      return (*itMap).size();                  for (int i = 0; i < list.size(); ++i) {
237  }                          const Instrument *pInstr = list.at(i);
238                            if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
239  int MidiInstrumentsModel::columnCount(const QModelIndex& /*parent*/) const {                                  delete pInstr;
240      return 9;                                  list.removeAt(i);
241  }                                  break;
242                            }
243  QVariant MidiInstrumentsModel::data(const QModelIndex &index, int role) const {                  }
244      if (!index.isValid()) return QVariant();          }
   
     const qsamplerInstrument* pInstr = NULL;  
   
     if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {  
         int n = 0;  
         for (InstrumentsMap::const_iterator itMap = instruments.begin(); itMap != instruments.end(); ++itMap) {  
             n += (*itMap).size();  
             if (index.row() < n)  
                 pInstr = &(*itMap)[index.row() + (*itMap).size() - n];  
         }  
     } else {  
         // resolve MIDI instrument map  
         InstrumentsMap::const_iterator itMap = instruments.find(m_iMidiMap);  
         if (itMap == 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) {  
         switch (index.column()) {  
             case 0: return pInstr->name();  
             case 1: return QVariant::fromValue(pInstr->map());  
             case 2: return QVariant::fromValue(pInstr->bank());  
             case 3: return QVariant::fromValue(pInstr->prog());  
             case 4: return pInstr->engineName();  
             case 5: return pInstr->instrumentFile();  
             case 6: return QVariant::fromValue(pInstr->instrumentNr());  
             case 7: return QString::number(pInstr->volume() * 100.0) + " %";  
             case 8: {  
                 switch (pInstr->loadMode()) {  
                     case 3: return QObject::tr("Persistent");  
                     case 2: return QObject::tr("On Demand Hold");  
                     case 1: return QObject::tr("On Demand");  
                     default: return QVariant();  
                 }  
             }  
             default: return QVariant();  
         }  
     }  
   
     return QVariant();  
 }  
   
 QVariant MidiInstrumentsModel::headerData(int section, Qt::Orientation orientation, int role) const {  
     if (orientation != Qt::Horizontal || role != Qt::DisplayRole)  
         return QVariant();  
   
     switch (section) {  
         case 0: return tr("Name");  
         case 1: return tr("Map");  
         case 2: return tr("Bank");  
         case 3: return tr("Prog");  
         case 4: return tr("Engine");  
         case 5: return tr("File");  
         case 6: return tr("Nr");  
         case 7: return tr("Vol");  
         case 8: return tr("Mode");  
         default: return QVariant();  
     }  
 }  
   
 qsamplerInstrument* MidiInstrumentsModel::addInstrument(int iMap, int iBank, int iProg) {  
     // Check it there's already one instrument item  
     // with the very same key (bank, program);  
     // if yes, just remove it without prejudice...  
     for (int i = 0; i < instruments[iMap].size(); i++) {  
         if (  
             instruments[iMap][i].bank() == iBank &&  
             instruments[iMap][i].prog() == iProg  
         ) {  
             instruments[iMap].removeAt(i);  
             break;  
         }  
     }  
   
     // resolve the appropriate place, we keep the list sorted that way ...  
     int i = 0;  
     for (; i < instruments[iMap].size(); i++)  
         if (  
             iBank > instruments[iMap][i].bank() ||  
             ( iBank == instruments[iMap][i].bank() &&  
               iProg > instruments[iMap][i].prog() )  
         ) break;  
   
     instruments[iMap].insert(i, qsamplerInstrument(iMap, iBank, iProg));  
     qsamplerInstrument& instr = instruments[iMap][i];  
     if (!instr.getInstrument())  
         instruments[iMap].removeAt(i);  
   
     return &instr;  
 }  
   
 void MidiInstrumentsModel::removeInstrument(const qsamplerInstrument& instrument) {  
     const int iMap  = instrument.map();  
     const int iBank = instrument.bank();  
     const int iProg = instrument.prog();  
     for (int i = 0; i < instruments[iMap].size(); i++) {  
         if (  
             instruments[iMap][i].bank() == iBank &&  
             instruments[iMap][i].prog() == iProg  
         ) {  
             instruments[iMap].removeAt(i);  
             break;  
         }  
     }  
 }  
   
 // reposition the instrument in the model (called when map/bank/prg changed)  
 void MidiInstrumentsModel::resort(const qsamplerInstrument instrument) {  
     const int iMap  = instrument.map();  
     const int iBank = instrument.bank();  
     const int iProg = instrument.prog();  
     // remove given instrument from its current list  
     removeInstrument(instrument);  
     // re-add the instrument  
     addInstrument(iMap, iBank, iProg);  
 }  
   
 void MidiInstrumentsModel::setMidiMap(int iMidiMap) {  
     if (iMidiMap < 0)  
         iMidiMap = LSCP_MIDI_MAP_ALL;  
   
     m_iMidiMap = iMidiMap;  
245  }  }
246    
247  int MidiInstrumentsModel::midiMap() const {  
248      return m_iMidiMap;  // Reposition the instrument in the model (called when map/bank/prg changed)
249    void InstrumentListModel::updateInstrument ( const Instrument *pInstrument )
250    {
251            const int iMap  = pInstrument->map();
252            const int iBank = pInstrument->bank();
253            const int iProg = pInstrument->prog();
254    
255            // Remove given instrument from its current list...
256            removeInstrument(pInstrument);
257    
258            // Re-add the instrument...
259            addInstrument(iMap, iBank, iProg);
260  }  }
261    
 void MidiInstrumentsModel::refresh() {  
         instruments.clear();  
262    
263          MainForm* pMainForm = MainForm::getInstance();  void InstrumentListModel::refresh (void)
264    {
265            MainForm *pMainForm = MainForm::getInstance();
266          if (pMainForm == NULL)          if (pMainForm == NULL)
267                  return;                  return;
268          if (pMainForm->client() == NULL)          if (pMainForm->client() == NULL)
# Line 225  void MidiInstrumentsModel::refresh() { Line 270  void MidiInstrumentsModel::refresh() {
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 241  void MidiInstrumentsModel::refresh() { Line 288  void MidiInstrumentsModel::refresh() {
288    
289          if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {          if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
290                  pMainForm->appendMessagesClient("lscp_list_midi_instruments");                  pMainForm->appendMessagesClient("lscp_list_midi_instruments");
291                  pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));                  pMainForm->appendMessagesError(
292                            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  // MidiInstrumentsDelegate - table cell renderer for MIDI prog mappings  // QSampler::InstrumentListView - list view for MIDI prog mappings
329  // (doesn't actually do anything ATM, but is already there for a future  //
 // cell editor widget implementation)  
330    
331  MidiInstrumentsDelegate::MidiInstrumentsDelegate(QObject* parent) : QItemDelegate(parent) {  // 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  QWidget* MidiInstrumentsDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {  
341      return QItemDelegate::createEditor(parent, option, index);  // Destructor.
342      //return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);  InstrumentListView::~InstrumentListView (void)
343    {
344            delete m_pListModel;
345  }  }
346    
347  void MidiInstrumentsDelegate::setEditorData(QWidget* /*editor*/, const QModelIndex& /*index*/) const {  
348    void InstrumentListView::setMidiMap ( int iMidiMap )
349    {
350            m_pListModel->setMidiMap(iMidiMap);
351  }  }
352    
353  void MidiInstrumentsDelegate::setModelData(QWidget* /*editor*/, QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const {  
354    int InstrumentListView::midiMap (void) const
355    {
356            return m_pListModel->midiMap();
357  }  }
358    
359  void MidiInstrumentsDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {  
360      QItemDelegate::updateEditorGeometry(editor, option, index);  const Instrument *InstrumentListView::addInstrument (
361      //if (editor) editor->setGeometry(option.rect);          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 InstrumentListView::removeInstrument ( const Instrument *pInstrument )
373    {
374            m_pListModel->beginReset();
375            m_pListModel->removeInstrument(pInstrument);
376            m_pListModel->endReset();
377    }
378    
379    
380    // Reposition the instrument in the model (called when map/bank/prg changed)
381    void InstrumentListView::updateInstrument ( const Instrument *pInstrument )
382    {
383            m_pListModel->beginReset();
384            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.1499  
changed lines
  Added in v.2064

  ViewVC Help
Powered by ViewVC