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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1523 - (show annotations) (download)
Sun Nov 25 11:40:47 2007 UTC (16 years, 4 months ago) by capela
File size: 8809 byte(s)
* Qt4 migration: fixed instrument map list sorting.

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

  ViewVC Help
Powered by ViewVC