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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1526 - (hide annotations) (download)
Mon Nov 26 10:58:23 2007 UTC (16 years, 4 months ago) by capela
File size: 8798 byte(s)
* Fixed crash on (All) instrument map list; instrument program number
  list display fix (off by one); header section
  widths are now arranged as in the Qt3 version.

1 capela 971 // qsamplerInstrumentList.cpp
2     //
3     /****************************************************************************
4 capela 1013 Copyright (C) 2003-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 1464 Copyright (C) 2007, Christian Schoenebeck
6 capela 971
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 capela 987 #include "qsamplerOptions.h"
30 capela 971 #include "qsamplerMainForm.h"
31    
32 capela 1499 #include <QApplication>
33     #include <QMessageBox>
34 schoenebeck 1461 #include <QMenu>
35 capela 1499 #include <QAction>
36     #include <QCursor>
37     #include <QFileInfo>
38 schoenebeck 1461
39 capela 971 // Needed for lroundf()
40     #include <math.h>
41    
42 capela 972 #ifndef CONFIG_ROUND
43 capela 980 static inline long lroundf ( float x )
44 capela 971 {
45 capela 980 if (x >= 0.0f)
46     return long(x + 0.5f);
47     else
48     return long(x - 0.5f);
49 capela 971 }
50     #endif
51    
52 schoenebeck 1461 using namespace QSampler;
53 capela 971
54    
55 schoenebeck 1492 //-------------------------------------------------------------------------
56     // MidiInstrumentsModel - data model for MIDI prog mappings (used for QTableView)
57 capela 971 //
58    
59 capela 1509 MidiInstrumentsModel::MidiInstrumentsModel ( QObject* pParent)
60     : QAbstractTableModel(pParent)
61     {
62     m_iMidiMap = LSCP_MIDI_MAP_ALL;
63 schoenebeck 1461 }
64 capela 971
65 capela 1509
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 schoenebeck 1461 }
79    
80 capela 1509
81     int MidiInstrumentsModel::columnCount ( const QModelIndex& /*parent*/) const
82     {
83     return 9;
84 schoenebeck 1461 }
85    
86    
87 capela 1509 QVariant MidiInstrumentsModel::data ( const QModelIndex &index, int role ) const
88     {
89     if (!index.isValid())
90     return QVariant();
91 schoenebeck 1492
92 capela 1509 const qsamplerInstrument* pInstr = NULL;
93 schoenebeck 1461
94 capela 1509 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 capela 1526 if (index.row() < n) {
100 capela 1509 pInstr = &(*itMap)[index.row() + (*itMap).size() - n];
101 capela 1526 break;
102     }
103 capela 1509 }
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 schoenebeck 1492
113 capela 1509 if (!pInstr)
114     return QVariant();
115 schoenebeck 1492
116 capela 1509 if (role == Qt::UserRole)
117     return QVariant::fromValue((void *) pInstr);
118 schoenebeck 1492
119 capela 1509 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 capela 1526 case 3: return QVariant::fromValue(pInstr->prog() + 1);
125 capela 1509 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 schoenebeck 1461 }
142    
143    
144 capela 1509 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 schoenebeck 1461 }
163    
164    
165 capela 1509 qsamplerInstrument* 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 schoenebeck 1461
179 capela 1523 // Resolve the appropriate place, we keep the list sorted that way ...
180 capela 1509 int i = 0;
181 capela 1523 for (; i < m_instruments[iMap].size(); ++i) {
182     if (iBank < m_instruments[iMap][i].bank()
183 capela 1509 || (iBank == m_instruments[iMap][i].bank() &&
184 capela 1523 iProg < m_instruments[iMap][i].prog())) {
185 capela 1509 break;
186 capela 1523 }
187     }
188 schoenebeck 1461
189 capela 1509 m_instruments[iMap].insert(i, qsamplerInstrument(iMap, iBank, iProg));
190     qsamplerInstrument& instr = m_instruments[iMap][i];
191     if (!instr.getInstrument())
192     m_instruments[iMap].removeAt(i);
193    
194     return &instr;
195 schoenebeck 1461 }
196    
197 capela 1509
198     void MidiInstrumentsModel::removeInstrument (
199     const qsamplerInstrument& 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 schoenebeck 1492 }
212    
213 capela 1509
214     // Reposition the instrument in the model (called when map/bank/prg changed)
215 capela 1523 void MidiInstrumentsModel::resort ( const qsamplerInstrument& instrument )
216 capela 1509 {
217     const int iMap = instrument.map();
218     const int iBank = instrument.bank();
219     const int iProg = instrument.prog();
220 capela 1523 // Remove given instrument from its current list
221 capela 1509 removeInstrument(instrument);
222 capela 1523 // Re-add the instrument
223 capela 1509 addInstrument(iMap, iBank, iProg);
224 schoenebeck 1492 }
225    
226 schoenebeck 1461
227 capela 1509 void MidiInstrumentsModel::setMidiMap ( int iMidiMap )
228     {
229     if (iMidiMap < 0)
230     iMidiMap = LSCP_MIDI_MAP_ALL;
231    
232     m_iMidiMap = iMidiMap;
233 schoenebeck 1461 }
234    
235 capela 1509
236     int MidiInstrumentsModel::midiMap (void) const
237     {
238     return m_iMidiMap;
239 schoenebeck 1461 }
240    
241 capela 1509 void MidiInstrumentsModel::refresh (void)
242     {
243     m_instruments.clear();
244 schoenebeck 1461
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 capela 1499 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
263 schoenebeck 1461 }
264    
265     QApplication::restoreOverrideCursor();
266    
267     if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
268     pMainForm->appendMessagesClient("lscp_list_midi_instruments");
269 capela 1509 pMainForm->appendMessagesError(
270     tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
271 schoenebeck 1461 }
272    
273 schoenebeck 1492 // inform the outer world (QTableView) that our data changed
274     QAbstractTableModel::reset();
275 schoenebeck 1461 }
276    
277    
278 schoenebeck 1492 //-------------------------------------------------------------------------
279     // MidiInstrumentsDelegate - table cell renderer for MIDI prog mappings
280     // (doesn't actually do anything ATM, but is already there for a future
281     // cell editor widget implementation)
282    
283 capela 1509 MidiInstrumentsDelegate::MidiInstrumentsDelegate ( QObject* pParent )
284     : QItemDelegate(pParent)
285     {
286 schoenebeck 1461 }
287    
288 capela 1509
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 schoenebeck 1461 }
295    
296 capela 1509
297     void MidiInstrumentsDelegate::setEditorData ( QWidget */*pEditor*/,
298     const QModelIndex& /*index*/) const
299     {
300 schoenebeck 1461 }
301    
302 capela 1509
303     void MidiInstrumentsDelegate::setModelData ( QWidget */*pEditor*/,
304     QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const
305     {
306 schoenebeck 1461 }
307    
308 capela 1509
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 schoenebeck 1461 }
315    
316 capela 1464
317 capela 971 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC