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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2065 - (hide annotations) (download)
Sat Mar 13 12:44:15 2010 UTC (9 years, 11 months ago) by capela
File size: 10528 byte(s)
* Automatic crash-dump reports, debugger stack-traces (gdb), back-
  traces, whatever, are being introduced as a brand new configure
  option (--enable-stacktrace) and default enabled on debug build
  targets (--enable-debug).

1 capela 971 // qsamplerInstrumentList.cpp
2     //
3     /****************************************************************************
4 capela 2064 Copyright (C) 2003-2010, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 1464 Copyright (C) 2007, Christian Schoenebeck
6 capela 971
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 2
10     of the License, or (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21     *****************************************************************************/
22    
23     #include "qsamplerAbout.h"
24     #include "qsamplerInstrumentList.h"
25    
26     #include "qsamplerInstrument.h"
27    
28 capela 987 #include "qsamplerOptions.h"
29 capela 971 #include "qsamplerMainForm.h"
30    
31 capela 1499 #include <QApplication>
32     #include <QCursor>
33 schoenebeck 1461
34 capela 971
35 capela 2064 namespace QSampler {
36 capela 971
37 schoenebeck 1492 //-------------------------------------------------------------------------
38 capela 2064 // QSampler::InstrumentListModel - data model for MIDI prog mappings
39     //
40 capela 971
41 capela 2064 InstrumentListModel::InstrumentListModel ( QObject *pParent )
42 capela 2065 : QAbstractItemModel(pParent), m_iMidiMap(LSCP_MIDI_MAP_ALL)
43 capela 1509 {
44 capela 2064 QAbstractItemModel::reset();
45 schoenebeck 1461 }
46 capela 971
47 capela 2064 InstrumentListModel::~InstrumentListModel (void)
48     {
49     clear();
50     }
51 capela 1509
52 capela 2064
53     int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const
54 capela 1509 {
55 capela 2064 int nrows = 0;
56    
57 capela 1509 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
58 capela 2064 InstrumentMap::const_iterator itMap = m_instruments.constBegin();
59     for ( ; itMap != m_instruments.constEnd(); ++itMap)
60     nrows += (*itMap).size();
61     } else {
62     InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
63     if (itMap != m_instruments.constEnd())
64     nrows += (*itMap).size();
65 capela 1509 }
66 capela 2064
67     return nrows;
68 schoenebeck 1461 }
69    
70 capela 1509
71 capela 2064 int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const
72 capela 1509 {
73     return 9;
74 schoenebeck 1461 }
75    
76    
77 capela 2064 QVariant InstrumentListModel::data (
78     const QModelIndex &index, int role ) const
79 capela 1509 {
80     if (!index.isValid())
81     return QVariant();
82 schoenebeck 1492
83 capela 2064 const Instrument *pInstr
84     = static_cast<Instrument *> (index.internalPointer());
85 schoenebeck 1461
86 capela 2064 if (pInstr && role == Qt::DisplayRole) {
87 capela 1509 switch (index.column()) {
88     case 0: return pInstr->name();
89     case 1: return QVariant::fromValue(pInstr->map());
90     case 2: return QVariant::fromValue(pInstr->bank());
91 capela 1526 case 3: return QVariant::fromValue(pInstr->prog() + 1);
92 capela 1509 case 4: return pInstr->engineName();
93     case 5: return pInstr->instrumentFile();
94     case 6: return QVariant::fromValue(pInstr->instrumentNr());
95     case 7: return QString::number(pInstr->volume() * 100.0) + " %";
96     case 8: {
97     switch (pInstr->loadMode()) {
98 capela 2064 case 3: return tr("Persistent");
99     case 2: return tr("On Demand Hold");
100     case 1: return tr("On Demand");
101 capela 1509 }
102     }
103 capela 2064 default:
104     break;
105 capela 1509 }
106     }
107    
108     return QVariant();
109 schoenebeck 1461 }
110    
111    
112 capela 2064 QModelIndex InstrumentListModel::index (
113     int row, int col, const QModelIndex& /*parent*/ ) const
114 capela 1509 {
115 capela 2064 const Instrument *pInstr = NULL;
116 capela 1509
117 capela 2064 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
118     int nrows = 0;
119     InstrumentMap::const_iterator itMap = m_instruments.constBegin();
120     for ( ; itMap != m_instruments.constEnd(); ++itMap) {
121     const InstrumentList& list = *itMap;
122     nrows += list.size();
123     if (row < nrows) {
124     pInstr = list.at(row + list.size() - nrows);
125     break;
126     }
127     }
128     } else {
129     // Resolve MIDI instrument map...
130     InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
131     if (itMap != m_instruments.constEnd()) {
132     const InstrumentList& list = *itMap;
133     // resolve instrument in that map
134     if (row < list.size())
135     pInstr = list.at(row);
136     }
137 capela 1509 }
138 capela 2064
139     if (pInstr)
140     return createIndex(row, col, (void *) pInstr);
141     else
142     return QModelIndex();
143 schoenebeck 1461 }
144    
145    
146 capela 2065 QModelIndex InstrumentListModel::parent ( const QModelIndex& /*child*/ ) const
147 capela 2064 {
148     return QModelIndex();
149     }
150    
151    
152     QVariant InstrumentListModel::headerData (
153     int section, Qt::Orientation orientation, int role ) const
154     {
155     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
156     switch (section) {
157     case 0: return tr("Name");
158     case 1: return tr("Map");
159     case 2: return tr("Bank");
160     case 3: return tr("Prog");
161     case 4: return tr("Engine");
162     case 5: return tr("File");
163     case 6: return tr("Nr");
164     case 7: return tr("Vol");
165     case 8: return tr("Mode");
166     }
167     }
168    
169     return QAbstractItemModel::headerData(section, orientation, role);
170     }
171    
172    
173     void InstrumentListModel::setMidiMap ( int iMidiMap )
174     {
175     if (iMidiMap < 0)
176     iMidiMap = LSCP_MIDI_MAP_ALL;
177    
178     m_iMidiMap = iMidiMap;
179     }
180    
181    
182     int InstrumentListModel::midiMap (void) const
183     {
184     return m_iMidiMap;
185     }
186    
187    
188     const Instrument *InstrumentListModel::addInstrument (
189 capela 1509 int iMap, int iBank, int iProg )
190     {
191     // Check it there's already one instrument item
192     // with the very same key (bank, program);
193     // if yes, just remove it without prejudice...
194 capela 2064 InstrumentList& list = m_instruments[iMap];
195     for (int i = 0; i < list.size(); ++i) {
196     const Instrument *pInstr = list.at(i);
197     if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
198     delete pInstr;
199     list.removeAt(i);
200 capela 1509 break;
201     }
202     }
203 schoenebeck 1461
204 capela 2064 // Resolve the appropriate place, we keep the list sorted that way...
205 capela 1509 int i = 0;
206 capela 2064 for ( ; i < list.size(); ++i) {
207     const Instrument *pInstr = list.at(i);
208     if (iBank < pInstr->bank()
209     || (iBank == pInstr->bank() && iProg < pInstr->prog())) {
210 capela 1509 break;
211 capela 1523 }
212     }
213 schoenebeck 1461
214 capela 2064 Instrument *pInstr = new Instrument(iMap, iBank, iProg);
215     if (pInstr->getInstrument()) {
216     list.insert(i, pInstr);
217     } else {
218     delete pInstr;
219     pInstr = NULL;
220     }
221 capela 1509
222 capela 2064 return pInstr;
223 schoenebeck 1461 }
224    
225 capela 1509
226 capela 2064 void InstrumentListModel::removeInstrument ( const Instrument *pInstrument )
227 capela 1509 {
228 capela 2064 const int iMap = pInstrument->map();
229     const int iBank = pInstrument->bank();
230     const int iProg = pInstrument->prog();
231    
232     if (m_instruments.contains(iMap)) {
233     InstrumentList& list = m_instruments[iMap];
234     for (int i = 0; i < list.size(); ++i) {
235     const Instrument *pInstr = list.at(i);
236     if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
237     delete pInstr;
238     list.removeAt(i);
239     break;
240     }
241 capela 1509 }
242     }
243 schoenebeck 1492 }
244    
245 capela 1509
246     // Reposition the instrument in the model (called when map/bank/prg changed)
247 capela 2064 void InstrumentListModel::updateInstrument ( const Instrument *pInstrument )
248 capela 1509 {
249 capela 2064 const int iMap = pInstrument->map();
250     const int iBank = pInstrument->bank();
251     const int iProg = pInstrument->prog();
252 schoenebeck 1492
253 capela 2064 // Remove given instrument from its current list...
254     removeInstrument(pInstrument);
255 schoenebeck 1461
256 capela 2064 // Re-add the instrument...
257     addInstrument(iMap, iBank, iProg);
258 schoenebeck 1461 }
259    
260 capela 1509
261 capela 2064 void InstrumentListModel::refresh (void)
262 capela 1509 {
263 capela 2064 MainForm *pMainForm = MainForm::getInstance();
264 schoenebeck 1461 if (pMainForm == NULL)
265     return;
266     if (pMainForm->client() == NULL)
267     return;
268    
269     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
270    
271 capela 2064 clear();
272    
273 schoenebeck 1461 // Load the whole bunch of instrument items...
274 capela 2064 lscp_midi_instrument_t *pInstrs
275 schoenebeck 1461 = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
276     for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
277     const int iMap = pInstrs[iInstr].map;
278     const int iBank = pInstrs[iInstr].bank;
279     const int iProg = pInstrs[iInstr].prog;
280     addInstrument(iMap, iBank, iProg);
281     // Try to keep it snappy :)
282 capela 1499 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
283 schoenebeck 1461 }
284    
285     QApplication::restoreOverrideCursor();
286    
287     if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
288     pMainForm->appendMessagesClient("lscp_list_midi_instruments");
289 capela 1509 pMainForm->appendMessagesError(
290     tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
291 schoenebeck 1461 }
292 capela 2064 }
293 schoenebeck 1461
294 capela 2064 void InstrumentListModel::beginReset (void)
295     {
296     #if QT_VERSION >= 0x040600
297     QAbstractItemModel::beginResetModel();
298     #endif
299 schoenebeck 1461 }
300    
301 capela 2064 void InstrumentListModel::endReset (void)
302     {
303     #if QT_VERSION >= 0x040600
304     QAbstractItemModel::endResetModel();
305     #else
306     QAbstractItemModel::reset();
307     #endif
308     }
309 schoenebeck 1461
310 capela 2064
311     // Map clear.
312     void InstrumentListModel::clear (void)
313     {
314     InstrumentMap::iterator itMap = m_instruments.begin();
315     for ( ; itMap != m_instruments.end(); ++itMap) {
316     InstrumentList& list = itMap.value();
317     qDeleteAll(list);
318     list.clear();
319     }
320    
321     m_instruments.clear();
322     }
323    
324    
325 schoenebeck 1492 //-------------------------------------------------------------------------
326 capela 2064 // QSampler::InstrumentListView - list view for MIDI prog mappings
327     //
328 schoenebeck 1492
329 capela 2064 // Constructor.
330     InstrumentListView::InstrumentListView ( QWidget *pParent )
331     : QTreeView(pParent)
332 capela 1509 {
333 capela 2064 m_pListModel = new InstrumentListModel(this);
334    
335     QTreeView::setModel(m_pListModel);
336 capela 2065
337     QTreeView::setRootIsDecorated(false);
338     QTreeView::setUniformRowHeights(true);
339     QTreeView::setAlternatingRowColors(true);
340     QTreeView::setSelectionBehavior(QAbstractItemView::SelectRows);
341     QTreeView::setSelectionMode(QAbstractItemView::SingleSelection);
342    
343     QHeaderView *pHeader = QTreeView::header();
344     pHeader->setDefaultAlignment(Qt::AlignLeft);
345     pHeader->setMovable(false);
346     pHeader->setStretchLastSection(true);
347     pHeader->resizeSection(0, 120); // Name
348     QTreeView::resizeColumnToContents(1); // Map
349     QTreeView::resizeColumnToContents(2); // Bank
350     QTreeView::resizeColumnToContents(3); // Prog
351     QTreeView::resizeColumnToContents(4); // Engine
352     pHeader->resizeSection(5, 240); // File
353     QTreeView::resizeColumnToContents(6); // Nr
354     pHeader->resizeSection(7, 60); // Vol
355 schoenebeck 1461 }
356    
357 capela 1509
358 capela 2064 // Destructor.
359     InstrumentListView::~InstrumentListView (void)
360 capela 1509 {
361 capela 2064 delete m_pListModel;
362 schoenebeck 1461 }
363    
364 capela 1509
365 capela 2064 void InstrumentListView::setMidiMap ( int iMidiMap )
366 capela 1509 {
367 capela 2064 m_pListModel->setMidiMap(iMidiMap);
368 schoenebeck 1461 }
369    
370 capela 1509
371 capela 2064 int InstrumentListView::midiMap (void) const
372 capela 1509 {
373 capela 2064 return m_pListModel->midiMap();
374 schoenebeck 1461 }
375    
376 capela 1509
377 capela 2064 const Instrument *InstrumentListView::addInstrument (
378     int iMap, int iBank, int iProg )
379 capela 1509 {
380 capela 2064 m_pListModel->beginReset();
381     const Instrument *pInstrument
382     = m_pListModel->addInstrument(iMap, iBank, iProg);
383     m_pListModel->endReset();
384    
385     return pInstrument;
386 schoenebeck 1461 }
387    
388 capela 1464
389 capela 2064 void InstrumentListView::removeInstrument ( const Instrument *pInstrument )
390     {
391     m_pListModel->beginReset();
392     m_pListModel->removeInstrument(pInstrument);
393     m_pListModel->endReset();
394     }
395    
396    
397     // Reposition the instrument in the model (called when map/bank/prg changed)
398     void InstrumentListView::updateInstrument ( const Instrument *pInstrument )
399     {
400     m_pListModel->beginReset();
401     m_pListModel->updateInstrument(pInstrument);
402     m_pListModel->endReset();}
403    
404    
405     // Refreshener.
406     void InstrumentListView::refresh (void)
407     {
408     m_pListModel->beginReset();
409     m_pListModel->refresh();
410     m_pListModel->endReset();
411     }
412    
413    
414     } // namespace QSampler
415    
416    
417 capela 971 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC