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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1509 - (hide annotations) (download)
Thu Nov 22 11:10:44 2007 UTC (16 years, 4 months ago) by capela
File size: 8797 byte(s)
* Audio routing table is initially hidden in the dialog, when
  creating a new sampler channel.

* README requirements and configuration notes update.

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     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 schoenebeck 1492
111 capela 1509 if (!pInstr)
112     return QVariant();
113 schoenebeck 1492
114 capela 1509 if (role == Qt::UserRole)
115     return QVariant::fromValue((void *) pInstr);
116 schoenebeck 1492
117 capela 1509 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 schoenebeck 1461 }
141    
142    
143 capela 1509 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 schoenebeck 1461 }
162    
163    
164 capela 1509 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 schoenebeck 1461
178 capela 1509 // 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 schoenebeck 1461
186 capela 1509 m_instruments[iMap].insert(i, qsamplerInstrument(iMap, iBank, iProg));
187     qsamplerInstrument& instr = m_instruments[iMap][i];
188     if (!instr.getInstrument())
189     m_instruments[iMap].removeAt(i);
190    
191     return &instr;
192 schoenebeck 1461 }
193    
194 capela 1509
195     void MidiInstrumentsModel::removeInstrument (
196     const qsamplerInstrument& instrument )
197     {
198     const int iMap = instrument.map();
199     const int iBank = instrument.bank();
200     const int iProg = instrument.prog();
201     for (int i = 0; i < m_instruments[iMap].size(); i++) {
202     if (m_instruments[iMap][i].bank() == iBank &&
203     m_instruments[iMap][i].prog() == iProg) {
204     m_instruments[iMap].removeAt(i);
205     break;
206     }
207     }
208 schoenebeck 1492 }
209    
210 capela 1509
211     // Reposition the instrument in the model (called when map/bank/prg changed)
212     void MidiInstrumentsModel::resort ( const qsamplerInstrument instrument )
213     {
214     const int iMap = instrument.map();
215     const int iBank = instrument.bank();
216     const int iProg = instrument.prog();
217     // remove given instrument from its current list
218     removeInstrument(instrument);
219     // re-add the instrument
220     addInstrument(iMap, iBank, iProg);
221 schoenebeck 1492 }
222    
223 schoenebeck 1461
224 capela 1509 void MidiInstrumentsModel::setMidiMap ( int iMidiMap )
225     {
226     if (iMidiMap < 0)
227     iMidiMap = LSCP_MIDI_MAP_ALL;
228    
229     m_iMidiMap = iMidiMap;
230 schoenebeck 1461 }
231    
232 capela 1509
233     int MidiInstrumentsModel::midiMap (void) const
234     {
235     return m_iMidiMap;
236 schoenebeck 1461 }
237    
238 capela 1509 void MidiInstrumentsModel::refresh (void)
239     {
240     m_instruments.clear();
241 schoenebeck 1461
242     MainForm* pMainForm = MainForm::getInstance();
243     if (pMainForm == NULL)
244     return;
245     if (pMainForm->client() == NULL)
246     return;
247    
248     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
249    
250     // Load the whole bunch of instrument items...
251     lscp_midi_instrument_t* pInstrs
252     = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
253     for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
254     const int iMap = pInstrs[iInstr].map;
255     const int iBank = pInstrs[iInstr].bank;
256     const int iProg = pInstrs[iInstr].prog;
257     addInstrument(iMap, iBank, iProg);
258     // Try to keep it snappy :)
259 capela 1499 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
260 schoenebeck 1461 }
261    
262     QApplication::restoreOverrideCursor();
263    
264     if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
265     pMainForm->appendMessagesClient("lscp_list_midi_instruments");
266 capela 1509 pMainForm->appendMessagesError(
267     tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
268 schoenebeck 1461 }
269    
270 schoenebeck 1492 // inform the outer world (QTableView) that our data changed
271     QAbstractTableModel::reset();
272 schoenebeck 1461 }
273    
274    
275 schoenebeck 1492 //-------------------------------------------------------------------------
276     // MidiInstrumentsDelegate - table cell renderer for MIDI prog mappings
277     // (doesn't actually do anything ATM, but is already there for a future
278     // cell editor widget implementation)
279    
280 capela 1509 MidiInstrumentsDelegate::MidiInstrumentsDelegate ( QObject* pParent )
281     : QItemDelegate(pParent)
282     {
283 schoenebeck 1461 }
284    
285 capela 1509
286     QWidget* MidiInstrumentsDelegate::createEditor ( QWidget* pParent,
287     const QStyleOptionViewItem& option, const QModelIndex& index ) const
288     {
289     return QItemDelegate::createEditor(pParent, option, index);
290     // return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);
291 schoenebeck 1461 }
292    
293 capela 1509
294     void MidiInstrumentsDelegate::setEditorData ( QWidget */*pEditor*/,
295     const QModelIndex& /*index*/) const
296     {
297 schoenebeck 1461 }
298    
299 capela 1509
300     void MidiInstrumentsDelegate::setModelData ( QWidget */*pEditor*/,
301     QAbstractItemModel* /*model*/, const QModelIndex& /*index*/) const
302     {
303 schoenebeck 1461 }
304    
305 capela 1509
306     void MidiInstrumentsDelegate::updateEditorGeometry ( QWidget *pEditor,
307     const QStyleOptionViewItem& option, const QModelIndex& index) const
308     {
309     QItemDelegate::updateEditorGeometry(pEditor, option, index);
310     // if (pEditor) pEditor->setGeometry(option.rect);
311 schoenebeck 1461 }
312    
313 capela 1464
314 capela 971 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC