~ubuntu-branches/ubuntu/maverick/qsampler/maverick

« back to all changes in this revision

Viewing changes to src/qsamplerInstrumentList.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2008-08-28 08:43:21 UTC
  • mfrom: (1.1.1 upstream) (2.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080828084321-guq8v04yg31co9gm
Tags: 0.2.1-1
* New upstream release
* Uploaded to Debian (Closes: #280576)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// qsamplerInstrumentList.cpp
 
2
//
 
3
/****************************************************************************
 
4
   Copyright (C) 2003-2007, 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
#include "qsamplerInstrumentForm.h"
 
28
 
 
29
#include "qsamplerOptions.h"
 
30
#include "qsamplerMainForm.h"
 
31
 
 
32
#include <QApplication>
 
33
#include <QMessageBox>
 
34
#include <QMenu>
 
35
#include <QAction>
 
36
#include <QCursor>
 
37
#include <QFileInfo>
 
38
 
 
39
// Needed for lroundf()
 
40
#include <math.h>
 
41
 
 
42
#ifndef CONFIG_ROUND
 
43
static inline long lroundf ( float x )
 
44
{
 
45
        if (x >= 0.0f)
 
46
                return long(x + 0.5f);
 
47
        else
 
48
                return long(x - 0.5f);
 
49
}
 
50
#endif
 
51
 
 
52
using namespace QSampler;
 
53
 
 
54
 
 
55
//-------------------------------------------------------------------------
 
56
// QSampler::MidiInstrumentsModel - data model for MIDI prog mappings
 
57
//                                  (used for QTableView)
 
58
 
 
59
MidiInstrumentsModel::MidiInstrumentsModel ( QObject* pParent)
 
60
        : QAbstractTableModel(pParent) 
 
61
{
 
62
        m_iMidiMap = LSCP_MIDI_MAP_ALL;
 
63
}
 
64
 
 
65
 
 
66
int MidiInstrumentsModel::rowCount ( const QModelIndex& /*parent*/) const
 
67
{
 
68
        if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
 
69
                int n = 0;
 
70
                for (InstrumentsMap::const_iterator itMap = m_instruments.begin();
 
71
                                itMap != m_instruments.end(); ++itMap)
 
72
                        n += (*itMap).size();
 
73
                return n;
 
74
        }
 
75
        InstrumentsMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
 
76
        if (itMap == m_instruments.end()) return 0;
 
77
        return (*itMap).size();
 
78
}
 
79
 
 
80
 
 
81
int MidiInstrumentsModel::columnCount ( const QModelIndex& /*parent*/) const
 
82
{
 
83
        return 9;
 
84
}
 
85
 
 
86
 
 
87
QVariant MidiInstrumentsModel::data ( const QModelIndex &index, int role ) const
 
88
{
 
89
        if (!index.isValid())
 
90
                return QVariant();
 
91
 
 
92
        const Instrument* pInstr = NULL;
 
93
 
 
94
        if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
 
95
                int n = 0;
 
96
                for (InstrumentsMap::const_iterator itMap = m_instruments.begin();
 
97
                                itMap != m_instruments.end(); ++itMap) {
 
98
                        n += (*itMap).size();
 
99
                        if (index.row() < n) {
 
100
                                pInstr = &(*itMap)[index.row() + (*itMap).size() - n];
 
101
                                break;
 
102
                        }
 
103
                }
 
104
        } else {
 
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()];
 
111
        }
 
112
 
 
113
        if (!pInstr)
 
114
                return QVariant();
 
115
 
 
116
        if (role == Qt::UserRole)
 
117
                return QVariant::fromValue((void *) pInstr);
 
118
 
 
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) + " %";
 
129
                        case 8: {
 
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");
 
134
                                }
 
135
                        }
 
136
                        default: return QVariant();
 
137
                }
 
138
        }
 
139
 
 
140
        return QVariant();
 
141
}
 
142
 
 
143
 
 
144
QVariant MidiInstrumentsModel::headerData (
 
145
        int section, Qt::Orientation orientation, int role ) const
 
146
{
 
147
        if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
 
148
                return QVariant();
 
149
 
 
150
        switch (section) {
 
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();
 
161
        }
 
162
}
 
163
 
 
164
 
 
165
Instrument* MidiInstrumentsModel::addInstrument (
 
166
        int iMap, int iBank, int iProg )
 
167
{
 
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);
 
175
                        break;
 
176
                }
 
177
        }
 
178
 
 
179
        // Resolve the appropriate place, we keep the list sorted that way ...
 
180
        int i = 0;
 
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())) {
 
185
                        break;
 
186
                }
 
187
        }
 
188
 
 
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);
 
193
 
 
194
        return &instr;
 
195
}
 
196
 
 
197
 
 
198
void MidiInstrumentsModel::removeInstrument (
 
199
        const Instrument& instrument )
 
200
{
 
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);
 
208
                        break;
 
209
                }
 
210
        }
 
211
}
 
212
 
 
213
 
 
214
// Reposition the instrument in the model (called when map/bank/prg changed)
 
215
void MidiInstrumentsModel::resort ( const Instrument& instrument )
 
216
{
 
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);
 
224
}
 
225
 
 
226
 
 
227
void MidiInstrumentsModel::setMidiMap ( int iMidiMap )
 
228
{
 
229
        if (iMidiMap < 0)
 
230
                iMidiMap = LSCP_MIDI_MAP_ALL;
 
231
 
 
232
        m_iMidiMap = iMidiMap;
 
233
}
 
234
 
 
235
 
 
236
int MidiInstrumentsModel::midiMap (void) const
 
237
{
 
238
        return m_iMidiMap;
 
239
}
 
240
 
 
241
void MidiInstrumentsModel::refresh (void)
 
242
{
 
243
        m_instruments.clear();
 
244
 
 
245
        MainForm* pMainForm = MainForm::getInstance();
 
246
        if (pMainForm == NULL)
 
247
                return;
 
248
        if (pMainForm->client() == NULL)
 
249
                return;
 
250
 
 
251
        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
252
 
 
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);
 
263
        }
 
264
 
 
265
        QApplication::restoreOverrideCursor();
 
266
 
 
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."));
 
271
        }
 
272
 
 
273
        // inform the outer world (QTableView) that our data changed
 
274
        QAbstractTableModel::reset();
 
275
}
 
276
 
 
277
 
 
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)
 
282
 
 
283
MidiInstrumentsDelegate::MidiInstrumentsDelegate ( QObject* pParent )
 
284
        : QItemDelegate(pParent)
 
285
{
 
286
}
 
287
 
 
288
 
 
289
QWidget* MidiInstrumentsDelegate::createEditor ( QWidget* pParent,
 
290
        const QStyleOptionViewItem& option, const QModelIndex& index ) const
 
291
{
 
292
        return QItemDelegate::createEditor(pParent, option, index);
 
293
//      return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);
 
294
}
 
295
 
 
296
 
 
297
void MidiInstrumentsDelegate::setEditorData ( QWidget */*pEditor*/,
 
298
        const QModelIndex& /*index*/) const
 
299
{
 
300
}
 
301
 
 
302
 
 
303
void MidiInstrumentsDelegate::setModelData ( QWidget */*pEditor*/,
 
304
        QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const
 
305
{
 
306
}
 
307
 
 
308
 
 
309
void MidiInstrumentsDelegate::updateEditorGeometry ( QWidget *pEditor,
 
310
        const QStyleOptionViewItem& option, const QModelIndex& index) const
 
311
{
 
312
        QItemDelegate::updateEditorGeometry(pEditor, option, index);
 
313
//      if (pEditor) pEditor->setGeometry(option.rect);
 
314
}
 
315
 
 
316
 
 
317
// end of qsamplerInstrumentList.cpp