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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3555 - (hide annotations) (download)
Tue Aug 13 10:19:32 2019 UTC (6 months, 1 week ago) by capela
File size: 10769 byte(s)
- In late compliance to C++11, all NULL constants replaced for nullptr.
1 capela 971 // qsamplerInstrumentList.cpp
2     //
3     /****************************************************************************
4 capela 3555 Copyright (C) 2003-2019, 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 capela 2079 #include <QHeaderView>
33 capela 1499 #include <QCursor>
34 schoenebeck 1461
35 capela 971
36 capela 2064 namespace QSampler {
37 capela 971
38 schoenebeck 1492 //-------------------------------------------------------------------------
39 capela 2064 // QSampler::InstrumentListModel - data model for MIDI prog mappings
40     //
41 capela 971
42 capela 2064 InstrumentListModel::InstrumentListModel ( QObject *pParent )
43 capela 2065 : QAbstractItemModel(pParent), m_iMidiMap(LSCP_MIDI_MAP_ALL)
44 capela 1509 {
45 capela 2068 // QAbstractItemModel::reset();
46 schoenebeck 1461 }
47 capela 971
48 capela 2064 InstrumentListModel::~InstrumentListModel (void)
49     {
50     clear();
51     }
52 capela 1509
53 capela 2064
54     int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const
55 capela 1509 {
56 capela 2064 int nrows = 0;
57    
58 capela 1509 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
59 capela 2064 InstrumentMap::const_iterator itMap = m_instruments.constBegin();
60     for ( ; itMap != m_instruments.constEnd(); ++itMap)
61     nrows += (*itMap).size();
62     } else {
63     InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
64     if (itMap != m_instruments.constEnd())
65     nrows += (*itMap).size();
66 capela 1509 }
67 capela 2064
68     return nrows;
69 schoenebeck 1461 }
70    
71 capela 1509
72 capela 2064 int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const
73 capela 1509 {
74     return 9;
75 schoenebeck 1461 }
76    
77    
78 capela 2064 QVariant InstrumentListModel::data (
79     const QModelIndex &index, int role ) const
80 capela 1509 {
81     if (!index.isValid())
82     return QVariant();
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 3555 const Instrument *pInstr = nullptr;
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     if (row < list.size())
134     pInstr = list.at(row);
135     }
136 capela 1509 }
137 capela 2064
138     if (pInstr)
139     return createIndex(row, col, (void *) pInstr);
140     else
141     return QModelIndex();
142 schoenebeck 1461 }
143    
144    
145 capela 2065 QModelIndex InstrumentListModel::parent ( const QModelIndex& /*child*/ ) const
146 capela 2064 {
147     return QModelIndex();
148     }
149    
150    
151     QVariant InstrumentListModel::headerData (
152     int section, Qt::Orientation orientation, int role ) const
153     {
154     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
155     switch (section) {
156     case 0: return tr("Name");
157     case 1: return tr("Map");
158     case 2: return tr("Bank");
159     case 3: return tr("Prog");
160     case 4: return tr("Engine");
161     case 5: return tr("File");
162     case 6: return tr("Nr");
163     case 7: return tr("Vol");
164     case 8: return tr("Mode");
165     }
166     }
167    
168     return QAbstractItemModel::headerData(section, orientation, role);
169     }
170    
171    
172     void InstrumentListModel::setMidiMap ( int iMidiMap )
173     {
174     if (iMidiMap < 0)
175     iMidiMap = LSCP_MIDI_MAP_ALL;
176    
177     m_iMidiMap = iMidiMap;
178     }
179    
180    
181     int InstrumentListModel::midiMap (void) const
182     {
183     return m_iMidiMap;
184     }
185    
186    
187     const Instrument *InstrumentListModel::addInstrument (
188 capela 1509 int iMap, int iBank, int iProg )
189     {
190     // Check it there's already one instrument item
191     // with the very same key (bank, program);
192     // if yes, just remove it without prejudice...
193 capela 2064 InstrumentList& list = m_instruments[iMap];
194 capela 2071
195     int i = 0;
196     for ( ; i < list.size(); ++i) {
197 capela 2064 const Instrument *pInstr = list.at(i);
198     if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
199     delete pInstr;
200     list.removeAt(i);
201 capela 1509 break;
202     }
203     }
204 schoenebeck 1461
205 capela 2064 // Resolve the appropriate place, we keep the list sorted that way...
206 capela 2071 for (i = 0; i < list.size(); ++i) {
207 capela 2064 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 capela 3555 pInstr = nullptr;
220 capela 2064 }
221 capela 1509
222 capela 2064 return pInstr;
223 schoenebeck 1461 }
224    
225 capela 1509
226 capela 2070 void InstrumentListModel::removeInstrument ( Instrument *pInstrument )
227 capela 1509 {
228 capela 2071 const int iMap = pInstrument->map();
229 capela 2064
230     if (m_instruments.contains(iMap)) {
231     InstrumentList& list = m_instruments[iMap];
232     for (int i = 0; i < list.size(); ++i) {
233 capela 2071 if (pInstrument == list.at(i)) {
234     delete pInstrument;
235 capela 2064 list.removeAt(i);
236     break;
237     }
238 capela 1509 }
239     }
240 schoenebeck 1492 }
241    
242 capela 1509
243 capela 2070 void InstrumentListModel::updateInstrument ( Instrument *pInstrument )
244     {
245     pInstrument->getInstrument();
246     }
247    
248    
249 capela 1509 // Reposition the instrument in the model (called when map/bank/prg changed)
250 capela 2070 void InstrumentListModel::resortInstrument ( Instrument *pInstrument )
251 capela 1509 {
252 capela 2064 const int iMap = pInstrument->map();
253     const int iBank = pInstrument->bank();
254     const int iProg = pInstrument->prog();
255 schoenebeck 1492
256 capela 2064 // Remove given instrument from its current list...
257     removeInstrument(pInstrument);
258 schoenebeck 1461
259 capela 2064 // Re-add the instrument...
260     addInstrument(iMap, iBank, iProg);
261 schoenebeck 1461 }
262    
263 capela 1509
264 capela 2064 void InstrumentListModel::refresh (void)
265 capela 1509 {
266 capela 2064 MainForm *pMainForm = MainForm::getInstance();
267 capela 3555 if (pMainForm == nullptr)
268 schoenebeck 1461 return;
269 capela 3555 if (pMainForm->client() == nullptr)
270 schoenebeck 1461 return;
271    
272     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
273    
274 capela 2064 clear();
275    
276 schoenebeck 1461 // Load the whole bunch of instrument items...
277 capela 2064 lscp_midi_instrument_t *pInstrs
278 schoenebeck 1461 = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
279     for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
280     const int iMap = pInstrs[iInstr].map;
281     const int iBank = pInstrs[iInstr].bank;
282     const int iProg = pInstrs[iInstr].prog;
283     addInstrument(iMap, iBank, iProg);
284     // Try to keep it snappy :)
285 capela 1499 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
286 schoenebeck 1461 }
287    
288     QApplication::restoreOverrideCursor();
289    
290 capela 3555 if (pInstrs == nullptr && ::lscp_client_get_errno(pMainForm->client())) {
291 schoenebeck 1461 pMainForm->appendMessagesClient("lscp_list_midi_instruments");
292 capela 1509 pMainForm->appendMessagesError(
293     tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
294 schoenebeck 1461 }
295 capela 2064 }
296 schoenebeck 1461
297 capela 2064 void InstrumentListModel::beginReset (void)
298     {
299 capela 3520 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
300 capela 2064 QAbstractItemModel::beginResetModel();
301     #endif
302 schoenebeck 1461 }
303    
304 capela 2064 void InstrumentListModel::endReset (void)
305     {
306 capela 3520 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
307 capela 2064 QAbstractItemModel::endResetModel();
308     #else
309     QAbstractItemModel::reset();
310     #endif
311     }
312 schoenebeck 1461
313 capela 2064
314     // Map clear.
315     void InstrumentListModel::clear (void)
316     {
317     InstrumentMap::iterator itMap = m_instruments.begin();
318     for ( ; itMap != m_instruments.end(); ++itMap) {
319     InstrumentList& list = itMap.value();
320     qDeleteAll(list);
321     list.clear();
322     }
323    
324     m_instruments.clear();
325     }
326    
327    
328 schoenebeck 1492 //-------------------------------------------------------------------------
329 capela 2064 // QSampler::InstrumentListView - list view for MIDI prog mappings
330     //
331 schoenebeck 1492
332 capela 2064 // Constructor.
333     InstrumentListView::InstrumentListView ( QWidget *pParent )
334     : QTreeView(pParent)
335 capela 1509 {
336 capela 2064 m_pListModel = new InstrumentListModel(this);
337    
338     QTreeView::setModel(m_pListModel);
339 capela 2065
340     QTreeView::setRootIsDecorated(false);
341     QTreeView::setUniformRowHeights(true);
342     QTreeView::setAlternatingRowColors(true);
343     QTreeView::setSelectionBehavior(QAbstractItemView::SelectRows);
344     QTreeView::setSelectionMode(QAbstractItemView::SingleSelection);
345 capela 2069 QTreeView::setItemsExpandable(false);
346    
347 capela 2065 QHeaderView *pHeader = QTreeView::header();
348     pHeader->setDefaultAlignment(Qt::AlignLeft);
349 capela 3520 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
350 capela 2065 pHeader->setMovable(false);
351 capela 2387 #endif
352 capela 2065 pHeader->setStretchLastSection(true);
353     pHeader->resizeSection(0, 120); // Name
354     QTreeView::resizeColumnToContents(1); // Map
355     QTreeView::resizeColumnToContents(2); // Bank
356     QTreeView::resizeColumnToContents(3); // Prog
357     QTreeView::resizeColumnToContents(4); // Engine
358     pHeader->resizeSection(5, 240); // File
359     QTreeView::resizeColumnToContents(6); // Nr
360     pHeader->resizeSection(7, 60); // Vol
361 schoenebeck 1461 }
362    
363 capela 1509
364 capela 2064 // Destructor.
365     InstrumentListView::~InstrumentListView (void)
366 capela 1509 {
367 capela 2064 delete m_pListModel;
368 schoenebeck 1461 }
369    
370 capela 1509
371 capela 2064 void InstrumentListView::setMidiMap ( int iMidiMap )
372 capela 1509 {
373 capela 2064 m_pListModel->setMidiMap(iMidiMap);
374 schoenebeck 1461 }
375    
376 capela 1509
377 capela 2064 int InstrumentListView::midiMap (void) const
378 capela 1509 {
379 capela 2064 return m_pListModel->midiMap();
380 schoenebeck 1461 }
381    
382 capela 1509
383 capela 2064 const Instrument *InstrumentListView::addInstrument (
384     int iMap, int iBank, int iProg )
385 capela 1509 {
386 capela 2064 m_pListModel->beginReset();
387     const Instrument *pInstrument
388     = m_pListModel->addInstrument(iMap, iBank, iProg);
389     m_pListModel->endReset();
390    
391     return pInstrument;
392 schoenebeck 1461 }
393    
394 capela 1464
395 capela 2070 void InstrumentListView::removeInstrument ( Instrument *pInstrument )
396 capela 2064 {
397     m_pListModel->beginReset();
398     m_pListModel->removeInstrument(pInstrument);
399     m_pListModel->endReset();
400     }
401    
402    
403 capela 2070 void InstrumentListView::updateInstrument ( Instrument *pInstrument )
404 capela 2064 {
405     m_pListModel->beginReset();
406     m_pListModel->updateInstrument(pInstrument);
407 capela 2068 m_pListModel->endReset();
408     }
409 capela 2064
410    
411 capela 2070 // Reposition the instrument in the model (called when map/bank/prg changed)
412     void InstrumentListView::resortInstrument ( Instrument *pInstrument )
413     {
414     m_pListModel->beginReset();
415     m_pListModel->resortInstrument(pInstrument);
416     m_pListModel->endReset();
417     }
418    
419    
420 capela 2064 // Refreshener.
421     void InstrumentListView::refresh (void)
422     {
423     m_pListModel->beginReset();
424     m_pListModel->refresh();
425     m_pListModel->endReset();
426     }
427    
428    
429     } // namespace QSampler
430    
431    
432 capela 971 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC