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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1499 - (show annotations) (download)
Tue Nov 20 16:48:04 2007 UTC (16 years, 4 months ago) by capela
File size: 9369 byte(s)
* Qt4 migration: one first step forward to kiss Qt3Support goodbye.

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 // MidiInstrumentsModel - data model for MIDI prog mappings (used for QTableView)
57 //
58
59 MidiInstrumentsModel::MidiInstrumentsModel(QObject* parent) : QAbstractTableModel(parent) {
60 m_iMidiMap = LSCP_MIDI_MAP_ALL;
61 }
62
63 int MidiInstrumentsModel::rowCount(const QModelIndex& /*parent*/) const {
64 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
65 int n = 0;
66 for (InstrumentsMap::const_iterator itMap = instruments.begin(); itMap != instruments.end(); ++itMap)
67 n += (*itMap).size();
68 return n;
69 }
70 InstrumentsMap::const_iterator itMap = instruments.find(m_iMidiMap);
71 if (itMap == instruments.end()) return 0;
72 return (*itMap).size();
73 }
74
75 int MidiInstrumentsModel::columnCount(const QModelIndex& /*parent*/) const {
76 return 9;
77 }
78
79 QVariant MidiInstrumentsModel::data(const QModelIndex &index, int role) const {
80 if (!index.isValid()) return QVariant();
81
82 const qsamplerInstrument* pInstr = NULL;
83
84 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
85 int n = 0;
86 for (InstrumentsMap::const_iterator itMap = instruments.begin(); itMap != instruments.end(); ++itMap) {
87 n += (*itMap).size();
88 if (index.row() < n)
89 pInstr = &(*itMap)[index.row() + (*itMap).size() - n];
90 }
91 } else {
92 // resolve MIDI instrument map
93 InstrumentsMap::const_iterator itMap = instruments.find(m_iMidiMap);
94 if (itMap == instruments.end()) return QVariant();
95 // resolve instrument in that map
96 if (index.row() >= (*itMap).size()) return QVariant();
97 pInstr = &(*itMap)[index.row()];
98 }
99
100 if (!pInstr) return QVariant();
101
102 if (role == Qt::UserRole) {
103 return QVariant::fromValue((void*)pInstr);
104 }
105
106 if (role == Qt::DisplayRole) {
107 switch (index.column()) {
108 case 0: return pInstr->name();
109 case 1: return QVariant::fromValue(pInstr->map());
110 case 2: return QVariant::fromValue(pInstr->bank());
111 case 3: return QVariant::fromValue(pInstr->prog());
112 case 4: return pInstr->engineName();
113 case 5: return pInstr->instrumentFile();
114 case 6: return QVariant::fromValue(pInstr->instrumentNr());
115 case 7: return QString::number(pInstr->volume() * 100.0) + " %";
116 case 8: {
117 switch (pInstr->loadMode()) {
118 case 3: return QObject::tr("Persistent");
119 case 2: return QObject::tr("On Demand Hold");
120 case 1: return QObject::tr("On Demand");
121 default: return QVariant();
122 }
123 }
124 default: return QVariant();
125 }
126 }
127
128 return QVariant();
129 }
130
131 QVariant MidiInstrumentsModel::headerData(int section, Qt::Orientation orientation, int role) const {
132 if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
133 return QVariant();
134
135 switch (section) {
136 case 0: return tr("Name");
137 case 1: return tr("Map");
138 case 2: return tr("Bank");
139 case 3: return tr("Prog");
140 case 4: return tr("Engine");
141 case 5: return tr("File");
142 case 6: return tr("Nr");
143 case 7: return tr("Vol");
144 case 8: return tr("Mode");
145 default: return QVariant();
146 }
147 }
148
149 qsamplerInstrument* MidiInstrumentsModel::addInstrument(int iMap, int iBank, int iProg) {
150 // Check it there's already one instrument item
151 // with the very same key (bank, program);
152 // if yes, just remove it without prejudice...
153 for (int i = 0; i < instruments[iMap].size(); i++) {
154 if (
155 instruments[iMap][i].bank() == iBank &&
156 instruments[iMap][i].prog() == iProg
157 ) {
158 instruments[iMap].removeAt(i);
159 break;
160 }
161 }
162
163 // resolve the appropriate place, we keep the list sorted that way ...
164 int i = 0;
165 for (; i < instruments[iMap].size(); i++)
166 if (
167 iBank > instruments[iMap][i].bank() ||
168 ( iBank == instruments[iMap][i].bank() &&
169 iProg > instruments[iMap][i].prog() )
170 ) break;
171
172 instruments[iMap].insert(i, qsamplerInstrument(iMap, iBank, iProg));
173 qsamplerInstrument& instr = instruments[iMap][i];
174 if (!instr.getInstrument())
175 instruments[iMap].removeAt(i);
176
177 return &instr;
178 }
179
180 void MidiInstrumentsModel::removeInstrument(const qsamplerInstrument& instrument) {
181 const int iMap = instrument.map();
182 const int iBank = instrument.bank();
183 const int iProg = instrument.prog();
184 for (int i = 0; i < instruments[iMap].size(); i++) {
185 if (
186 instruments[iMap][i].bank() == iBank &&
187 instruments[iMap][i].prog() == iProg
188 ) {
189 instruments[iMap].removeAt(i);
190 break;
191 }
192 }
193 }
194
195 // reposition the instrument in the model (called when map/bank/prg changed)
196 void MidiInstrumentsModel::resort(const qsamplerInstrument instrument) {
197 const int iMap = instrument.map();
198 const int iBank = instrument.bank();
199 const int iProg = instrument.prog();
200 // remove given instrument from its current list
201 removeInstrument(instrument);
202 // re-add the instrument
203 addInstrument(iMap, iBank, iProg);
204 }
205
206 void MidiInstrumentsModel::setMidiMap(int iMidiMap) {
207 if (iMidiMap < 0)
208 iMidiMap = LSCP_MIDI_MAP_ALL;
209
210 m_iMidiMap = iMidiMap;
211 }
212
213 int MidiInstrumentsModel::midiMap() const {
214 return m_iMidiMap;
215 }
216
217 void MidiInstrumentsModel::refresh() {
218 instruments.clear();
219
220 MainForm* pMainForm = MainForm::getInstance();
221 if (pMainForm == NULL)
222 return;
223 if (pMainForm->client() == NULL)
224 return;
225
226 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
227
228 // Load the whole bunch of instrument items...
229 lscp_midi_instrument_t* pInstrs
230 = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
231 for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
232 const int iMap = pInstrs[iInstr].map;
233 const int iBank = pInstrs[iInstr].bank;
234 const int iProg = pInstrs[iInstr].prog;
235 addInstrument(iMap, iBank, iProg);
236 // Try to keep it snappy :)
237 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
238 }
239
240 QApplication::restoreOverrideCursor();
241
242 if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
243 pMainForm->appendMessagesClient("lscp_list_midi_instruments");
244 pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
245 }
246
247 // inform the outer world (QTableView) that our data changed
248 QAbstractTableModel::reset();
249 }
250
251
252 //-------------------------------------------------------------------------
253 // MidiInstrumentsDelegate - table cell renderer for MIDI prog mappings
254 // (doesn't actually do anything ATM, but is already there for a future
255 // cell editor widget implementation)
256
257 MidiInstrumentsDelegate::MidiInstrumentsDelegate(QObject* parent) : QItemDelegate(parent) {
258 }
259
260 QWidget* MidiInstrumentsDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
261 return QItemDelegate::createEditor(parent, option, index);
262 //return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);
263 }
264
265 void MidiInstrumentsDelegate::setEditorData(QWidget* /*editor*/, const QModelIndex& /*index*/) const {
266 }
267
268 void MidiInstrumentsDelegate::setModelData(QWidget* /*editor*/, QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const {
269 }
270
271 void MidiInstrumentsDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
272 QItemDelegate::updateEditorGeometry(editor, option, index);
273 //if (editor) editor->setGeometry(option.rect);
274 }
275
276
277 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC