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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2071 - (hide annotations) (download)
Mon Mar 15 18:21:28 2010 UTC (14 years ago) by capela
File size: 10647 byte(s)
* Maybe fixed instrument list view/model for Qt >= 4.6, at last.

1 capela 971 // qsamplerInstrumentList.cpp
2     //
3     /****************************************************************************
4 capela 2064 Copyright (C) 2003-2010, 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    
28 capela 987 #include "qsamplerOptions.h"
29 capela 971 #include "qsamplerMainForm.h"
30    
31 capela 1499 #include <QApplication>
32     #include <QCursor>
33 schoenebeck 1461
34 capela 971
35 capela 2064 namespace QSampler {
36 capela 971
37 schoenebeck 1492 //-------------------------------------------------------------------------
38 capela 2064 // QSampler::InstrumentListModel - data model for MIDI prog mappings
39     //
40 capela 971
41 capela 2064 InstrumentListModel::InstrumentListModel ( QObject *pParent )
42 capela 2065 : QAbstractItemModel(pParent), m_iMidiMap(LSCP_MIDI_MAP_ALL)
43 capela 1509 {
44 capela 2068 // QAbstractItemModel::reset();
45 schoenebeck 1461 }
46 capela 971
47 capela 2064 InstrumentListModel::~InstrumentListModel (void)
48     {
49     clear();
50     }
51 capela 1509
52 capela 2064
53     int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const
54 capela 1509 {
55 capela 2064 int nrows = 0;
56    
57 capela 1509 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
58 capela 2064 InstrumentMap::const_iterator itMap = m_instruments.constBegin();
59     for ( ; itMap != m_instruments.constEnd(); ++itMap)
60     nrows += (*itMap).size();
61     } else {
62     InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
63     if (itMap != m_instruments.constEnd())
64     nrows += (*itMap).size();
65 capela 1509 }
66 capela 2064
67     return nrows;
68 schoenebeck 1461 }
69    
70 capela 1509
71 capela 2064 int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const
72 capela 1509 {
73     return 9;
74 schoenebeck 1461 }
75    
76    
77 capela 2064 QVariant InstrumentListModel::data (
78     const QModelIndex &index, int role ) const
79 capela 1509 {
80     if (!index.isValid())
81     return QVariant();
82 capela 2064 const Instrument *pInstr
83     = static_cast<Instrument *> (index.internalPointer());
84 schoenebeck 1461
85 capela 2064 if (pInstr && role == Qt::DisplayRole) {
86 capela 1509 switch (index.column()) {
87     case 0: return pInstr->name();
88     case 1: return QVariant::fromValue(pInstr->map());
89     case 2: return QVariant::fromValue(pInstr->bank());
90 capela 1526 case 3: return QVariant::fromValue(pInstr->prog() + 1);
91 capela 1509 case 4: return pInstr->engineName();
92     case 5: return pInstr->instrumentFile();
93     case 6: return QVariant::fromValue(pInstr->instrumentNr());
94     case 7: return QString::number(pInstr->volume() * 100.0) + " %";
95     case 8: {
96     switch (pInstr->loadMode()) {
97 capela 2064 case 3: return tr("Persistent");
98     case 2: return tr("On Demand Hold");
99     case 1: return tr("On Demand");
100 capela 1509 }
101     }
102 capela 2064 default:
103     break;
104 capela 1509 }
105     }
106    
107     return QVariant();
108 schoenebeck 1461 }
109    
110    
111 capela 2064 QModelIndex InstrumentListModel::index (
112     int row, int col, const QModelIndex& /*parent*/ ) const
113 capela 1509 {
114 capela 2064 const Instrument *pInstr = NULL;
115 capela 1509
116 capela 2064 if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
117     int nrows = 0;
118     InstrumentMap::const_iterator itMap = m_instruments.constBegin();
119     for ( ; itMap != m_instruments.constEnd(); ++itMap) {
120     const InstrumentList& list = *itMap;
121     nrows += list.size();
122     if (row < nrows) {
123     pInstr = list.at(row + list.size() - nrows);
124     break;
125     }
126     }
127     } else {
128     // Resolve MIDI instrument map...
129     InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap);
130     if (itMap != m_instruments.constEnd()) {
131     const InstrumentList& list = *itMap;
132     if (row < list.size())
133     pInstr = list.at(row);
134     }
135 capela 1509 }
136 capela 2064
137     if (pInstr)
138     return createIndex(row, col, (void *) pInstr);
139     else
140     return QModelIndex();
141 schoenebeck 1461 }
142    
143    
144 capela 2065 QModelIndex InstrumentListModel::parent ( const QModelIndex& /*child*/ ) const
145 capela 2064 {
146     return QModelIndex();
147     }
148    
149    
150     QVariant InstrumentListModel::headerData (
151     int section, Qt::Orientation orientation, int role ) const
152     {
153     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
154     switch (section) {
155     case 0: return tr("Name");
156     case 1: return tr("Map");
157     case 2: return tr("Bank");
158     case 3: return tr("Prog");
159     case 4: return tr("Engine");
160     case 5: return tr("File");
161     case 6: return tr("Nr");
162     case 7: return tr("Vol");
163     case 8: return tr("Mode");
164     }
165     }
166    
167     return QAbstractItemModel::headerData(section, orientation, role);
168     }
169    
170    
171     void InstrumentListModel::setMidiMap ( int iMidiMap )
172     {
173     if (iMidiMap < 0)
174     iMidiMap = LSCP_MIDI_MAP_ALL;
175    
176     m_iMidiMap = iMidiMap;
177     }
178    
179    
180     int InstrumentListModel::midiMap (void) const
181     {
182     return m_iMidiMap;
183     }
184    
185    
186     const Instrument *InstrumentListModel::addInstrument (
187 capela 1509 int iMap, int iBank, int iProg )
188     {
189     // Check it there's already one instrument item
190     // with the very same key (bank, program);
191     // if yes, just remove it without prejudice...
192 capela 2064 InstrumentList& list = m_instruments[iMap];
193 capela 2071
194     int i = 0;
195     for ( ; i < list.size(); ++i) {
196 capela 2064 const Instrument *pInstr = list.at(i);
197     if (pInstr->bank() == iBank && pInstr->prog() == iProg) {
198     delete pInstr;
199     list.removeAt(i);
200 capela 1509 break;
201     }
202     }
203 schoenebeck 1461
204 capela 2064 // Resolve the appropriate place, we keep the list sorted that way...
205 capela 2071 for (i = 0; i < list.size(); ++i) {
206 capela 2064 const Instrument *pInstr = list.at(i);
207     if (iBank < pInstr->bank()
208     || (iBank == pInstr->bank() && iProg < pInstr->prog())) {
209 capela 1509 break;
210 capela 1523 }
211     }
212 schoenebeck 1461
213 capela 2064 Instrument *pInstr = new Instrument(iMap, iBank, iProg);
214     if (pInstr->getInstrument()) {
215     list.insert(i, pInstr);
216     } else {
217     delete pInstr;
218     pInstr = NULL;
219     }
220 capela 1509
221 capela 2064 return pInstr;
222 schoenebeck 1461 }
223    
224 capela 1509
225 capela 2070 void InstrumentListModel::removeInstrument ( Instrument *pInstrument )
226 capela 1509 {
227 capela 2071 const int iMap = pInstrument->map();
228 capela 2064
229     if (m_instruments.contains(iMap)) {
230     InstrumentList& list = m_instruments[iMap];
231     for (int i = 0; i < list.size(); ++i) {
232 capela 2071 if (pInstrument == list.at(i)) {
233     delete pInstrument;
234 capela 2064 list.removeAt(i);
235     break;
236     }
237 capela 1509 }
238     }
239 schoenebeck 1492 }
240    
241 capela 1509
242 capela 2070 void InstrumentListModel::updateInstrument ( Instrument *pInstrument )
243     {
244     pInstrument->getInstrument();
245     }
246    
247    
248 capela 1509 // Reposition the instrument in the model (called when map/bank/prg changed)
249 capela 2070 void InstrumentListModel::resortInstrument ( Instrument *pInstrument )
250 capela 1509 {
251 capela 2064 const int iMap = pInstrument->map();
252     const int iBank = pInstrument->bank();
253     const int iProg = pInstrument->prog();
254 schoenebeck 1492
255 capela 2064 // Remove given instrument from its current list...
256     removeInstrument(pInstrument);
257 schoenebeck 1461
258 capela 2064 // Re-add the instrument...
259     addInstrument(iMap, iBank, iProg);
260 schoenebeck 1461 }
261    
262 capela 1509
263 capela 2064 void InstrumentListModel::refresh (void)
264 capela 1509 {
265 capela 2064 MainForm *pMainForm = MainForm::getInstance();
266 schoenebeck 1461 if (pMainForm == NULL)
267     return;
268     if (pMainForm->client() == NULL)
269     return;
270    
271     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
272    
273 capela 2064 clear();
274    
275 schoenebeck 1461 // Load the whole bunch of instrument items...
276 capela 2064 lscp_midi_instrument_t *pInstrs
277 schoenebeck 1461 = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
278     for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
279     const int iMap = pInstrs[iInstr].map;
280     const int iBank = pInstrs[iInstr].bank;
281     const int iProg = pInstrs[iInstr].prog;
282     addInstrument(iMap, iBank, iProg);
283     // Try to keep it snappy :)
284 capela 1499 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
285 schoenebeck 1461 }
286    
287     QApplication::restoreOverrideCursor();
288    
289     if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
290     pMainForm->appendMessagesClient("lscp_list_midi_instruments");
291 capela 1509 pMainForm->appendMessagesError(
292     tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
293 schoenebeck 1461 }
294 capela 2064 }
295 schoenebeck 1461
296 capela 2064 void InstrumentListModel::beginReset (void)
297     {
298     #if QT_VERSION >= 0x040600
299     QAbstractItemModel::beginResetModel();
300     #endif
301 schoenebeck 1461 }
302    
303 capela 2064 void InstrumentListModel::endReset (void)
304     {
305     #if QT_VERSION >= 0x040600
306     QAbstractItemModel::endResetModel();
307     #else
308     QAbstractItemModel::reset();
309     #endif
310     }
311 schoenebeck 1461
312 capela 2064
313     // Map clear.
314     void InstrumentListModel::clear (void)
315     {
316     InstrumentMap::iterator itMap = m_instruments.begin();
317     for ( ; itMap != m_instruments.end(); ++itMap) {
318     InstrumentList& list = itMap.value();
319     qDeleteAll(list);
320     list.clear();
321     }
322    
323     m_instruments.clear();
324     }
325    
326    
327 schoenebeck 1492 //-------------------------------------------------------------------------
328 capela 2064 // QSampler::InstrumentListView - list view for MIDI prog mappings
329     //
330 schoenebeck 1492
331 capela 2064 // Constructor.
332     InstrumentListView::InstrumentListView ( QWidget *pParent )
333     : QTreeView(pParent)
334 capela 1509 {
335 capela 2064 m_pListModel = new InstrumentListModel(this);
336    
337     QTreeView::setModel(m_pListModel);
338 capela 2065
339     QTreeView::setRootIsDecorated(false);
340     QTreeView::setUniformRowHeights(true);
341     QTreeView::setAlternatingRowColors(true);
342     QTreeView::setSelectionBehavior(QAbstractItemView::SelectRows);
343     QTreeView::setSelectionMode(QAbstractItemView::SingleSelection);
344 capela 2069 QTreeView::setItemsExpandable(false);
345    
346 capela 2065 QHeaderView *pHeader = QTreeView::header();
347     pHeader->setDefaultAlignment(Qt::AlignLeft);
348     pHeader->setMovable(false);
349     pHeader->setStretchLastSection(true);
350     pHeader->resizeSection(0, 120); // Name
351     QTreeView::resizeColumnToContents(1); // Map
352     QTreeView::resizeColumnToContents(2); // Bank
353     QTreeView::resizeColumnToContents(3); // Prog
354     QTreeView::resizeColumnToContents(4); // Engine
355     pHeader->resizeSection(5, 240); // File
356     QTreeView::resizeColumnToContents(6); // Nr
357     pHeader->resizeSection(7, 60); // Vol
358 schoenebeck 1461 }
359    
360 capela 1509
361 capela 2064 // Destructor.
362     InstrumentListView::~InstrumentListView (void)
363 capela 1509 {
364 capela 2064 delete m_pListModel;
365 schoenebeck 1461 }
366    
367 capela 1509
368 capela 2064 void InstrumentListView::setMidiMap ( int iMidiMap )
369 capela 1509 {
370 capela 2064 m_pListModel->setMidiMap(iMidiMap);
371 schoenebeck 1461 }
372    
373 capela 1509
374 capela 2064 int InstrumentListView::midiMap (void) const
375 capela 1509 {
376 capela 2064 return m_pListModel->midiMap();
377 schoenebeck 1461 }
378    
379 capela 1509
380 capela 2064 const Instrument *InstrumentListView::addInstrument (
381     int iMap, int iBank, int iProg )
382 capela 1509 {
383 capela 2064 m_pListModel->beginReset();
384     const Instrument *pInstrument
385     = m_pListModel->addInstrument(iMap, iBank, iProg);
386     m_pListModel->endReset();
387    
388     return pInstrument;
389 schoenebeck 1461 }
390    
391 capela 1464
392 capela 2070 void InstrumentListView::removeInstrument ( Instrument *pInstrument )
393 capela 2064 {
394     m_pListModel->beginReset();
395     m_pListModel->removeInstrument(pInstrument);
396     m_pListModel->endReset();
397     }
398    
399    
400 capela 2070 void InstrumentListView::updateInstrument ( Instrument *pInstrument )
401 capela 2064 {
402     m_pListModel->beginReset();
403     m_pListModel->updateInstrument(pInstrument);
404 capela 2068 m_pListModel->endReset();
405     }
406 capela 2064
407    
408 capela 2070 // Reposition the instrument in the model (called when map/bank/prg changed)
409     void InstrumentListView::resortInstrument ( Instrument *pInstrument )
410     {
411     m_pListModel->beginReset();
412     m_pListModel->resortInstrument(pInstrument);
413     m_pListModel->endReset();
414     }
415    
416    
417 capela 2064 // Refreshener.
418     void InstrumentListView::refresh (void)
419     {
420     m_pListModel->beginReset();
421     m_pListModel->refresh();
422     m_pListModel->endReset();
423     }
424    
425    
426     } // namespace QSampler
427    
428    
429 capela 971 // end of qsamplerInstrumentList.cpp

  ViewVC Help
Powered by ViewVC