1
// qsamplerInstrumentList.cpp
3
/****************************************************************************
4
Copyright (C) 2003-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5
Copyright (C) 2007, Christian Schoenebeck
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.
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.
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.
21
*****************************************************************************/
23
#include "qsamplerAbout.h"
24
#include "qsamplerInstrumentList.h"
26
#include "qsamplerInstrument.h"
27
#include "qsamplerInstrumentForm.h"
29
#include "qsamplerOptions.h"
30
#include "qsamplerMainForm.h"
32
#include <QApplication>
33
#include <QMessageBox>
39
// Needed for lroundf()
43
static inline long lroundf ( float x )
46
return long(x + 0.5f);
48
return long(x - 0.5f);
52
using namespace QSampler;
55
//-------------------------------------------------------------------------
56
// QSampler::MidiInstrumentsModel - data model for MIDI prog mappings
57
// (used for QTableView)
59
MidiInstrumentsModel::MidiInstrumentsModel ( QObject* pParent)
60
: QAbstractTableModel(pParent)
62
m_iMidiMap = LSCP_MIDI_MAP_ALL;
66
int MidiInstrumentsModel::rowCount ( const QModelIndex& /*parent*/) const
68
if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
70
for (InstrumentsMap::const_iterator itMap = m_instruments.begin();
71
itMap != m_instruments.end(); ++itMap)
75
InstrumentsMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
76
if (itMap == m_instruments.end()) return 0;
77
return (*itMap).size();
81
int MidiInstrumentsModel::columnCount ( const QModelIndex& /*parent*/) const
87
QVariant MidiInstrumentsModel::data ( const QModelIndex &index, int role ) const
92
const Instrument* pInstr = NULL;
94
if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
96
for (InstrumentsMap::const_iterator itMap = m_instruments.begin();
97
itMap != m_instruments.end(); ++itMap) {
99
if (index.row() < n) {
100
pInstr = &(*itMap)[index.row() + (*itMap).size() - n];
105
// resolve MIDI instrument map
106
InstrumentsMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
107
if (itMap == m_instruments.end()) return QVariant();
108
// resolve instrument in that map
109
if (index.row() >= (*itMap).size()) return QVariant();
110
pInstr = &(*itMap)[index.row()];
116
if (role == Qt::UserRole)
117
return QVariant::fromValue((void *) pInstr);
119
if (role == Qt::DisplayRole) {
120
switch (index.column()) {
121
case 0: return pInstr->name();
122
case 1: return QVariant::fromValue(pInstr->map());
123
case 2: return QVariant::fromValue(pInstr->bank());
124
case 3: return QVariant::fromValue(pInstr->prog() + 1);
125
case 4: return pInstr->engineName();
126
case 5: return pInstr->instrumentFile();
127
case 6: return QVariant::fromValue(pInstr->instrumentNr());
128
case 7: return QString::number(pInstr->volume() * 100.0) + " %";
130
switch (pInstr->loadMode()) {
131
case 3: return QObject::tr("Persistent");
132
case 2: return QObject::tr("On Demand Hold");
133
case 1: return QObject::tr("On Demand");
136
default: return QVariant();
144
QVariant MidiInstrumentsModel::headerData (
145
int section, Qt::Orientation orientation, int role ) const
147
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
151
case 0: return tr("Name");
152
case 1: return tr("Map");
153
case 2: return tr("Bank");
154
case 3: return tr("Prog");
155
case 4: return tr("Engine");
156
case 5: return tr("File");
157
case 6: return tr("Nr");
158
case 7: return tr("Vol");
159
case 8: return tr("Mode");
160
default: return QVariant();
165
Instrument* MidiInstrumentsModel::addInstrument (
166
int iMap, int iBank, int iProg )
168
// Check it there's already one instrument item
169
// with the very same key (bank, program);
170
// if yes, just remove it without prejudice...
171
for (int i = 0; i < m_instruments[iMap].size(); i++) {
172
if (m_instruments[iMap][i].bank() == iBank &&
173
m_instruments[iMap][i].prog() == iProg) {
174
m_instruments[iMap].removeAt(i);
179
// Resolve the appropriate place, we keep the list sorted that way ...
181
for (; i < m_instruments[iMap].size(); ++i) {
182
if (iBank < m_instruments[iMap][i].bank()
183
|| (iBank == m_instruments[iMap][i].bank() &&
184
iProg < m_instruments[iMap][i].prog())) {
189
m_instruments[iMap].insert(i, Instrument(iMap, iBank, iProg));
190
Instrument& instr = m_instruments[iMap][i];
191
if (!instr.getInstrument())
192
m_instruments[iMap].removeAt(i);
198
void MidiInstrumentsModel::removeInstrument (
199
const Instrument& instrument )
201
const int iMap = instrument.map();
202
const int iBank = instrument.bank();
203
const int iProg = instrument.prog();
204
for (int i = 0; i < m_instruments[iMap].size(); i++) {
205
if (m_instruments[iMap][i].bank() == iBank &&
206
m_instruments[iMap][i].prog() == iProg) {
207
m_instruments[iMap].removeAt(i);
214
// Reposition the instrument in the model (called when map/bank/prg changed)
215
void MidiInstrumentsModel::resort ( const Instrument& instrument )
217
const int iMap = instrument.map();
218
const int iBank = instrument.bank();
219
const int iProg = instrument.prog();
220
// Remove given instrument from its current list
221
removeInstrument(instrument);
222
// Re-add the instrument
223
addInstrument(iMap, iBank, iProg);
227
void MidiInstrumentsModel::setMidiMap ( int iMidiMap )
230
iMidiMap = LSCP_MIDI_MAP_ALL;
232
m_iMidiMap = iMidiMap;
236
int MidiInstrumentsModel::midiMap (void) const
241
void MidiInstrumentsModel::refresh (void)
243
m_instruments.clear();
245
MainForm* pMainForm = MainForm::getInstance();
246
if (pMainForm == NULL)
248
if (pMainForm->client() == NULL)
251
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
253
// Load the whole bunch of instrument items...
254
lscp_midi_instrument_t* pInstrs
255
= ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
256
for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
257
const int iMap = pInstrs[iInstr].map;
258
const int iBank = pInstrs[iInstr].bank;
259
const int iProg = pInstrs[iInstr].prog;
260
addInstrument(iMap, iBank, iProg);
261
// Try to keep it snappy :)
262
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
265
QApplication::restoreOverrideCursor();
267
if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
268
pMainForm->appendMessagesClient("lscp_list_midi_instruments");
269
pMainForm->appendMessagesError(
270
tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
273
// inform the outer world (QTableView) that our data changed
274
QAbstractTableModel::reset();
278
//-------------------------------------------------------------------------
279
// QSampler::MidiInstrumentsDelegate - table cell renderer for MIDI prog
280
// mappings (doesn't actually do anything ATM, but is already there for a
281
// future cell editor widget implementation)
283
MidiInstrumentsDelegate::MidiInstrumentsDelegate ( QObject* pParent )
284
: QItemDelegate(pParent)
289
QWidget* MidiInstrumentsDelegate::createEditor ( QWidget* pParent,
290
const QStyleOptionViewItem& option, const QModelIndex& index ) const
292
return QItemDelegate::createEditor(pParent, option, index);
293
// return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);
297
void MidiInstrumentsDelegate::setEditorData ( QWidget */*pEditor*/,
298
const QModelIndex& /*index*/) const
303
void MidiInstrumentsDelegate::setModelData ( QWidget */*pEditor*/,
304
QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const
309
void MidiInstrumentsDelegate::updateEditorGeometry ( QWidget *pEditor,
310
const QStyleOptionViewItem& option, const QModelIndex& index) const
312
QItemDelegate::updateEditorGeometry(pEditor, option, index);
313
// if (pEditor) pEditor->setGeometry(option.rect);
317
// end of qsamplerInstrumentList.cpp