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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1492 - (show annotations) (download)
Mon Nov 19 21:08:18 2007 UTC (13 years ago) by schoenebeck
File size: 9398 byte(s)
* Qt4 migration: finished MIDI instrument mapping dialogs, with this commit
  all the functionalities from the Qt3 version of qsampler are finally
  restored, only minor "cosmetical" things to fix now

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

  ViewVC Help
Powered by ViewVC