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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3555 - (show annotations) (download)
Tue Aug 13 10:19:32 2019 UTC (4 years, 7 months ago) by capela
File size: 10769 byte(s)
- In late compliance to C++11, all NULL constants replaced for nullptr.
1 // qsamplerInstrumentList.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2003-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2007, Christian Schoenebeck
6
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 #include "qsamplerOptions.h"
29 #include "qsamplerMainForm.h"
30
31 #include <QApplication>
32 #include <QHeaderView>
33 #include <QCursor>
34
35
36 namespace QSampler {
37
38 //-------------------------------------------------------------------------
39 // QSampler::InstrumentListModel - data model for MIDI prog mappings
40 //
41
42 InstrumentListModel::InstrumentListModel ( QObject *pParent )
43 : QAbstractItemModel(pParent), m_iMidiMap(LSCP_MIDI_MAP_ALL)
44 {
45 // QAbstractItemModel::reset();
46 }
47
48 InstrumentListModel::~InstrumentListModel (void)
49 {
50 clear();
51 }
52
53
54 int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const
55 {
56 int nrows = 0;
57
58 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
59 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 }
67
68 return nrows;
69 }
70
71
72 int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const
73 {
74 return 9;
75 }
76
77
78 QVariant InstrumentListModel::data (
79 const QModelIndex &index, int role ) const
80 {
81 if (!index.isValid())
82 return QVariant();
83 const Instrument *pInstr
84 = static_cast<Instrument *> (index.internalPointer());
85
86 if (pInstr && role == Qt::DisplayRole) {
87 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 case 3: return QVariant::fromValue(pInstr->prog() + 1);
92 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 case 3: return tr("Persistent");
99 case 2: return tr("On Demand Hold");
100 case 1: return tr("On Demand");
101 }
102 }
103 default:
104 break;
105 }
106 }
107
108 return QVariant();
109 }
110
111
112 QModelIndex InstrumentListModel::index (
113 int row, int col, const QModelIndex& /*parent*/ ) const
114 {
115 const Instrument *pInstr = nullptr;
116
117 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 }
137
138 if (pInstr)
139 return createIndex(row, col, (void *) pInstr);
140 else
141 return QModelIndex();
142 }
143
144
145 QModelIndex InstrumentListModel::parent ( const QModelIndex& /*child*/ ) const
146 {
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 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 InstrumentList& list = m_instruments[iMap];
194
195 int i = 0;
196 for ( ; i < list.size(); ++i) {
197 const Instrument *pInstr = list.at(i);
198 if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
199 delete pInstr;
200 list.removeAt(i);
201 break;
202 }
203 }
204
205 // Resolve the appropriate place, we keep the list sorted that way...
206 for (i = 0; i < list.size(); ++i) {
207 const Instrument *pInstr = list.at(i);
208 if (iBank < pInstr->bank()
209 || (iBank == pInstr->bank() && iProg < pInstr->prog())) {
210 break;
211 }
212 }
213
214 Instrument *pInstr = new Instrument(iMap, iBank, iProg);
215 if (pInstr->getInstrument()) {
216 list.insert(i, pInstr);
217 } else {
218 delete pInstr;
219 pInstr = nullptr;
220 }
221
222 return pInstr;
223 }
224
225
226 void InstrumentListModel::removeInstrument ( Instrument *pInstrument )
227 {
228 const int iMap = pInstrument->map();
229
230 if (m_instruments.contains(iMap)) {
231 InstrumentList& list = m_instruments[iMap];
232 for (int i = 0; i < list.size(); ++i) {
233 if (pInstrument == list.at(i)) {
234 delete pInstrument;
235 list.removeAt(i);
236 break;
237 }
238 }
239 }
240 }
241
242
243 void InstrumentListModel::updateInstrument ( Instrument *pInstrument )
244 {
245 pInstrument->getInstrument();
246 }
247
248
249 // Reposition the instrument in the model (called when map/bank/prg changed)
250 void InstrumentListModel::resortInstrument ( Instrument *pInstrument )
251 {
252 const int iMap = pInstrument->map();
253 const int iBank = pInstrument->bank();
254 const int iProg = pInstrument->prog();
255
256 // Remove given instrument from its current list...
257 removeInstrument(pInstrument);
258
259 // Re-add the instrument...
260 addInstrument(iMap, iBank, iProg);
261 }
262
263
264 void InstrumentListModel::refresh (void)
265 {
266 MainForm *pMainForm = MainForm::getInstance();
267 if (pMainForm == nullptr)
268 return;
269 if (pMainForm->client() == nullptr)
270 return;
271
272 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
273
274 clear();
275
276 // Load the whole bunch of instrument items...
277 lscp_midi_instrument_t *pInstrs
278 = ::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 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
286 }
287
288 QApplication::restoreOverrideCursor();
289
290 if (pInstrs == nullptr && ::lscp_client_get_errno(pMainForm->client())) {
291 pMainForm->appendMessagesClient("lscp_list_midi_instruments");
292 pMainForm->appendMessagesError(
293 tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
294 }
295 }
296
297 void InstrumentListModel::beginReset (void)
298 {
299 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
300 QAbstractItemModel::beginResetModel();
301 #endif
302 }
303
304 void InstrumentListModel::endReset (void)
305 {
306 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
307 QAbstractItemModel::endResetModel();
308 #else
309 QAbstractItemModel::reset();
310 #endif
311 }
312
313
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 //-------------------------------------------------------------------------
329 // QSampler::InstrumentListView - list view for MIDI prog mappings
330 //
331
332 // Constructor.
333 InstrumentListView::InstrumentListView ( QWidget *pParent )
334 : QTreeView(pParent)
335 {
336 m_pListModel = new InstrumentListModel(this);
337
338 QTreeView::setModel(m_pListModel);
339
340 QTreeView::setRootIsDecorated(false);
341 QTreeView::setUniformRowHeights(true);
342 QTreeView::setAlternatingRowColors(true);
343 QTreeView::setSelectionBehavior(QAbstractItemView::SelectRows);
344 QTreeView::setSelectionMode(QAbstractItemView::SingleSelection);
345 QTreeView::setItemsExpandable(false);
346
347 QHeaderView *pHeader = QTreeView::header();
348 pHeader->setDefaultAlignment(Qt::AlignLeft);
349 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
350 pHeader->setMovable(false);
351 #endif
352 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 }
362
363
364 // Destructor.
365 InstrumentListView::~InstrumentListView (void)
366 {
367 delete m_pListModel;
368 }
369
370
371 void InstrumentListView::setMidiMap ( int iMidiMap )
372 {
373 m_pListModel->setMidiMap(iMidiMap);
374 }
375
376
377 int InstrumentListView::midiMap (void) const
378 {
379 return m_pListModel->midiMap();
380 }
381
382
383 const Instrument *InstrumentListView::addInstrument (
384 int iMap, int iBank, int iProg )
385 {
386 m_pListModel->beginReset();
387 const Instrument *pInstrument
388 = m_pListModel->addInstrument(iMap, iBank, iProg);
389 m_pListModel->endReset();
390
391 return pInstrument;
392 }
393
394
395 void InstrumentListView::removeInstrument ( Instrument *pInstrument )
396 {
397 m_pListModel->beginReset();
398 m_pListModel->removeInstrument(pInstrument);
399 m_pListModel->endReset();
400 }
401
402
403 void InstrumentListView::updateInstrument ( Instrument *pInstrument )
404 {
405 m_pListModel->beginReset();
406 m_pListModel->updateInstrument(pInstrument);
407 m_pListModel->endReset();
408 }
409
410
411 // 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 // 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 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC