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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 962 by capela, Sun Dec 3 18:27:23 2006 UTC revision 1464 by capela, Thu Nov 1 17:14:21 2007 UTC
# Line 1  Line 1 
1  // qsamplerInstrumentList.cpp  // qsamplerInstrumentList.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2003-2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2003-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5       Copyright (C) 2007, Christian Schoenebeck
6     This program is free software; you can redistribute it and/or  
7     modify it under the terms of the GNU General Public License     This program is free software; you can redistribute it and/or
8     as published by the Free Software Foundation; either version 2     modify it under the terms of the GNU General Public License
9     of the License, or (at your option) any later version.     as published by the Free Software Foundation; either version 2
10       of the License, or (at your option) any later version.
11     This program is distributed in the hope that it will be useful,  
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     This program is distributed in the hope that it will be useful,
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     GNU General Public License for more details.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15       GNU General Public License for more details.
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     You should have received a copy of the GNU General Public License
18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     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  #include "qsamplerAbout.h"  
23  #include "qsamplerInstrumentList.h"  #include "qsamplerAbout.h"
24    #include "qsamplerInstrumentList.h"
25  #include "qsamplerInstrument.h"  
26  #include "qsamplerInstrumentForm.h"  #include "qsamplerInstrument.h"
27    #include "qsamplerInstrumentForm.h"
28  #include "qsamplerMainForm.h"  
29    #include "qsamplerOptions.h"
30  #include <qaction.h>  #include "qsamplerMainForm.h"
31  #include <qfileinfo.h>  
32  #include <qpopupmenu.h>  #include <qapplication.h>
33    #include <qmessagebox.h>
34    #include <qeventloop.h>
35  //----------------------------------------------------------------------  #include <qaction.h>
36  // class qsamplerInstrumentGroup -- custom group list view item.  #include <qcursor.h>
37  //  #include <qfileinfo.h>
38    
39  // Constructors.  #include <QMenu>
40  qsamplerInstrumentGroup::qsamplerInstrumentGroup (  
41          qsamplerInstrumentList *pListView, const QString& sName,  // Needed for lroundf()
42          QListViewItem *pItemAfter )  #include <math.h>
43          : QListViewItem(pListView, pItemAfter ? pItemAfter : pListView->lastItem())  
44  {  #ifndef CONFIG_ROUND
45          QListViewItem::setRenameEnabled(0, true);  static inline long lroundf ( float x )
46    {
47          QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png"));          if (x >= 0.0f)
48          QListViewItem::setText(0, sName);                  return long(x + 0.5f);
49  }          else
50                    return long(x - 0.5f);
51    }
52  qsamplerInstrumentGroup::qsamplerInstrumentGroup (  #endif
53          qsamplerInstrumentGroup *pGroupItem, const QString& sName )  
54          : QListViewItem(pGroupItem, sName)  using namespace QSampler;
55  {  
56          QListViewItem::setRenameEnabled(0, true);  //----------------------------------------------------------------------
57    // class qsamplerInstrumentGroup -- custom group list view item.
58          QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png"));  //
59  }  
60    #if 0
61    // Constructors.
62  // Default destructor.  qsamplerInstrumentGroup::qsamplerInstrumentGroup (
63  qsamplerInstrumentGroup::~qsamplerInstrumentGroup (void)          qsamplerInstrumentList *pListView, const QString& sName,
64  {          QListViewItem *pItemAfter )
65  }          : QListViewItem(pListView, pItemAfter ? pItemAfter : pListView->lastItem())
66    {
67            QListViewItem::setRenameEnabled(0, true);
68  // Instance accessors.  
69  void qsamplerInstrumentGroup::setName ( const QString& sName )          QListViewItem::setPixmap(0, QPixmap(":/icons/itemGroup.png"));
70  {          QListViewItem::setText(0, sName);
71          QListViewItem::setText(0, sName);  }
72  }  
73    
74    qsamplerInstrumentGroup::qsamplerInstrumentGroup (
75  QString qsamplerInstrumentGroup::name (void) const          qsamplerInstrumentGroup *pGroupItem, const QString& sName )
76  {          : QListViewItem(pGroupItem, sName)
77          return QListViewItem::text(0);  {
78  }          QListViewItem::setRenameEnabled(0, true);
79    
80            QListViewItem::setPixmap(0, QPixmap(":/icons/itemGroup.png"));
81  qsamplerInstrumentGroup *qsamplerInstrumentGroup::groupItem (void) const  }
82  {  
83          QListViewItem *pParent = QListViewItem::parent();  
84          while (pParent && pParent->rtti() != qsamplerInstrumentList::Group)  // Default destructor.
85                  pParent = pParent->parent();  qsamplerInstrumentGroup::~qsamplerInstrumentGroup (void)
86          return static_cast<qsamplerInstrumentGroup *> (pParent);  {
87  }  }
88    
89    
90  qsamplerInstrumentList *qsamplerInstrumentGroup::listView (void) const  // Instance accessors.
91  {  void qsamplerInstrumentGroup::setName ( const QString& sName )
92          return static_cast<qsamplerInstrumentList *> (QListViewItem::listView());  {
93  }          QListViewItem::setText(0, sName);
94    }
95    
96  // To show up whether its open or not.  
97  void qsamplerInstrumentGroup::setOpen ( bool bOpen )  QString qsamplerInstrumentGroup::name (void) const
98  {  {
99          // Set the proper pixmap of this...          return QListViewItem::text(0);
100          if (rtti() == qsamplerInstrumentList::Group) {  }
101                  QListViewItem::setPixmap(0, QPixmap::fromMimeSource(  
102                          bOpen ? "itemGroupOpen.png" : "itemGroup.png"));  
103          }  qsamplerInstrumentGroup *qsamplerInstrumentGroup::groupItem (void) const
104          // Open it up...  {
105          QListViewItem::setOpen(bOpen);          QListViewItem *pParent = QListViewItem::parent();
106            while (pParent && pParent->rtti() != qsamplerInstrumentList::Group)
107          // All ancestors should be also visible.                  pParent = pParent->parent();
108          if (bOpen && QListViewItem::parent())          return static_cast<qsamplerInstrumentGroup *> (pParent);
109                  QListViewItem::parent()->setOpen(true);  }
110  }  
111    
112    qsamplerInstrumentList *qsamplerInstrumentGroup::listView (void) const
113  // To virtually distinguish between list view items.  {
114  int qsamplerInstrumentGroup::rtti (void) const          return static_cast<qsamplerInstrumentList *> (QListViewItem::listView());
115  {  }
116          return qsamplerInstrumentList::Group;  
117  }  
118    // To show up whether its open or not.
119    void qsamplerInstrumentGroup::setOpen ( bool bOpen )
120  //----------------------------------------------------------------------  {
121  // class qsamplerInstrumentItem -- custom file list view item.          // Set the proper pixmap of this...
122  //          if (rtti() == qsamplerInstrumentList::Group) {
123                    QListViewItem::setPixmap(0, QPixmap(bOpen ?
124  // Constructors.                          ":/icons/itemGroupOpen.png" : ":/icons/itemGroup.png"));
125  qsamplerInstrumentItem::qsamplerInstrumentItem (          }
126          qsamplerInstrumentList *pListView,          // Open it up...
127          qsamplerInstrument *pInstrument,          QListViewItem::setOpen(bOpen);
128          QListViewItem *pItemAfter )  
129          : qsamplerInstrumentGroup(pListView, pInstrument->name(), pItemAfter)          // All ancestors should be also visible.
130  {          if (bOpen && QListViewItem::parent())
131          m_pInstrument = pInstrument;                  QListViewItem::parent()->setOpen(true);
132    }
133          update();  
134  }  
135    // To virtually distinguish between list view items.
136  qsamplerInstrumentItem::qsamplerInstrumentItem (  int qsamplerInstrumentGroup::rtti (void) const
137          qsamplerInstrumentGroup *pGroupItem,  {
138          qsamplerInstrument *pInstrument )          return qsamplerInstrumentList::Group;
139          : qsamplerInstrumentGroup(pGroupItem, pInstrument->name())  }
140  {  
141          m_pInstrument = pInstrument;  
142    //----------------------------------------------------------------------
143          update();  // class qsamplerInstrumentItem -- custom file list view item.
144  }  //
145    
146    // Constructors.
147  // Default destructor.  qsamplerInstrumentItem::qsamplerInstrumentItem (
148  qsamplerInstrumentItem::~qsamplerInstrumentItem (void)          qsamplerInstrumentList *pListView,
149  {          qsamplerInstrument *pInstrument,
150          if (m_pInstrument)          QListViewItem *pItemAfter )
151                  delete m_pInstrument;          : qsamplerInstrumentGroup(pListView, pInstrument->name(), pItemAfter)
152  }  {
153            m_pInstrument = pInstrument;
154    
155  // To virtually distinguish between list view items.          update();
156  int qsamplerInstrumentItem::rtti (void) const  }
157  {  
158          return qsamplerInstrumentList::Item;  qsamplerInstrumentItem::qsamplerInstrumentItem (
159  }          qsamplerInstrumentGroup *pGroupItem,
160            qsamplerInstrument *pInstrument )
161            : qsamplerInstrumentGroup(pGroupItem, pInstrument->name())
162  // Payload accessor.  {
163  qsamplerInstrument *qsamplerInstrumentItem::Instrument (void) const          m_pInstrument = pInstrument;
164  {  
165          return m_pInstrument;          update();
166  }  }
167    
168    
169  // Item refreshment.  // Default destructor.
170  void qsamplerInstrumentItem::update (void)  qsamplerInstrumentItem::~qsamplerInstrumentItem (void)
171  {  {
172          QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemFile.png"));          if (m_pInstrument)
173                    delete m_pInstrument;
174          const QString s = "-";  }
175          if (m_pInstrument) {  
176                  setText(0, m_pInstrument->name());  
177                  setText(1, QString::number(m_pInstrument->bank()));  // To virtually distinguish between list view items.
178                  setText(2, QString::number(m_pInstrument->program()));  int qsamplerInstrumentItem::rtti (void) const
179                  setText(3, m_pInstrument->engineName());  {
180                  setText(4, QFileInfo(m_pInstrument->instrumentFile()).fileName());          return qsamplerInstrumentList::Item;
181                  setText(5, QString::number(m_pInstrument->instrumentNr()));  }
182                  setText(6, QString::number(int(m_pInstrument->volume() * 100.0f)));  
183                  QString sLoadMode = s;  
184                  switch (m_pInstrument->loadMode()) {  // Payload accessor.
185                  case 3:  qsamplerInstrument *qsamplerInstrumentItem::instrument (void) const
186                          sLoadMode = QObject::tr("Persistent");  {
187                          break;          return m_pInstrument;
188                  case 2:  }
189                          sLoadMode = QObject::tr("On Demand Hold");  
190                          break;  
191                  case 1:  // Item refreshment.
192                          sLoadMode = QObject::tr("On Demand");  void qsamplerInstrumentItem::update (void)
193                          break;  {
194                  }          QListViewItem::setPixmap(0, QPixmap(":/icons/itemFile.png"));
195                  setText(7, sLoadMode);  
196          } else {          const QString s = "-";
197                  for (int i = 0; i < listView()->columns(); i++)          if (m_pInstrument) {
198                          setText(i, s);                  setText(0, m_pInstrument->name());
199          }                  setText(1, QString::number(m_pInstrument->map()));
200  }                  setText(2, QString::number(m_pInstrument->bank()));
201                    setText(3, QString::number(m_pInstrument->prog() + 1));
202                    setText(4, m_pInstrument->engineName());
203  //----------------------------------------------------------------------------                  setText(5, QFileInfo(m_pInstrument->instrumentFile()).fileName());
204  // qsamplerInstrumentList -- MIDI instrument list view.                  setText(6, QString::number(m_pInstrument->instrumentNr()));
205  //                  setText(7, QString::number(::lroundf(100.0f * m_pInstrument->volume())));
206                    QString sLoadMode = s;
207  // Constructor.                  switch (m_pInstrument->loadMode()) {
208  qsamplerInstrumentList::qsamplerInstrumentList (                  case 3:
209          QWidget *pParent, const char *pszName )                          sLoadMode = QObject::tr("Persistent");
210          : QListView(pParent, pszName)                          break;
211  {                  case 2:
212  //  QListView::setRootIsDecorated(true);                          sLoadMode = QObject::tr("On Demand Hold");
213          QListView::setResizeMode(QListView::NoColumn);                          break;
214  //      QListView::setAcceptDrops(true);                  case 1:
215          QListView::setDragAutoScroll(true);                          sLoadMode = QObject::tr("On Demand");
216          QListView::setSizePolicy(                          break;
217                  QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));                  }
218  //      QListView::setShowToolTips(false);                  setText(8, sLoadMode);
219          QListView::setSortColumn(-1);          } else {
220                    for (int i = 0; i < listView()->columns(); i++)
221          QListView::addColumn(tr("Name"));                          setText(i, s);
222          QListView::addColumn(tr("Bank"));          }
223          QListView::addColumn(tr("Prog"));  }
224          QListView::addColumn(tr("Engine"));  
225          QListView::addColumn(tr("File"));  
226          QListView::addColumn(tr("Nr"));  //----------------------------------------------------------------------------
227          QListView::addColumn(tr("Vol"));  // qsamplerInstrumentList -- MIDI instrument list view.
228          QListView::addColumn(tr("Mode"));  //
229    
230          QListView::setColumnAlignment(1, Qt::AlignHCenter);     // Bank  // Constructor.
231          QListView::setColumnAlignment(2, Qt::AlignHCenter);     // Prog  qsamplerInstrumentList::qsamplerInstrumentList (
232          QListView::setColumnAlignment(5, Qt::AlignHCenter);     // Nr          QWidget *pParent, const char *pszName )
233          QListView::setColumnAlignment(6, Qt::AlignHCenter);     // Vol          : QListView(pParent, pszName)
234    {
235          QListView::setColumnWidth(0, 60);       // Name          m_iMidiMap = LSCP_MIDI_MAP_ALL;
236          QListView::setColumnWidth(0, 120);      // File  
237    //  QListView::setRootIsDecorated(true);
238          m_pNewGroupAction = new QAction(tr("New &Group"), tr("Ctrl+G"), this);          QListView::setAllColumnsShowFocus(true);
239          m_pNewItemAction  = new QAction(tr("New &Instrument..."), tr("Ctrl+I"), this);          QListView::setResizeMode(QListView::NoColumn);
240          m_pEditItemAction = new QAction(tr("&Edit..."), tr("Ctrl+E"), this);  //      QListView::setAcceptDrops(true);
241          m_pRenameAction   = new QAction(tr("&Rename"), tr("Ctrl+R"), this);          QListView::setDragAutoScroll(true);
242          m_pDeleteAction   = new QAction(tr("&Delete"), tr("Ctrl+D"), this);          QListView::setSizePolicy(
243          m_pRefreshAction  = new QAction(tr("Re&fresh"), tr("Ctrl+F"), this);                  QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
244    //      QListView::setShowToolTips(false);
245          QObject::connect(m_pNewGroupAction,          QListView::setSortColumn(-1);
246                  SIGNAL(activated()),  
247                  SLOT(newGroupSlot()));          QListView::addColumn(tr("Name"));
248          QObject::connect(m_pNewItemAction,          QListView::addColumn(tr("Map"));
249                  SIGNAL(activated()),          QListView::addColumn(tr("Bank"));
250                  SLOT(newItemSlot()));          QListView::addColumn(tr("Prog"));
251          QObject::connect(m_pEditItemAction,          QListView::addColumn(tr("Engine"));
252                  SIGNAL(activated()),          QListView::addColumn(tr("File"));
253                  SLOT(editItemSlot()));          QListView::addColumn(tr("Nr"));
254          QObject::connect(m_pRenameAction,          QListView::addColumn(tr("Vol"));
255                  SIGNAL(activated()),          QListView::addColumn(tr("Mode"));
256                  SLOT(renameSlot()));  
257          QObject::connect(m_pDeleteAction,          QListView::setColumnAlignment(1, Qt::AlignHCenter);     // Map
258                  SIGNAL(activated()),          QListView::setColumnAlignment(2, Qt::AlignHCenter);     // Bank
259                  SLOT(deleteSlot()));          QListView::setColumnAlignment(3, Qt::AlignHCenter);     // Prog
260          QObject::connect(m_pRefreshAction,          QListView::setColumnAlignment(6, Qt::AlignHCenter);     // Nr
261                  SIGNAL(activated()),          QListView::setColumnAlignment(7, Qt::AlignHCenter);     // Vol
262                  SLOT(refresh()));  
263            QListView::setColumnWidth(0, 120);      // Name
264          QObject::connect(this,          QListView::setColumnWidth(5, 240);      // File
265                  SIGNAL(selectionChanged()),  
266                  SLOT(selectionChangedSlot()));          m_pNewGroupAction = new QAction(
267          QObject::connect(this,                  QIcon(":/icons/itemGroupNew.png"),
268                  SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)),                  tr("New &Group"), tr("Ctrl+G"), this);
269                  SLOT(activatedSlot(QListViewItem*)));          m_pNewItemAction  = new QAction(
270          QObject::connect(this,                  QIcon(":/icons/itemNew.png"),
271                  SIGNAL(returnPressed(QListViewItem*)),                  tr("New &Instrument..."), tr("Ins"), this);
272                  SLOT(activatedSlot(QListViewItem*)));          m_pEditItemAction = new QAction(
273          QObject::connect(this,                  QIcon(":/icons/formEdit.png"),
274                  SIGNAL(itemRenamed(QListViewItem*,int)),                  tr("&Edit..."), tr("Enter"), this);
275                  SLOT(renamedSlot(QListViewItem*)));          m_pRenameAction   = new QAction(tr("&Rename"), tr("F2"), this);
276            m_pDeleteAction   = new QAction(
277          selectionChangedSlot();                  QIcon(":/icons/formRemove.png"),
278  }                  tr("&Delete"), tr("Del"), this);
279            m_pRefreshAction  = new QAction(
280                    QIcon(":/icons/formRefresh.png"),
281  // Default destructor.                  tr("Re&fresh"), tr("F5"), this);
282  qsamplerInstrumentList::~qsamplerInstrumentList (void)  
283  {          m_pNewGroupAction->setToolTip(tr("New Group"));
284          delete m_pNewGroupAction;          m_pNewItemAction->setToolTip(tr("New Instrument"));
285          delete m_pNewItemAction;          m_pEditItemAction->setToolTip(tr("Edit"));
286          delete m_pEditItemAction;          m_pRenameAction->setToolTip(tr("Rename"));
287          delete m_pRenameAction;          m_pDeleteAction->setToolTip(tr("Delete"));
288          delete m_pDeleteAction;          m_pRefreshAction->setToolTip(tr("Refresh"));
289  }  
290            QObject::connect(m_pNewGroupAction,
291                    SIGNAL(activated()),
292  // Add a new instrument item, optionally under a given group.                  SLOT(newGroupSlot()));
293  qsamplerInstrumentItem *qsamplerInstrumentList::addItem (          QObject::connect(m_pNewItemAction,
294          qsamplerInstrument *pInstrument,                  SIGNAL(activated()),
295          qsamplerInstrumentGroup *pParentGroup )                  SLOT(newItemSlot()));
296  {          QObject::connect(m_pEditItemAction,
297          qsamplerInstrumentItem *pItem = findItem(pInstrument);                  SIGNAL(activated()),
298          if (pItem == NULL) {                  SLOT(editItemSlot()));
299                  if (pParentGroup)          QObject::connect(m_pRenameAction,
300                          pItem = new qsamplerInstrumentItem(pParentGroup, pInstrument);                  SIGNAL(activated()),
301                  else                  SLOT(renameSlot()));
302                          pItem = new qsamplerInstrumentItem(this, pInstrument);          QObject::connect(m_pDeleteAction,
303          }                  SIGNAL(activated()),
304          QListView::setSelected(pItem, true);                  SLOT(deleteSlot()));
305          return pItem;          QObject::connect(m_pRefreshAction,
306  }                  SIGNAL(activated()),
307                    SLOT(refresh()));
308    
309  // Add a new instrument group, optionally under another group.          QObject::connect(this,
310  qsamplerInstrumentGroup *qsamplerInstrumentList::addGroup (                  SIGNAL(selectionChanged()),
311          const QString& sName, qsamplerInstrumentGroup *pParentGroup )                  SLOT(selectionChangedSlot()));
312  {          QObject::connect(this,
313          qsamplerInstrumentGroup *pGroup = findGroup(sName);                  SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)),
314          if (pGroup == NULL) {                  SLOT(activatedSlot(QListViewItem*)));
315                  if (pParentGroup)          QObject::connect(this,
316                          pGroup = new qsamplerInstrumentGroup(pParentGroup, sName);                  SIGNAL(returnPressed(QListViewItem*)),
317                  else                  SLOT(activatedSlot(QListViewItem*)));
318                          pGroup = new qsamplerInstrumentGroup(this, sName);          QObject::connect(this,
319          }                  SIGNAL(itemRenamed(QListViewItem*,int)),
320          QListView::setSelected(pGroup, true);                  SLOT(renamedSlot(QListViewItem*)));
321          return pGroup;  
322  }          selectionChangedSlot();
323    }
324    
325  // Find a group item, given its name.  
326  qsamplerInstrumentGroup *qsamplerInstrumentList::findGroup (  // Default destructor.
327          const QString& sName ) const  qsamplerInstrumentList::~qsamplerInstrumentList (void)
328  {  {
329          // Iterate all over the place to search for the group.          delete m_pNewGroupAction;
330          QListViewItemIterator iter((QListView *) this);          delete m_pNewItemAction;
331          while (iter.current()) {          delete m_pEditItemAction;
332                  QListViewItem *pItem = iter.current();          delete m_pRenameAction;
333                  if (pItem->rtti() == Group && pItem->text(0) == sName)          delete m_pDeleteAction;
334                          return static_cast<qsamplerInstrumentGroup *> (pItem);  }
335                  ++iter;  
336          }  
337          // Not found.  // Add a new instrument item, optionally under a given group.
338          return NULL;  qsamplerInstrumentItem *qsamplerInstrumentList::addItem (
339  }          qsamplerInstrument *pInstrument,
340            qsamplerInstrumentGroup *pParentGroup )
341    {
342  // Find a file item, given its name.          // Check it there's already one instrument item
343  qsamplerInstrumentItem *qsamplerInstrumentList::findItem (          // with the very same key (bank, program);
344          qsamplerInstrument *pInstrument ) const          // if yes, just remove it without prejudice...
345  {          qsamplerInstrumentItem *pItem = findItem(pInstrument);
346          // Iterate all over the place to search for the group.          if (pItem) {
347          QListViewItemIterator iter((QListView *) this);                  // If exactly the same, just update view and bail out...
348          while (iter.current()) {                  if (pItem->instrument() == pInstrument) {
349                  QListViewItem *pListItem = iter.current();                          pItem->update();
350                  if (pListItem->rtti() == Item) {                          return pItem;
351                          qsamplerInstrumentItem *pItem                  }
352                                  = static_cast<qsamplerInstrumentItem *> (pListItem);                  // Remove it, as instrument keys must be unique.
353                          if (pItem && pItem->Instrument() == pInstrument)                  delete pItem;
354                                  return pItem;          }
355                  }  
356                  ++iter;          // Add the new item under proper group one, if any...
357          }          if (pParentGroup) {
358          // Not found.                  pParentGroup->setOpen(true);
359          return NULL;                  pItem = new qsamplerInstrumentItem(pParentGroup, pInstrument);
360  }          } else {
361                    pItem = new qsamplerInstrumentItem(this, pInstrument);
362            }
363  // Find and return the nearest group item...  
364  qsamplerInstrumentGroup *qsamplerInstrumentList::groupItem (          // Set it as current selection...
365          QListViewItem *pItem ) const          QListView::setSelected(pItem, true);
366  {  
367          while (pItem && pItem->rtti() != Group)          return pItem;
368                  pItem = pItem->parent();  }
369          return static_cast<qsamplerInstrumentGroup *> (pItem);  
370  }  
371    // Add a new instrument group, optionally under another group.
372    qsamplerInstrumentGroup *qsamplerInstrumentList::addGroup (
373  // Add a new group item below the current one.          const QString& sName, qsamplerInstrumentGroup *pParentGroup )
374  void qsamplerInstrumentList::newGroupSlot (void)  {
375  {          qsamplerInstrumentGroup *pGroup = findGroup(sName);
376          qsamplerInstrumentGroup *pParentGroup          if (pGroup == NULL) {
377                  = groupItem(QListView::selectedItem());                  if (pParentGroup) {
378          qsamplerInstrumentGroup *pNewGroup                          pParentGroup->setOpen(true);
379                  = addGroup(tr("New Group"), pParentGroup);                          pGroup = new qsamplerInstrumentGroup(pParentGroup, sName);
380          if (pParentGroup)                  } else {
381                  pParentGroup->setOpen(true);                          pGroup = new qsamplerInstrumentGroup(this, sName);
382          if (pNewGroup)                  }
383                  pNewGroup->startRename(0);          }
384            QListView::setSelected(pGroup, true);
385          selectionChangedSlot();          return pGroup;
386  }  }
387    
388    
389  // Add a new instrument item below the current one.  // Find a group item, given its name.
390  void qsamplerInstrumentList::newItemSlot (void)  qsamplerInstrumentGroup *qsamplerInstrumentList::findGroup (
391  {          const QString& sName ) const
392          qsamplerInstrument *pInstrument = new qsamplerInstrument();  {
393            // Iterate all over the place to search for the group.
394          qsamplerInstrumentForm form(this);          QListViewItemIterator iter((QListView *) this);
395          form.setup(pInstrument);          while (iter.current()) {
396          if (!form.exec()) {                  QListViewItem *pItem = iter.current();
397                  delete pInstrument;                  if (pItem->rtti() == Group && pItem->text(0) == sName)
398                  return;                          return static_cast<qsamplerInstrumentGroup *> (pItem);
399          }                  ++iter;
400            }
401          pInstrument->map();          // Not found.
402          emit instrumentsChanged();          return NULL;
403    }
404          qsamplerInstrumentGroup *pParentGroup  
405                  = groupItem(QListView::selectedItem());  
406          addItem(pInstrument, pParentGroup);  // Find a file item, given its name.
407          if (pParentGroup)  qsamplerInstrumentItem *qsamplerInstrumentList::findItem (
408                  pParentGroup->setOpen(true);          qsamplerInstrument *pInstrument ) const
409    {
410          selectionChangedSlot();          if (pInstrument == NULL)
411  }                  return NULL;
412    
413            // Iterate all over the place to search for the group.
414  // Edit current item below the current one.          QListViewItemIterator iter((QListView *) this);
415  void qsamplerInstrumentList::editItemSlot (void)          while (iter.current()) {
416  {                  QListViewItem *pListItem = iter.current();
417          QListViewItem *pListItem = QListView::selectedItem();                  if (pListItem->rtti() == Item) {
418          if (pListItem == NULL)                          qsamplerInstrumentItem *pItem
419                  return;                                  = static_cast<qsamplerInstrumentItem *> (pListItem);
420          if (pListItem->rtti() == Item) {                          if (pItem && pItem->instrument()
421                  qsamplerInstrumentItem *pItem                                  && pItem->instrument()->map()  == pInstrument->map()
422                          = static_cast<qsamplerInstrumentItem *> (pListItem);                                  && pItem->instrument()->bank() == pInstrument->bank()
423                  if (pItem && pItem->Instrument()) {                                  && pItem->instrument()->prog() == pInstrument->prog())
424                          qsamplerInstrumentForm form(this);                                  return pItem;
425                          form.setup(pItem->Instrument());                  }
426                          if (form.exec()) {                  ++iter;
427                                  pItem->Instrument()->map();          }
428                                  emit instrumentsChanged();          // Not found.
429                                  pItem->update();          return NULL;
430                          }  }
431                  }  
432          }  
433    // Find and return the nearest group item...
434          selectionChangedSlot();  qsamplerInstrumentGroup *qsamplerInstrumentList::groupItem (
435  }          QListViewItem *pItem ) const
436    {
437            while (pItem && pItem->rtti() != Group)
438  // Rename current group/item.                  pItem = pItem->parent();
439  void qsamplerInstrumentList::renameSlot (void)          return static_cast<qsamplerInstrumentGroup *> (pItem);
440  {  }
441          QListViewItem *pListItem = QListView::selectedItem();  
442          if (pListItem)  
443                  pListItem->startRename(0);  // Add a new group item below the current one.
444    void qsamplerInstrumentList::newGroupSlot (void)
445          selectionChangedSlot();  {
446  }          qsamplerInstrumentGroup *pNewGroup
447                    = addGroup(tr("New Group"), groupItem(QListView::selectedItem()));
448            if (pNewGroup)
449  // Remove current group/item.                  pNewGroup->startRename(0);
450  void qsamplerInstrumentList::deleteSlot (void)  
451  {          selectionChangedSlot();
452          QListViewItem *pListItem = QListView::selectedItem();  }
453          if (pListItem) {  
454                  if (pListItem->rtti() == Item) {  
455                          qsamplerInstrumentItem *pItem  // Map selector.
456                                  = static_cast<qsamplerInstrumentItem *> (pListItem);  void qsamplerInstrumentList::setMidiMap ( int iMidiMap )
457                          if (pItem && pItem->Instrument()) {  {
458                                  pItem->Instrument()->unmap();          if (iMidiMap < 0)
459                                  emit instrumentsChanged();                  iMidiMap = LSCP_MIDI_MAP_ALL;
460                          }  
461                  }          m_iMidiMap = iMidiMap;
462                  delete pListItem;  }
463          }  
464    int qsamplerInstrumentList::midiMap (void) const
465          selectionChangedSlot();  {
466  }          return m_iMidiMap;
467    }
468    
469  // In-place selection slot.  
470  void qsamplerInstrumentList::selectionChangedSlot (void)  // List actions accessors.
471  {  QAction *qsamplerInstrumentList::newGroupAction (void) const
472          qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();  {
473          QListViewItem *pListItem = QListView::selectedItem();          return m_pNewGroupAction;
474          bool bEnabled = (pMainForm && pMainForm->client());  }
475          m_pNewItemAction->setEnabled(bEnabled);  
476          bEnabled = (bEnabled && pListItem != NULL);  QAction *qsamplerInstrumentList::newItemAction (void) const
477          m_pEditItemAction->setEnabled(bEnabled && pListItem->rtti() == Item);  {
478          m_pRenameAction->setEnabled(bEnabled);          return m_pNewItemAction;
479          m_pDeleteAction->setEnabled(bEnabled);  }
480  }  
481    QAction *qsamplerInstrumentList::editItemAction (void) const
482    {
483  // In-place activation slot.          return m_pEditItemAction;
484  void qsamplerInstrumentList::activatedSlot ( QListViewItem *pListItem )  }
485  {  
486          // FIXME: Hope the list view item is the one selected.  QAction *qsamplerInstrumentList::renameAction (void) const
487          if (pListItem->rtti() == Item)  {
488                  editItemSlot();          return m_pRenameAction;
489  }  }
490    
491    QAction *qsamplerInstrumentList::deleteAction (void) const
492  // In-place aliasing slot.  {
493  void qsamplerInstrumentList::renamedSlot ( QListViewItem *pListItem )          return m_pDeleteAction;
494  {  }
495          if (pListItem->rtti() == Item) {  
496                  qsamplerInstrumentItem *pItem  QAction *qsamplerInstrumentList::refreshAction (void) const
497                          = static_cast<qsamplerInstrumentItem *> (pListItem);  {
498                  if (pItem && pItem->Instrument()) {          return m_pRefreshAction;
499                          pItem->Instrument()->setName(pListItem->text(0));  }
500                          pItem->Instrument()->map();  
501                          emit instrumentsChanged();  
502                          pItem->update();  // Add a new instrument item below the current one.
503                  }  void qsamplerInstrumentList::newItemSlot (void)
504          }  {
505  }          qsamplerInstrument *pInstrument = new qsamplerInstrument();
506    
507            qsamplerInstrumentForm form(this);
508  // Context menu request event handler.          form.setup(pInstrument);
509  void qsamplerInstrumentList::contextMenuEvent (          if (!form.exec()) {
510          QContextMenuEvent *pContextMenuEvent )                  delete pInstrument;
511  {                  return;
512          QPopupMenu menu(this);          }
513    
514          // Construct context menu.          // Commit...
515          m_pNewItemAction->addTo(&menu);          pInstrument->mapInstrument();
516  //      m_pNewGroupAction->addTo(&menu);          // add new item to the tree...
517          menu.insertSeparator();          addItem(pInstrument, groupItem(QListView::selectedItem()));
518          m_pEditItemAction->addTo(&menu);          // Notify we've changes...
519          m_pRenameAction->addTo(&menu);          emit instrumentsChanged();
520          m_pDeleteAction->addTo(&menu);  
521          menu.insertSeparator();          selectionChangedSlot();
522          m_pRefreshAction->addTo(&menu);  }
523    
524          menu.exec(pContextMenuEvent->globalPos());  
525  }  // Edit current item below the current one.
526    void qsamplerInstrumentList::editItemSlot (void)
527    {
528  // General reloader.          QListViewItem *pListItem = QListView::selectedItem();
529  void qsamplerInstrumentList::refresh (void)          if (pListItem == NULL)
530  {                  return;
531          clear();          if (pListItem->rtti() == Item) {
532                    qsamplerInstrument *pInstrument = NULL;
533          qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();                  qsamplerInstrumentItem *pItem
534          if (pMainForm == NULL)                          = static_cast<qsamplerInstrumentItem *> (pListItem);
535                  return;                  if (pItem)
536          if (pMainForm->client() == NULL)                          pInstrument = pItem->instrument();
537                  return;                  if (pInstrument) {
538                            // Save current key values...
539          qsamplerInstrumentItem *pItem = NULL;                          qsamplerInstrument oldInstrument(*pInstrument);
540          lscp_midi_instrument_t *pInstrs                          // Do the edit dance...
541                  = ::lscp_list_midi_instruments(pMainForm->client());                          qsamplerInstrumentForm form(this);
542          for (int iInstr = 0; pInstrs && pInstrs[iInstr].program >= 0; ++iInstr) {                          form.setup(pInstrument);
543                  int iBank = (pInstrs[iInstr].bank_msb << 7) | pInstrs[iInstr].bank_lsb;                          if (form.exec()) {
544                  int iProgram = pInstrs[iInstr].program;                                  // Commit...
545                  qsamplerInstrument *pInstrument                                  pInstrument->mapInstrument();
546                          = new qsamplerInstrument(iBank, iProgram);                                  // Check whether we changed instrument key...
547                  if (pInstrument->get())                                  if (oldInstrument.map()  == pInstrument->map()  &&
548                          pItem = new qsamplerInstrumentItem(this, pInstrument, pItem);                                          oldInstrument.bank() == pInstrument->bank() &&
549          }                                          oldInstrument.prog() == pInstrument->prog()) {
550                                            // just update tree item...
551          if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {                                          pItem->update();
552                  pMainForm->appendMessagesClient("lscp_list_midi_instruments");                                  } else {
553                  pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));                                          // Unmap old instance...
554          }                                          oldInstrument.unmapInstrument();
555                                            // Change item tree, whether applicable...
556          selectionChangedSlot();                                          if (m_iMidiMap < 0 || m_iMidiMap == pInstrument->map()) {
557  }                                                  // Add new brand item into view...
558                                                    addItem(pInstrument, groupItem(pListItem));
559                                            } else {
560  // end of qsamplerInstrumentList.cpp                                                  // Just remove/hide old one.
561                                                    delete pItem;
562                                            }
563                                    }
564                                    // Notify we've changes...
565                                    emit instrumentsChanged();
566                            }
567                    }
568            }
569    
570            selectionChangedSlot();
571    }
572    
573    
574    // Rename current group/item.
575    void qsamplerInstrumentList::renameSlot (void)
576    {
577            QListViewItem *pListItem = QListView::selectedItem();
578            if (pListItem)
579                    pListItem->startRename(0);
580    
581            selectionChangedSlot();
582    }
583    
584    
585    // Remove current group/item.
586    void qsamplerInstrumentList::deleteSlot (void)
587    {
588            QListViewItem *pListItem = QListView::selectedItem();
589            if (pListItem == NULL)
590                    return;
591    
592            qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
593            if (pMainForm == NULL)
594                    return;
595    
596            // Prompt user if this is for real...
597            qsamplerOptions *pOptions = pMainForm->options();
598            if (pOptions && pOptions->bConfirmRemove) {
599                    if (QMessageBox::warning(this,
600                            QSAMPLER_TITLE ": " + tr("Warning"),
601                            tr("Delete %1:\n\n"
602                            "%2\n\n"
603                            "Are you sure?")
604                            .arg(pListItem->rtti() == Item ? tr("instrument") : tr("group"))
605                            .arg(pListItem->text(0)),
606                            tr("OK"), tr("Cancel")) > 0)
607                            return;
608            }
609    
610            // Unmap instrument entry...
611            if (pListItem->rtti() == Item) {
612                    qsamplerInstrumentItem *pItem
613                            = static_cast<qsamplerInstrumentItem *> (pListItem);
614                    if (pItem && pItem->instrument()) {
615                            pItem->instrument()->unmapInstrument();
616                            emit instrumentsChanged();
617                    }
618            }
619    
620            // Do it for real...
621            delete pListItem;
622    
623            selectionChangedSlot();
624    }
625    
626    
627    // In-place selection slot.
628    void qsamplerInstrumentList::selectionChangedSlot (void)
629    {
630            qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
631            QListViewItem *pListItem = QListView::selectedItem();
632            bool bEnabled = (pMainForm && pMainForm->client());
633            m_pNewItemAction->setEnabled(bEnabled);
634            bEnabled = (bEnabled && pListItem != NULL);
635            m_pEditItemAction->setEnabled(bEnabled && pListItem->rtti() == Item);
636            m_pRenameAction->setEnabled(bEnabled);
637            m_pDeleteAction->setEnabled(bEnabled);
638    }
639    
640    
641    // In-place activation slot.
642    void qsamplerInstrumentList::activatedSlot ( QListViewItem *pListItem )
643    {
644            // FIXME: Hope the list view item is the one selected.
645            if (pListItem && pListItem->rtti() == Item)
646                    editItemSlot();
647    }
648    
649    
650    // In-place aliasing slot.
651    void qsamplerInstrumentList::renamedSlot ( QListViewItem *pListItem )
652    {
653            if (pListItem->rtti() == Item) {
654                    qsamplerInstrumentItem *pItem
655                            = static_cast<qsamplerInstrumentItem *> (pListItem);
656                    if (pItem && pItem->instrument()) {
657                            pItem->instrument()->setName(pListItem->text(0));
658                            pItem->instrument()->mapInstrument();
659                            emit instrumentsChanged();
660                            pItem->update();
661                    }
662            }
663    }
664    
665    
666    // Context menu request event handler.
667    void qsamplerInstrumentList::contextMenuEvent (
668            QContextMenuEvent *pContextMenuEvent )
669    {
670            if (!m_pNewItemAction->isEnabled())
671                    return;
672    
673            QPopupMenu menu(this);
674    
675            // Construct context menu.
676            m_pNewItemAction->addTo(&menu);
677    //      m_pNewGroupAction->addTo(&menu);
678            menu.insertSeparator();
679            m_pEditItemAction->addTo(&menu);
680            m_pRenameAction->addTo(&menu);
681            m_pDeleteAction->addTo(&menu);
682            menu.insertSeparator();
683            m_pRefreshAction->addTo(&menu);
684    
685            menu.exec(pContextMenuEvent->globalPos());
686    }
687    
688    
689    // General reloader.
690    void qsamplerInstrumentList::refresh (void)
691    {
692            clear();
693    
694            qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
695            if (pMainForm == NULL)
696                    return;
697            if (pMainForm->client() == NULL)
698                    return;
699    
700            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
701    
702            // Load the whole bunch of instrument items...
703            qsamplerInstrumentItem *pItem = NULL;
704            lscp_midi_instrument_t *pInstrs
705                    = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
706            for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
707                    int iMap  = pInstrs[iInstr].map;
708                    int iBank = pInstrs[iInstr].bank;
709                    int iProg = pInstrs[iInstr].prog;
710                    qsamplerInstrument *pInstrument
711                            = new qsamplerInstrument(iMap, iBank, iProg);
712                    if (pInstrument->getInstrument())
713                            pItem = new qsamplerInstrumentItem(this, pInstrument, pItem);
714                    // Try to keep it snappy :)
715                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
716            }
717    
718            QApplication::restoreOverrideCursor();
719    
720            if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
721                    pMainForm->appendMessagesClient("lscp_list_midi_instruments");
722                    pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
723            }
724    
725            selectionChangedSlot();
726    }
727    #endif
728    
729    MidiInstrumentsModel::MidiInstrumentsModel(QObject* parent) : QAbstractTableModel(parent) {
730        m_iMidiMap = LSCP_MIDI_MAP_ALL;
731    }
732    
733    int MidiInstrumentsModel::rowCount(const QModelIndex& /*parent*/) const {
734        if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
735            int n = 0;
736            for (InstrumentsMap::const_iterator itMap = instruments.begin(); itMap != instruments.end(); ++itMap)
737                n += (*itMap).size();
738            return n;
739        }
740        InstrumentsMap::const_iterator itMap = instruments.find(m_iMidiMap);
741        if (itMap == instruments.end()) return 0;
742        return (*itMap).size();
743    }
744    
745    int MidiInstrumentsModel::columnCount(const QModelIndex& /*parent*/) const {
746        return 9;
747    }
748    
749    QVariant MidiInstrumentsModel::data(const QModelIndex &index, int role) const {
750        if (!index.isValid() || role != Qt::DisplayRole) return QVariant();
751    
752        if (m_iMidiMap == LSCP_MIDI_MAP_ALL) {
753            int n = 0;
754            for (InstrumentsMap::const_iterator itMap = instruments.begin(); itMap != instruments.end(); ++itMap) {
755                n += (*itMap).size();
756                if (index.row() < n)
757                    return QVariant::fromValue(
758                        (*itMap)[index.row() + (*itMap).size() - n]
759                    );
760            }
761        } else {
762            // resolve MIDI instrument map
763            InstrumentsMap::const_iterator itMap = instruments.find(m_iMidiMap);
764            if (itMap == instruments.end()) return QVariant();
765            // resolve instrument in that map
766            if (index.row() >= (*itMap).size()) return QVariant();
767            return QVariant::fromValue(
768                (*itMap)[index.row()]
769            );
770        }
771    
772        return QVariant();
773    }
774    
775    QVariant MidiInstrumentsModel::headerData(int section, Qt::Orientation orientation, int role) const {
776        if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
777            return QVariant();
778    
779        switch (section) {
780            case 0: return tr("Name");
781            case 1: return tr("Map");
782            case 2: return tr("Bank");
783            case 3: return tr("Prog");
784            case 4: return tr("Engine");
785            case 5: return tr("File");
786            case 6: return tr("Nr");
787            case 7: return tr("Vol");
788            case 8: return tr("Mode");
789            default: return QVariant();
790        }
791    }
792    
793    qsamplerInstrument* MidiInstrumentsModel::addInstrument(int iMap, int iBank, int iProg) {
794        // Check it there's already one instrument item
795        // with the very same key (bank, program);
796        // if yes, just remove it without prejudice...
797        for (int i = 0; i < instruments[iMap].size(); i++) {
798            if (
799                instruments[iMap][i].bank() == iBank &&
800                instruments[iMap][i].prog() == iProg
801            ) {
802                instruments[iMap].removeAt(i);
803                break;
804            }
805        }
806    
807        // resolve the appropriate place, we keep the list sorted that way ...
808        int i = 0;
809        for (; i < instruments[iMap].size(); i++)
810            if (
811                iBank > instruments[iMap][i].bank() ||
812                ( iBank == instruments[iMap][i].bank() &&
813                  iProg > instruments[iMap][i].prog() )
814            ) break;
815    
816        qsamplerInstrument& instr = instruments[iMap][i] = qsamplerInstrument(iMap, iBank, iProg);
817    
818        return &instr;
819    }
820    
821    void MidiInstrumentsModel::setMidiMap(int iMidiMap) {
822        if (iMidiMap < 0)
823            iMidiMap = LSCP_MIDI_MAP_ALL;
824    
825        m_iMidiMap = iMidiMap;
826    }
827    
828    int MidiInstrumentsModel::midiMap() const {
829        return m_iMidiMap;
830    }
831    
832    void MidiInstrumentsModel::refresh() {
833            instruments.clear();
834    
835            MainForm* pMainForm = MainForm::getInstance();
836            if (pMainForm == NULL)
837                    return;
838            if (pMainForm->client() == NULL)
839                    return;
840    
841            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
842    
843            // Load the whole bunch of instrument items...
844            lscp_midi_instrument_t* pInstrs
845                    = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap);
846            for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) {
847                    const int iMap  = pInstrs[iInstr].map;
848                    const int iBank = pInstrs[iInstr].bank;
849                    const int iProg = pInstrs[iInstr].prog;
850                    addInstrument(iMap, iBank, iProg);
851                    // Try to keep it snappy :)
852                    QApplication::processEvents(QEventLoop::ExcludeUserInput);
853            }
854    
855            QApplication::restoreOverrideCursor();
856    
857            if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) {
858                    pMainForm->appendMessagesClient("lscp_list_midi_instruments");
859                    pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry."));
860            }
861    
862            //selectionChangedSlot();
863    }
864    
865    
866    MidiInstrumentsDelegate::MidiInstrumentsDelegate(QObject* parent) : QItemDelegate(parent) {
867    }
868    
869    QWidget* MidiInstrumentsDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
870        return new QLabel(index.model()->data(index, Qt::DisplayRole).toString(), parent);
871    }
872    
873    void MidiInstrumentsDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
874    }
875    
876    void MidiInstrumentsDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
877    }
878    
879    void MidiInstrumentsDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
880        if (editor) editor->setGeometry(option.rect);
881    }
882    
883    
884    // end of qsamplerInstrumentList.cpp

Legend:
Removed from v.962  
changed lines
  Added in v.1464

  ViewVC Help
Powered by ViewVC