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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 971 - (hide annotations) (download)
Thu Dec 7 10:36:26 2006 UTC (13 years, 2 months ago) by capela
File size: 15906 byte(s)
* MIDI instrumeent map program numbers are now displayed in
  the range 1-128, instead of the internal 0-127.

1 capela 971 // qsamplerInstrumentList.cpp
2     //
3     /****************************************************************************
4     Copyright (C) 2003-2005, rncbc aka Rui Nuno Capela. All rights reserved.
5    
6     This program is free software; you can redistribute it and/or
7     modify it under the terms of the GNU General Public License
8     as published by the Free Software Foundation; either version 2
9     of the License, or (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19    
20     *****************************************************************************/
21    
22     #include "qsamplerAbout.h"
23     #include "qsamplerInstrumentList.h"
24    
25     #include "qsamplerInstrument.h"
26     #include "qsamplerInstrumentForm.h"
27    
28     #include "qsamplerMainForm.h"
29    
30     #include <qaction.h>
31     #include <qfileinfo.h>
32     #include <qpopupmenu.h>
33    
34     // Needed for lroundf()
35     #include <math.h>
36    
37     #ifdef __BORLANDC__
38     static long lroundf ( float fval )
39     {
40     double fint = 0.0;
41     float frac = float(::modf(fval, &fint));
42     long lint = long(fint);
43     if (frac >= +0.5f)
44     lint++;
45     else
46     if (frac <= -0.5f)
47     lint--;
48     return lint;
49     }
50     #endif
51    
52    
53     //----------------------------------------------------------------------
54     // class qsamplerInstrumentGroup -- custom group list view item.
55     //
56    
57     // Constructors.
58     qsamplerInstrumentGroup::qsamplerInstrumentGroup (
59     qsamplerInstrumentList *pListView, const QString& sName,
60     QListViewItem *pItemAfter )
61     : QListViewItem(pListView, pItemAfter ? pItemAfter : pListView->lastItem())
62     {
63     QListViewItem::setRenameEnabled(0, true);
64    
65     QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png"));
66     QListViewItem::setText(0, sName);
67     }
68    
69    
70     qsamplerInstrumentGroup::qsamplerInstrumentGroup (
71     qsamplerInstrumentGroup *pGroupItem, const QString& sName )
72     : QListViewItem(pGroupItem, sName)
73     {
74     QListViewItem::setRenameEnabled(0, true);
75    
76     QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png"));
77     }
78    
79    
80     // Default destructor.
81     qsamplerInstrumentGroup::~qsamplerInstrumentGroup (void)
82     {
83     }
84    
85    
86     // Instance accessors.
87     void qsamplerInstrumentGroup::setName ( const QString& sName )
88     {
89     QListViewItem::setText(0, sName);
90     }
91    
92    
93     QString qsamplerInstrumentGroup::name (void) const
94     {
95     return QListViewItem::text(0);
96     }
97    
98    
99     qsamplerInstrumentGroup *qsamplerInstrumentGroup::groupItem (void) const
100     {
101     QListViewItem *pParent = QListViewItem::parent();
102     while (pParent && pParent->rtti() != qsamplerInstrumentList::Group)
103     pParent = pParent->parent();
104     return static_cast<qsamplerInstrumentGroup *> (pParent);
105     }
106    
107    
108     qsamplerInstrumentList *qsamplerInstrumentGroup::listView (void) const
109     {
110     return static_cast<qsamplerInstrumentList *> (QListViewItem::listView());
111     }
112    
113    
114     // To show up whether its open or not.
115     void qsamplerInstrumentGroup::setOpen ( bool bOpen )
116     {
117     // Set the proper pixmap of this...
118     if (rtti() == qsamplerInstrumentList::Group) {
119     QListViewItem::setPixmap(0, QPixmap::fromMimeSource(
120     bOpen ? "itemGroupOpen.png" : "itemGroup.png"));
121     }
122     // Open it up...
123     QListViewItem::setOpen(bOpen);
124    
125     // All ancestors should be also visible.
126     if (bOpen && QListViewItem::parent())
127     QListViewItem::parent()->setOpen(true);
128     }
129    
130    
131     // To virtually distinguish between list view items.
132     int qsamplerInstrumentGroup::rtti (void) const
133     {
134     return qsamplerInstrumentList::Group;
135     }
136    
137    
138     //----------------------------------------------------------------------
139     // class qsamplerInstrumentItem -- custom file list view item.
140     //
141    
142     // Constructors.
143     qsamplerInstrumentItem::qsamplerInstrumentItem (
144     qsamplerInstrumentList *pListView,
145     qsamplerInstrument *pInstrument,
146     QListViewItem *pItemAfter )
147     : qsamplerInstrumentGroup(pListView, pInstrument->name(), pItemAfter)
148     {
149     m_pInstrument = pInstrument;
150    
151     update();
152     }
153    
154     qsamplerInstrumentItem::qsamplerInstrumentItem (
155     qsamplerInstrumentGroup *pGroupItem,
156     qsamplerInstrument *pInstrument )
157     : qsamplerInstrumentGroup(pGroupItem, pInstrument->name())
158     {
159     m_pInstrument = pInstrument;
160    
161     update();
162     }
163    
164    
165     // Default destructor.
166     qsamplerInstrumentItem::~qsamplerInstrumentItem (void)
167     {
168     if (m_pInstrument)
169     delete m_pInstrument;
170     }
171    
172    
173     // To virtually distinguish between list view items.
174     int qsamplerInstrumentItem::rtti (void) const
175     {
176     return qsamplerInstrumentList::Item;
177     }
178    
179    
180     // Payload accessor.
181     qsamplerInstrument *qsamplerInstrumentItem::instrument (void) const
182     {
183     return m_pInstrument;
184     }
185    
186    
187     // Item refreshment.
188     void qsamplerInstrumentItem::update (void)
189     {
190     QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemFile.png"));
191    
192     const QString s = "-";
193     if (m_pInstrument) {
194     setText(0, m_pInstrument->name());
195     setText(1, QString::number(m_pInstrument->bank()));
196     setText(2, QString::number(m_pInstrument->program() + 1));
197     setText(3, m_pInstrument->engineName());
198     setText(4, QFileInfo(m_pInstrument->instrumentFile()).fileName());
199     setText(5, QString::number(m_pInstrument->instrumentNr()));
200     setText(6, QString::number(::lroundf(100.0f * m_pInstrument->volume())));
201     QString sLoadMode = s;
202     switch (m_pInstrument->loadMode()) {
203     case 3:
204     sLoadMode = QObject::tr("Persistent");
205     break;
206     case 2:
207     sLoadMode = QObject::tr("On Demand Hold");
208     break;
209     case 1:
210     sLoadMode = QObject::tr("On Demand");
211     break;
212     }
213     setText(7, sLoadMode);
214     } else {
215     for (int i = 0; i < listView()->columns(); i++)
216     setText(i, s);
217     }
218     }
219    
220    
221     //----------------------------------------------------------------------------
222     // qsamplerInstrumentList -- MIDI instrument list view.
223     //
224    
225     // Constructor.
226     qsamplerInstrumentList::qsamplerInstrumentList (
227     QWidget *pParent, const char *pszName )
228     : QListView(pParent, pszName)
229     {
230     // QListView::setRootIsDecorated(true);
231     QListView::setResizeMode(QListView::NoColumn);
232     // QListView::setAcceptDrops(true);
233     QListView::setDragAutoScroll(true);
234     QListView::setSizePolicy(
235     QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
236     // QListView::setShowToolTips(false);
237     QListView::setSortColumn(-1);
238    
239     QListView::addColumn(tr("Name"));
240     QListView::addColumn(tr("Bank"));
241     QListView::addColumn(tr("Prog"));
242     QListView::addColumn(tr("Engine"));
243     QListView::addColumn(tr("File"));
244     QListView::addColumn(tr("Nr"));
245     QListView::addColumn(tr("Vol"));
246     QListView::addColumn(tr("Mode"));
247    
248     QListView::setColumnAlignment(1, Qt::AlignHCenter); // Bank
249     QListView::setColumnAlignment(2, Qt::AlignHCenter); // Prog
250     QListView::setColumnAlignment(5, Qt::AlignHCenter); // Nr
251     QListView::setColumnAlignment(6, Qt::AlignHCenter); // Vol
252    
253     QListView::setColumnWidth(0, 60); // Name
254     QListView::setColumnWidth(0, 120); // File
255    
256     m_pNewGroupAction = new QAction(tr("New &Group"), tr("Ctrl+G"), this);
257     m_pNewItemAction = new QAction(tr("New &Instrument..."), tr("Ctrl+I"), this);
258     m_pEditItemAction = new QAction(tr("&Edit..."), tr("Ctrl+E"), this);
259     m_pRenameAction = new QAction(tr("&Rename"), tr("Ctrl+R"), this);
260     m_pDeleteAction = new QAction(tr("&Delete"), tr("Ctrl+D"), this);
261     m_pRefreshAction = new QAction(tr("Re&fresh"), tr("Ctrl+F"), this);
262    
263     QObject::connect(m_pNewGroupAction,
264     SIGNAL(activated()),
265     SLOT(newGroupSlot()));
266     QObject::connect(m_pNewItemAction,
267     SIGNAL(activated()),
268     SLOT(newItemSlot()));
269     QObject::connect(m_pEditItemAction,
270     SIGNAL(activated()),
271     SLOT(editItemSlot()));
272     QObject::connect(m_pRenameAction,
273     SIGNAL(activated()),
274     SLOT(renameSlot()));
275     QObject::connect(m_pDeleteAction,
276     SIGNAL(activated()),
277     SLOT(deleteSlot()));
278     QObject::connect(m_pRefreshAction,
279     SIGNAL(activated()),
280     SLOT(refresh()));
281    
282     QObject::connect(this,
283     SIGNAL(selectionChanged()),
284     SLOT(selectionChangedSlot()));
285     QObject::connect(this,
286     SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)),
287     SLOT(activatedSlot(QListViewItem*)));
288     QObject::connect(this,
289     SIGNAL(returnPressed(QListViewItem*)),
290     SLOT(activatedSlot(QListViewItem*)));
291     QObject::connect(this,
292     SIGNAL(itemRenamed(QListViewItem*,int)),
293     SLOT(renamedSlot(QListViewItem*)));
294    
295     selectionChangedSlot();
296     }
297    
298    
299     // Default destructor.
300     qsamplerInstrumentList::~qsamplerInstrumentList (void)
301     {
302     delete m_pNewGroupAction;
303     delete m_pNewItemAction;
304     delete m_pEditItemAction;
305     delete m_pRenameAction;
306     delete m_pDeleteAction;
307     }
308    
309    
310     // Add a new instrument item, optionally under a given group.
311     qsamplerInstrumentItem *qsamplerInstrumentList::addItem (
312     qsamplerInstrument *pInstrument,
313     qsamplerInstrumentGroup *pParentGroup )
314     {
315     qsamplerInstrumentItem *pItem = findItem(pInstrument);
316     if (pItem == NULL) {
317     if (pParentGroup)
318     pItem = new qsamplerInstrumentItem(pParentGroup, pInstrument);
319     else
320     pItem = new qsamplerInstrumentItem(this, pInstrument);
321     }
322     QListView::setSelected(pItem, true);
323     return pItem;
324     }
325    
326    
327     // Add a new instrument group, optionally under another group.
328     qsamplerInstrumentGroup *qsamplerInstrumentList::addGroup (
329     const QString& sName, qsamplerInstrumentGroup *pParentGroup )
330     {
331     qsamplerInstrumentGroup *pGroup = findGroup(sName);
332     if (pGroup == NULL) {
333     if (pParentGroup)
334     pGroup = new qsamplerInstrumentGroup(pParentGroup, sName);
335     else
336     pGroup = new qsamplerInstrumentGroup(this, sName);
337     }
338     QListView::setSelected(pGroup, true);
339     return pGroup;
340     }
341    
342    
343     // Find a group item, given its name.
344     qsamplerInstrumentGroup *qsamplerInstrumentList::findGroup (
345     const QString& sName ) const
346     {
347     // Iterate all over the place to search for the group.
348     QListViewItemIterator iter((QListView *) this);
349     while (iter.current()) {
350     QListViewItem *pItem = iter.current();
351     if (pItem->rtti() == Group && pItem->text(0) == sName)
352     return static_cast<qsamplerInstrumentGroup *> (pItem);
353     ++iter;
354     }
355     // Not found.
356     return NULL;
357     }
358    
359    
360     // Find a file item, given its name.
361     qsamplerInstrumentItem *qsamplerInstrumentList::findItem (
362     qsamplerInstrument *pInstrument ) const
363     {
364     if (pInstrument == NULL)
365     return NULL;
366    
367     // Iterate all over the place to search for the group.
368     QListViewItemIterator iter((QListView *) this);
369     while (iter.current()) {
370     QListViewItem *pListItem = iter.current();
371     if (pListItem->rtti() == Item) {
372     qsamplerInstrumentItem *pItem
373     = static_cast<qsamplerInstrumentItem *> (pListItem);
374     if (pItem && pItem->instrument()
375     && pItem->instrument()->bank() == pInstrument->bank()
376     && pItem->instrument()->program() == pInstrument->program())
377     return pItem;
378     }
379     ++iter;
380     }
381     // Not found.
382     return NULL;
383     }
384    
385    
386     // Find and return the nearest group item...
387     qsamplerInstrumentGroup *qsamplerInstrumentList::groupItem (
388     QListViewItem *pItem ) const
389     {
390     while (pItem && pItem->rtti() != Group)
391     pItem = pItem->parent();
392     return static_cast<qsamplerInstrumentGroup *> (pItem);
393     }
394    
395    
396     // Add a new group item below the current one.
397     void qsamplerInstrumentList::newGroupSlot (void)
398     {
399     qsamplerInstrumentGroup *pParentGroup
400     = groupItem(QListView::selectedItem());
401     qsamplerInstrumentGroup *pNewGroup
402     = addGroup(tr("New Group"), pParentGroup);
403     if (pParentGroup)
404     pParentGroup->setOpen(true);
405     if (pNewGroup)
406     pNewGroup->startRename(0);
407    
408     selectionChangedSlot();
409     }
410    
411    
412     // Add a new instrument item below the current one.
413     void qsamplerInstrumentList::newItemSlot (void)
414     {
415     qsamplerInstrument *pInstrument = new qsamplerInstrument();
416    
417     qsamplerInstrumentForm form(this);
418     form.setup(pInstrument);
419     if (!form.exec()) {
420     delete pInstrument;
421     return;
422     }
423    
424     // Check it there's already one instrument item
425     // with the very same key (bank, program);
426     // if yes, just remove it without prejudice...
427     qsamplerInstrumentItem *pItem = findItem(pInstrument);
428     if (pItem)
429     delete pItem;
430    
431     pInstrument->map();
432     emit instrumentsChanged();
433    
434     qsamplerInstrumentGroup *pParentGroup
435     = groupItem(QListView::selectedItem());
436     addItem(pInstrument, pParentGroup);
437     if (pParentGroup)
438     pParentGroup->setOpen(true);
439    
440     selectionChangedSlot();
441     }
442    
443    
444     // Edit current item below the current one.
445     void qsamplerInstrumentList::editItemSlot (void)
446     {
447     QListViewItem *pListItem = QListView::selectedItem();
448     if (pListItem == NULL)
449     return;
450     if (pListItem->rtti() == Item) {
451     qsamplerInstrumentItem *pItem
452     = static_cast<qsamplerInstrumentItem *> (pListItem);
453     if (pItem && pItem->instrument()) {
454     qsamplerInstrumentForm form(this);
455     form.setup(pItem->instrument());
456     if (form.exec()) {
457     pItem->instrument()->map();
458     emit instrumentsChanged();
459     pItem->update();
460     }
461     }
462     }
463    
464     selectionChangedSlot();
465     }
466    
467    
468     // Rename current group/item.
469     void qsamplerInstrumentList::renameSlot (void)
470     {
471     QListViewItem *pListItem = QListView::selectedItem();
472     if (pListItem)
473     pListItem->startRename(0);
474    
475     selectionChangedSlot();
476     }
477    
478    
479     // Remove current group/item.
480     void qsamplerInstrumentList::deleteSlot (void)
481     {
482     QListViewItem *pListItem = QListView::selectedItem();
483     if (pListItem) {
484     if (pListItem->rtti() == Item) {
485     qsamplerInstrumentItem *pItem
486     = static_cast<qsamplerInstrumentItem *> (pListItem);
487     if (pItem && pItem->instrument()) {
488     pItem->instrument()->unmap();
489     emit instrumentsChanged();
490     }
491     }
492     delete pListItem;
493     }
494    
495     selectionChangedSlot();
496     }
497    
498    
499     // In-place selection slot.
500     void qsamplerInstrumentList::selectionChangedSlot (void)
501     {
502     qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
503     QListViewItem *pListItem = QListView::selectedItem();
504     bool bEnabled = (pMainForm && pMainForm->client());
505     m_pNewItemAction->setEnabled(bEnabled);
506     bEnabled = (bEnabled && pListItem != NULL);
507     m_pEditItemAction->setEnabled(bEnabled && pListItem->rtti() == Item);
508     m_pRenameAction->setEnabled(bEnabled);
509     m_pDeleteAction->setEnabled(bEnabled);
510     }
511    
512    
513     // In-place activation slot.
514     void qsamplerInstrumentList::activatedSlot ( QListViewItem *pListItem )
515     {
516     // FIXME: Hope the list view item is the one selected.
517     if (pListItem->rtti() == Item)
518     editItemSlot();
519     }
520    
521    
522     // In-place aliasing slot.
523     void qsamplerInstrumentList::renamedSlot ( QListViewItem *pListItem )
524     {
525     if (pListItem->rtti() == Item) {
526     qsamplerInstrumentItem *pItem
527     = static_cast<qsamplerInstrumentItem *> (pListItem);
528     if (pItem && pItem->instrument()) {
529     pItem->instrument()->setName(pListItem->text(0));
530     pItem->instrument()->map();
531     emit instrumentsChanged();
532     pItem->update();
533     }
534     }
535     }
536    
537    
538     // Context menu request event handler.
539     void qsamplerInstrumentList::contextMenuEvent (
540     QContextMenuEvent *pContextMenuEvent )
541     {
542     if (!m_pNewItemAction->isEnabled())
543     return;
544    
545     QPopupMenu menu(this);
546    
547     // Construct context menu.
548     m_pNewItemAction->addTo(&menu);
549     // m_pNewGroupAction->addTo(&menu);
550     menu.insertSeparator();
551     m_pEditItemAction->addTo(&menu);
552     m_pRenameAction->addTo(&menu);
553     m_pDeleteAction->addTo(&menu);
554     menu.insertSeparator();
555     m_pRefreshAction->addTo(&menu);
556    
557     menu.exec(pContextMenuEvent->globalPos());
558     }
559    
560    
561     // General reloader.
562     void qsamplerInstrumentList::refresh (void)
563     {
564     clear();
565    
566     qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
567     if (pMainForm == NULL)
568     return;
569     if (pMainForm->client() == NULL)
570     return;
571    
572     qsamplerInstrumentItem *pItem = NULL;
573     lscp_midi_instrument_t *pInstrs
574     = ::lscp_list_midi_instruments(pMainForm->client());
575     for (int iInstr = 0; pInstrs && pInstrs[iInstr].program >= 0; ++iInstr) {
576     int iBank = (pInstrs[iInstr].bank_msb << 7) | pInstrs[iInstr].bank_lsb;
577     int iProgram = pInstrs[iInstr].program;
578     qsamplerInstrument *pInstrument
579     = new qsamplerInstrument(iBank, iProgram);
580     if (pInstrument->get())
581     pItem = new qsamplerInstrumentItem(this, pInstrument, pItem);
582     }
583    
584     if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
585     pMainForm->appendMessagesClient("lscp_list_midi_instruments");
586     pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
587     }
588    
589     selectionChangedSlot();
590     }
591    
592    
593     // end of qsamplerInstrumentList.cpp
594    

  ViewVC Help
Powered by ViewVC