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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 987 - (hide annotations) (download)
Tue Dec 19 11:19:55 2006 UTC (13 years, 2 months ago) by capela
File size: 16640 byte(s)
* Revised error verbosity in general and on session load/save;
  hour-glass wait cursor is now displayed on session load/save;
  keyboard shortcuts changed on MIDI instruments view context;
  improved channel strip arrangement on session open/load;
  instrument map entry removal confirmation (as optional);
  corrected some tooltip text strings.

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 capela 987 #include "qsamplerOptions.h"
29 capela 971 #include "qsamplerMainForm.h"
30    
31 capela 987 #include <qmessagebox.h>
32 capela 971 #include <qaction.h>
33     #include <qfileinfo.h>
34     #include <qpopupmenu.h>
35    
36     // Needed for lroundf()
37     #include <math.h>
38    
39 capela 972 #ifndef CONFIG_ROUND
40 capela 980 static inline long lroundf ( float x )
41 capela 971 {
42 capela 980 if (x >= 0.0f)
43     return long(x + 0.5f);
44     else
45     return long(x - 0.5f);
46 capela 971 }
47     #endif
48    
49    
50     //----------------------------------------------------------------------
51     // class qsamplerInstrumentGroup -- custom group list view item.
52     //
53    
54     // Constructors.
55     qsamplerInstrumentGroup::qsamplerInstrumentGroup (
56     qsamplerInstrumentList *pListView, const QString& sName,
57     QListViewItem *pItemAfter )
58     : QListViewItem(pListView, pItemAfter ? pItemAfter : pListView->lastItem())
59     {
60     QListViewItem::setRenameEnabled(0, true);
61    
62     QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png"));
63     QListViewItem::setText(0, sName);
64     }
65    
66    
67     qsamplerInstrumentGroup::qsamplerInstrumentGroup (
68     qsamplerInstrumentGroup *pGroupItem, const QString& sName )
69     : QListViewItem(pGroupItem, sName)
70     {
71     QListViewItem::setRenameEnabled(0, true);
72    
73     QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png"));
74     }
75    
76    
77     // Default destructor.
78     qsamplerInstrumentGroup::~qsamplerInstrumentGroup (void)
79     {
80     }
81    
82    
83     // Instance accessors.
84     void qsamplerInstrumentGroup::setName ( const QString& sName )
85     {
86     QListViewItem::setText(0, sName);
87     }
88    
89    
90     QString qsamplerInstrumentGroup::name (void) const
91     {
92     return QListViewItem::text(0);
93     }
94    
95    
96     qsamplerInstrumentGroup *qsamplerInstrumentGroup::groupItem (void) const
97     {
98     QListViewItem *pParent = QListViewItem::parent();
99     while (pParent && pParent->rtti() != qsamplerInstrumentList::Group)
100     pParent = pParent->parent();
101     return static_cast<qsamplerInstrumentGroup *> (pParent);
102     }
103    
104    
105     qsamplerInstrumentList *qsamplerInstrumentGroup::listView (void) const
106     {
107     return static_cast<qsamplerInstrumentList *> (QListViewItem::listView());
108     }
109    
110    
111     // To show up whether its open or not.
112     void qsamplerInstrumentGroup::setOpen ( bool bOpen )
113     {
114     // Set the proper pixmap of this...
115     if (rtti() == qsamplerInstrumentList::Group) {
116     QListViewItem::setPixmap(0, QPixmap::fromMimeSource(
117     bOpen ? "itemGroupOpen.png" : "itemGroup.png"));
118     }
119     // Open it up...
120     QListViewItem::setOpen(bOpen);
121    
122     // All ancestors should be also visible.
123     if (bOpen && QListViewItem::parent())
124     QListViewItem::parent()->setOpen(true);
125     }
126    
127    
128     // To virtually distinguish between list view items.
129     int qsamplerInstrumentGroup::rtti (void) const
130     {
131     return qsamplerInstrumentList::Group;
132     }
133    
134    
135     //----------------------------------------------------------------------
136     // class qsamplerInstrumentItem -- custom file list view item.
137     //
138    
139     // Constructors.
140     qsamplerInstrumentItem::qsamplerInstrumentItem (
141     qsamplerInstrumentList *pListView,
142     qsamplerInstrument *pInstrument,
143     QListViewItem *pItemAfter )
144     : qsamplerInstrumentGroup(pListView, pInstrument->name(), pItemAfter)
145     {
146     m_pInstrument = pInstrument;
147    
148     update();
149     }
150    
151     qsamplerInstrumentItem::qsamplerInstrumentItem (
152     qsamplerInstrumentGroup *pGroupItem,
153     qsamplerInstrument *pInstrument )
154     : qsamplerInstrumentGroup(pGroupItem, pInstrument->name())
155     {
156     m_pInstrument = pInstrument;
157    
158     update();
159     }
160    
161    
162     // Default destructor.
163     qsamplerInstrumentItem::~qsamplerInstrumentItem (void)
164     {
165     if (m_pInstrument)
166     delete m_pInstrument;
167     }
168    
169    
170     // To virtually distinguish between list view items.
171     int qsamplerInstrumentItem::rtti (void) const
172     {
173     return qsamplerInstrumentList::Item;
174     }
175    
176    
177     // Payload accessor.
178     qsamplerInstrument *qsamplerInstrumentItem::instrument (void) const
179     {
180     return m_pInstrument;
181     }
182    
183    
184     // Item refreshment.
185     void qsamplerInstrumentItem::update (void)
186     {
187     QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemFile.png"));
188    
189     const QString s = "-";
190     if (m_pInstrument) {
191     setText(0, m_pInstrument->name());
192 capela 980 setText(1, QString::number(m_pInstrument->map()));
193     setText(2, QString::number(m_pInstrument->bank()));
194     setText(3, QString::number(m_pInstrument->prog() + 1));
195     setText(4, m_pInstrument->engineName());
196     setText(5, QFileInfo(m_pInstrument->instrumentFile()).fileName());
197     setText(6, QString::number(m_pInstrument->instrumentNr()));
198     setText(7, QString::number(::lroundf(100.0f * m_pInstrument->volume())));
199 capela 971 QString sLoadMode = s;
200     switch (m_pInstrument->loadMode()) {
201     case 3:
202     sLoadMode = QObject::tr("Persistent");
203     break;
204     case 2:
205     sLoadMode = QObject::tr("On Demand Hold");
206     break;
207     case 1:
208     sLoadMode = QObject::tr("On Demand");
209     break;
210     }
211 capela 980 setText(8, sLoadMode);
212 capela 971 } else {
213     for (int i = 0; i < listView()->columns(); i++)
214     setText(i, s);
215     }
216     }
217    
218    
219     //----------------------------------------------------------------------------
220     // qsamplerInstrumentList -- MIDI instrument list view.
221     //
222    
223     // Constructor.
224     qsamplerInstrumentList::qsamplerInstrumentList (
225     QWidget *pParent, const char *pszName )
226     : QListView(pParent, pszName)
227     {
228     // QListView::setRootIsDecorated(true);
229     QListView::setResizeMode(QListView::NoColumn);
230     // QListView::setAcceptDrops(true);
231     QListView::setDragAutoScroll(true);
232     QListView::setSizePolicy(
233     QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
234     // QListView::setShowToolTips(false);
235     QListView::setSortColumn(-1);
236    
237     QListView::addColumn(tr("Name"));
238 capela 980 QListView::addColumn(tr("Map"));
239 capela 971 QListView::addColumn(tr("Bank"));
240     QListView::addColumn(tr("Prog"));
241     QListView::addColumn(tr("Engine"));
242     QListView::addColumn(tr("File"));
243     QListView::addColumn(tr("Nr"));
244     QListView::addColumn(tr("Vol"));
245     QListView::addColumn(tr("Mode"));
246    
247 capela 980 QListView::setColumnAlignment(1, Qt::AlignHCenter); // Map
248     QListView::setColumnAlignment(2, Qt::AlignHCenter); // Bank
249     QListView::setColumnAlignment(3, Qt::AlignHCenter); // Prog
250     QListView::setColumnAlignment(6, Qt::AlignHCenter); // Nr
251     QListView::setColumnAlignment(7, Qt::AlignHCenter); // Vol
252 capela 971
253 capela 980 QListView::setColumnWidth(0, 120); // Name
254     QListView::setColumnWidth(5, 240); // File
255 capela 971
256     m_pNewGroupAction = new QAction(tr("New &Group"), tr("Ctrl+G"), this);
257 capela 987 m_pNewItemAction = new QAction(tr("New &Instrument..."), tr("Ins"), this);
258     m_pEditItemAction = new QAction(tr("&Edit..."), tr("Enter"), this);
259     m_pRenameAction = new QAction(tr("&Rename"), tr("F2"), this);
260     m_pDeleteAction = new QAction(tr("&Delete"), tr("Del"), this);
261     m_pRefreshAction = new QAction(tr("Re&fresh"), tr("F5"), this);
262 capela 971
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 capela 980 && pItem->instrument()->map() == pInstrument->map()
376 capela 971 && pItem->instrument()->bank() == pInstrument->bank()
377 capela 980 && pItem->instrument()->prog() == pInstrument->prog())
378 capela 971 return pItem;
379     }
380     ++iter;
381     }
382     // Not found.
383     return NULL;
384     }
385    
386    
387     // Find and return the nearest group item...
388     qsamplerInstrumentGroup *qsamplerInstrumentList::groupItem (
389     QListViewItem *pItem ) const
390     {
391     while (pItem && pItem->rtti() != Group)
392     pItem = pItem->parent();
393     return static_cast<qsamplerInstrumentGroup *> (pItem);
394     }
395    
396    
397     // Add a new group item below the current one.
398     void qsamplerInstrumentList::newGroupSlot (void)
399     {
400     qsamplerInstrumentGroup *pParentGroup
401     = groupItem(QListView::selectedItem());
402     qsamplerInstrumentGroup *pNewGroup
403     = addGroup(tr("New Group"), pParentGroup);
404     if (pParentGroup)
405     pParentGroup->setOpen(true);
406     if (pNewGroup)
407     pNewGroup->startRename(0);
408    
409     selectionChangedSlot();
410     }
411    
412    
413     // Add a new instrument item below the current one.
414     void qsamplerInstrumentList::newItemSlot (void)
415     {
416     qsamplerInstrument *pInstrument = new qsamplerInstrument();
417    
418     qsamplerInstrumentForm form(this);
419     form.setup(pInstrument);
420     if (!form.exec()) {
421     delete pInstrument;
422     return;
423     }
424    
425     // Check it there's already one instrument item
426     // with the very same key (bank, program);
427     // if yes, just remove it without prejudice...
428     qsamplerInstrumentItem *pItem = findItem(pInstrument);
429     if (pItem)
430     delete pItem;
431    
432 capela 980 pInstrument->mapInstrument();
433 capela 971 emit instrumentsChanged();
434    
435     qsamplerInstrumentGroup *pParentGroup
436     = groupItem(QListView::selectedItem());
437     addItem(pInstrument, pParentGroup);
438     if (pParentGroup)
439     pParentGroup->setOpen(true);
440    
441     selectionChangedSlot();
442     }
443    
444    
445     // Edit current item below the current one.
446     void qsamplerInstrumentList::editItemSlot (void)
447     {
448     QListViewItem *pListItem = QListView::selectedItem();
449     if (pListItem == NULL)
450     return;
451     if (pListItem->rtti() == Item) {
452     qsamplerInstrumentItem *pItem
453     = static_cast<qsamplerInstrumentItem *> (pListItem);
454     if (pItem && pItem->instrument()) {
455     qsamplerInstrumentForm form(this);
456     form.setup(pItem->instrument());
457     if (form.exec()) {
458 capela 980 pItem->instrument()->mapInstrument();
459 capela 971 emit instrumentsChanged();
460     pItem->update();
461     }
462     }
463     }
464    
465     selectionChangedSlot();
466     }
467    
468    
469     // Rename current group/item.
470     void qsamplerInstrumentList::renameSlot (void)
471     {
472     QListViewItem *pListItem = QListView::selectedItem();
473     if (pListItem)
474     pListItem->startRename(0);
475    
476     selectionChangedSlot();
477     }
478    
479    
480     // Remove current group/item.
481     void qsamplerInstrumentList::deleteSlot (void)
482     {
483     QListViewItem *pListItem = QListView::selectedItem();
484 capela 987 if (pListItem == NULL)
485     return;
486    
487     qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
488     if (pMainForm == NULL)
489     return;
490    
491     // Prompt user if this is for real...
492     qsamplerOptions *pOptions = pMainForm->options();
493     if (pOptions && pOptions->bConfirmRemove) {
494     if (QMessageBox::warning(this,
495     QSAMPLER_TITLE ": " + tr("Warning"),
496     tr("Delete %1:\n\n"
497     "%2\n\n"
498     "Are you sure?")
499     .arg(pListItem->rtti() == Item ? tr("instrument") : tr("group"))
500     .arg(pListItem->text(0)),
501     tr("OK"), tr("Cancel")) > 0)
502     return;
503     }
504    
505     // Unmap instrument entry...
506     if (pListItem->rtti() == Item) {
507     qsamplerInstrumentItem *pItem
508     = static_cast<qsamplerInstrumentItem *> (pListItem);
509     if (pItem && pItem->instrument()) {
510     pItem->instrument()->unmapInstrument();
511     emit instrumentsChanged();
512 capela 971 }
513     }
514    
515 capela 987 // Do it for real...
516     delete pListItem;
517    
518 capela 971 selectionChangedSlot();
519     }
520    
521    
522     // In-place selection slot.
523     void qsamplerInstrumentList::selectionChangedSlot (void)
524     {
525     qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
526     QListViewItem *pListItem = QListView::selectedItem();
527     bool bEnabled = (pMainForm && pMainForm->client());
528     m_pNewItemAction->setEnabled(bEnabled);
529     bEnabled = (bEnabled && pListItem != NULL);
530     m_pEditItemAction->setEnabled(bEnabled && pListItem->rtti() == Item);
531     m_pRenameAction->setEnabled(bEnabled);
532     m_pDeleteAction->setEnabled(bEnabled);
533     }
534    
535    
536     // In-place activation slot.
537     void qsamplerInstrumentList::activatedSlot ( QListViewItem *pListItem )
538     {
539     // FIXME: Hope the list view item is the one selected.
540     if (pListItem->rtti() == Item)
541     editItemSlot();
542     }
543    
544    
545     // In-place aliasing slot.
546     void qsamplerInstrumentList::renamedSlot ( QListViewItem *pListItem )
547     {
548     if (pListItem->rtti() == Item) {
549     qsamplerInstrumentItem *pItem
550     = static_cast<qsamplerInstrumentItem *> (pListItem);
551     if (pItem && pItem->instrument()) {
552     pItem->instrument()->setName(pListItem->text(0));
553 capela 980 pItem->instrument()->mapInstrument();
554 capela 971 emit instrumentsChanged();
555     pItem->update();
556     }
557     }
558     }
559    
560    
561     // Context menu request event handler.
562     void qsamplerInstrumentList::contextMenuEvent (
563     QContextMenuEvent *pContextMenuEvent )
564     {
565     if (!m_pNewItemAction->isEnabled())
566     return;
567    
568     QPopupMenu menu(this);
569    
570     // Construct context menu.
571     m_pNewItemAction->addTo(&menu);
572     // m_pNewGroupAction->addTo(&menu);
573     menu.insertSeparator();
574     m_pEditItemAction->addTo(&menu);
575     m_pRenameAction->addTo(&menu);
576     m_pDeleteAction->addTo(&menu);
577     menu.insertSeparator();
578     m_pRefreshAction->addTo(&menu);
579    
580     menu.exec(pContextMenuEvent->globalPos());
581     }
582    
583    
584     // General reloader.
585     void qsamplerInstrumentList::refresh (void)
586     {
587     clear();
588    
589     qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
590     if (pMainForm == NULL)
591     return;
592     if (pMainForm->client() == NULL)
593     return;
594    
595     qsamplerInstrumentItem *pItem = NULL;
596     lscp_midi_instrument_t *pInstrs
597 capela 980 = ::lscp_list_midi_instruments(pMainForm->client(), LSCP_MIDI_MAP_ALL);
598 capela 987 for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
599 capela 980 int iMap = pInstrs[iInstr].map;
600     int iBank = pInstrs[iInstr].bank;
601     int iProg = pInstrs[iInstr].prog;
602 capela 971 qsamplerInstrument *pInstrument
603 capela 980 = new qsamplerInstrument(iMap, iBank, iProg);
604     if (pInstrument->getInstrument())
605 capela 971 pItem = new qsamplerInstrumentItem(this, pInstrument, pItem);
606     }
607    
608     if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
609     pMainForm->appendMessagesClient("lscp_list_midi_instruments");
610     pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
611     }
612    
613     selectionChangedSlot();
614     }
615    
616    
617     // end of qsamplerInstrumentList.cpp
618    

  ViewVC Help
Powered by ViewVC