--- qsampler/trunk/src/qsamplerInstrumentList.cpp 2006/12/06 19:38:02 969 +++ qsampler/trunk/src/qsamplerInstrumentList.cpp 2010/03/15 10:45:35 2069 @@ -1,574 +1,417 @@ -// qsamplerInstrumentList.cpp -// -/**************************************************************************** - Copyright (C) 2003-2005, rncbc aka Rui Nuno Capela. All rights reserved. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*****************************************************************************/ - -#include "qsamplerAbout.h" -#include "qsamplerInstrumentList.h" - -#include "qsamplerInstrument.h" -#include "qsamplerInstrumentForm.h" - -#include "qsamplerMainForm.h" - -#include -#include -#include - -// Needed for lroundf() -#include - - -//---------------------------------------------------------------------- -// class qsamplerInstrumentGroup -- custom group list view item. -// - -// Constructors. -qsamplerInstrumentGroup::qsamplerInstrumentGroup ( - qsamplerInstrumentList *pListView, const QString& sName, - QListViewItem *pItemAfter ) - : QListViewItem(pListView, pItemAfter ? pItemAfter : pListView->lastItem()) -{ - QListViewItem::setRenameEnabled(0, true); - - QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png")); - QListViewItem::setText(0, sName); -} - - -qsamplerInstrumentGroup::qsamplerInstrumentGroup ( - qsamplerInstrumentGroup *pGroupItem, const QString& sName ) - : QListViewItem(pGroupItem, sName) -{ - QListViewItem::setRenameEnabled(0, true); - - QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemGroup.png")); -} - - -// Default destructor. -qsamplerInstrumentGroup::~qsamplerInstrumentGroup (void) -{ -} - - -// Instance accessors. -void qsamplerInstrumentGroup::setName ( const QString& sName ) -{ - QListViewItem::setText(0, sName); -} - - -QString qsamplerInstrumentGroup::name (void) const -{ - return QListViewItem::text(0); -} - - -qsamplerInstrumentGroup *qsamplerInstrumentGroup::groupItem (void) const -{ - QListViewItem *pParent = QListViewItem::parent(); - while (pParent && pParent->rtti() != qsamplerInstrumentList::Group) - pParent = pParent->parent(); - return static_cast (pParent); -} - - -qsamplerInstrumentList *qsamplerInstrumentGroup::listView (void) const -{ - return static_cast (QListViewItem::listView()); -} - - -// To show up whether its open or not. -void qsamplerInstrumentGroup::setOpen ( bool bOpen ) -{ - // Set the proper pixmap of this... - if (rtti() == qsamplerInstrumentList::Group) { - QListViewItem::setPixmap(0, QPixmap::fromMimeSource( - bOpen ? "itemGroupOpen.png" : "itemGroup.png")); - } - // Open it up... - QListViewItem::setOpen(bOpen); - - // All ancestors should be also visible. - if (bOpen && QListViewItem::parent()) - QListViewItem::parent()->setOpen(true); -} - - -// To virtually distinguish between list view items. -int qsamplerInstrumentGroup::rtti (void) const -{ - return qsamplerInstrumentList::Group; -} - - -//---------------------------------------------------------------------- -// class qsamplerInstrumentItem -- custom file list view item. -// - -// Constructors. -qsamplerInstrumentItem::qsamplerInstrumentItem ( - qsamplerInstrumentList *pListView, - qsamplerInstrument *pInstrument, - QListViewItem *pItemAfter ) - : qsamplerInstrumentGroup(pListView, pInstrument->name(), pItemAfter) -{ - m_pInstrument = pInstrument; - - update(); -} - -qsamplerInstrumentItem::qsamplerInstrumentItem ( - qsamplerInstrumentGroup *pGroupItem, - qsamplerInstrument *pInstrument ) - : qsamplerInstrumentGroup(pGroupItem, pInstrument->name()) -{ - m_pInstrument = pInstrument; - - update(); -} - - -// Default destructor. -qsamplerInstrumentItem::~qsamplerInstrumentItem (void) -{ - if (m_pInstrument) - delete m_pInstrument; -} - - -// To virtually distinguish between list view items. -int qsamplerInstrumentItem::rtti (void) const -{ - return qsamplerInstrumentList::Item; -} - - -// Payload accessor. -qsamplerInstrument *qsamplerInstrumentItem::instrument (void) const -{ - return m_pInstrument; -} - - -// Item refreshment. -void qsamplerInstrumentItem::update (void) -{ - QListViewItem::setPixmap(0, QPixmap::fromMimeSource("itemFile.png")); - - const QString s = "-"; - if (m_pInstrument) { - setText(0, m_pInstrument->name()); - setText(1, QString::number(m_pInstrument->bank())); - setText(2, QString::number(m_pInstrument->program())); - setText(3, m_pInstrument->engineName()); - setText(4, QFileInfo(m_pInstrument->instrumentFile()).fileName()); - setText(5, QString::number(m_pInstrument->instrumentNr())); - setText(6, QString::number(::lroundf(100.0f * m_pInstrument->volume()))); - QString sLoadMode = s; - switch (m_pInstrument->loadMode()) { - case 3: - sLoadMode = QObject::tr("Persistent"); - break; - case 2: - sLoadMode = QObject::tr("On Demand Hold"); - break; - case 1: - sLoadMode = QObject::tr("On Demand"); - break; - } - setText(7, sLoadMode); - } else { - for (int i = 0; i < listView()->columns(); i++) - setText(i, s); - } -} - - -//---------------------------------------------------------------------------- -// qsamplerInstrumentList -- MIDI instrument list view. -// - -// Constructor. -qsamplerInstrumentList::qsamplerInstrumentList ( - QWidget *pParent, const char *pszName ) - : QListView(pParent, pszName) -{ -// QListView::setRootIsDecorated(true); - QListView::setResizeMode(QListView::NoColumn); -// QListView::setAcceptDrops(true); - QListView::setDragAutoScroll(true); - QListView::setSizePolicy( - QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); -// QListView::setShowToolTips(false); - QListView::setSortColumn(-1); - - QListView::addColumn(tr("Name")); - QListView::addColumn(tr("Bank")); - QListView::addColumn(tr("Prog")); - QListView::addColumn(tr("Engine")); - QListView::addColumn(tr("File")); - QListView::addColumn(tr("Nr")); - QListView::addColumn(tr("Vol")); - QListView::addColumn(tr("Mode")); - - QListView::setColumnAlignment(1, Qt::AlignHCenter); // Bank - QListView::setColumnAlignment(2, Qt::AlignHCenter); // Prog - QListView::setColumnAlignment(5, Qt::AlignHCenter); // Nr - QListView::setColumnAlignment(6, Qt::AlignHCenter); // Vol - - QListView::setColumnWidth(0, 60); // Name - QListView::setColumnWidth(0, 120); // File - - m_pNewGroupAction = new QAction(tr("New &Group"), tr("Ctrl+G"), this); - m_pNewItemAction = new QAction(tr("New &Instrument..."), tr("Ctrl+I"), this); - m_pEditItemAction = new QAction(tr("&Edit..."), tr("Ctrl+E"), this); - m_pRenameAction = new QAction(tr("&Rename"), tr("Ctrl+R"), this); - m_pDeleteAction = new QAction(tr("&Delete"), tr("Ctrl+D"), this); - m_pRefreshAction = new QAction(tr("Re&fresh"), tr("Ctrl+F"), this); - - QObject::connect(m_pNewGroupAction, - SIGNAL(activated()), - SLOT(newGroupSlot())); - QObject::connect(m_pNewItemAction, - SIGNAL(activated()), - SLOT(newItemSlot())); - QObject::connect(m_pEditItemAction, - SIGNAL(activated()), - SLOT(editItemSlot())); - QObject::connect(m_pRenameAction, - SIGNAL(activated()), - SLOT(renameSlot())); - QObject::connect(m_pDeleteAction, - SIGNAL(activated()), - SLOT(deleteSlot())); - QObject::connect(m_pRefreshAction, - SIGNAL(activated()), - SLOT(refresh())); - - QObject::connect(this, - SIGNAL(selectionChanged()), - SLOT(selectionChangedSlot())); - QObject::connect(this, - SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)), - SLOT(activatedSlot(QListViewItem*))); - QObject::connect(this, - SIGNAL(returnPressed(QListViewItem*)), - SLOT(activatedSlot(QListViewItem*))); - QObject::connect(this, - SIGNAL(itemRenamed(QListViewItem*,int)), - SLOT(renamedSlot(QListViewItem*))); - - selectionChangedSlot(); -} - - -// Default destructor. -qsamplerInstrumentList::~qsamplerInstrumentList (void) -{ - delete m_pNewGroupAction; - delete m_pNewItemAction; - delete m_pEditItemAction; - delete m_pRenameAction; - delete m_pDeleteAction; -} - - -// Add a new instrument item, optionally under a given group. -qsamplerInstrumentItem *qsamplerInstrumentList::addItem ( - qsamplerInstrument *pInstrument, - qsamplerInstrumentGroup *pParentGroup ) -{ - qsamplerInstrumentItem *pItem = findItem(pInstrument); - if (pItem == NULL) { - if (pParentGroup) - pItem = new qsamplerInstrumentItem(pParentGroup, pInstrument); - else - pItem = new qsamplerInstrumentItem(this, pInstrument); - } - QListView::setSelected(pItem, true); - return pItem; -} - - -// Add a new instrument group, optionally under another group. -qsamplerInstrumentGroup *qsamplerInstrumentList::addGroup ( - const QString& sName, qsamplerInstrumentGroup *pParentGroup ) -{ - qsamplerInstrumentGroup *pGroup = findGroup(sName); - if (pGroup == NULL) { - if (pParentGroup) - pGroup = new qsamplerInstrumentGroup(pParentGroup, sName); - else - pGroup = new qsamplerInstrumentGroup(this, sName); - } - QListView::setSelected(pGroup, true); - return pGroup; -} - - -// Find a group item, given its name. -qsamplerInstrumentGroup *qsamplerInstrumentList::findGroup ( - const QString& sName ) const -{ - // Iterate all over the place to search for the group. - QListViewItemIterator iter((QListView *) this); - while (iter.current()) { - QListViewItem *pItem = iter.current(); - if (pItem->rtti() == Group && pItem->text(0) == sName) - return static_cast (pItem); - ++iter; - } - // Not found. - return NULL; -} - - -// Find a file item, given its name. -qsamplerInstrumentItem *qsamplerInstrumentList::findItem ( - qsamplerInstrument *pInstrument ) const -{ - if (pInstrument == NULL) - return NULL; - - // Iterate all over the place to search for the group. - QListViewItemIterator iter((QListView *) this); - while (iter.current()) { - QListViewItem *pListItem = iter.current(); - if (pListItem->rtti() == Item) { - qsamplerInstrumentItem *pItem - = static_cast (pListItem); - if (pItem && pItem->instrument() - && pItem->instrument()->bank() == pInstrument->bank() - && pItem->instrument()->program() == pInstrument->program()) - return pItem; - } - ++iter; - } - // Not found. - return NULL; -} - - -// Find and return the nearest group item... -qsamplerInstrumentGroup *qsamplerInstrumentList::groupItem ( - QListViewItem *pItem ) const -{ - while (pItem && pItem->rtti() != Group) - pItem = pItem->parent(); - return static_cast (pItem); -} - - -// Add a new group item below the current one. -void qsamplerInstrumentList::newGroupSlot (void) -{ - qsamplerInstrumentGroup *pParentGroup - = groupItem(QListView::selectedItem()); - qsamplerInstrumentGroup *pNewGroup - = addGroup(tr("New Group"), pParentGroup); - if (pParentGroup) - pParentGroup->setOpen(true); - if (pNewGroup) - pNewGroup->startRename(0); - - selectionChangedSlot(); -} - - -// Add a new instrument item below the current one. -void qsamplerInstrumentList::newItemSlot (void) -{ - qsamplerInstrument *pInstrument = new qsamplerInstrument(); - - qsamplerInstrumentForm form(this); - form.setup(pInstrument); - if (!form.exec()) { - delete pInstrument; - return; - } - - // Check it there's already one for the same key (bank, program) - qsamplerInstrumentItem *pItem = findItem(pInstrument); - if (pItem) - delete pItem; - - pInstrument->map(); - emit instrumentsChanged(); - - qsamplerInstrumentGroup *pParentGroup - = groupItem(QListView::selectedItem()); - addItem(pInstrument, pParentGroup); - if (pParentGroup) - pParentGroup->setOpen(true); - - selectionChangedSlot(); -} - - -// Edit current item below the current one. -void qsamplerInstrumentList::editItemSlot (void) -{ - QListViewItem *pListItem = QListView::selectedItem(); - if (pListItem == NULL) - return; - if (pListItem->rtti() == Item) { - qsamplerInstrumentItem *pItem - = static_cast (pListItem); - if (pItem && pItem->instrument()) { - qsamplerInstrumentForm form(this); - form.setup(pItem->instrument()); - if (form.exec()) { - pItem->instrument()->map(); - emit instrumentsChanged(); - pItem->update(); - } - } - } - - selectionChangedSlot(); -} - - -// Rename current group/item. -void qsamplerInstrumentList::renameSlot (void) -{ - QListViewItem *pListItem = QListView::selectedItem(); - if (pListItem) - pListItem->startRename(0); - - selectionChangedSlot(); -} - - -// Remove current group/item. -void qsamplerInstrumentList::deleteSlot (void) -{ - QListViewItem *pListItem = QListView::selectedItem(); - if (pListItem) { - if (pListItem->rtti() == Item) { - qsamplerInstrumentItem *pItem - = static_cast (pListItem); - if (pItem && pItem->instrument()) { - pItem->instrument()->unmap(); - emit instrumentsChanged(); - } - } - delete pListItem; - } - - selectionChangedSlot(); -} - - -// In-place selection slot. -void qsamplerInstrumentList::selectionChangedSlot (void) -{ - qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance(); - QListViewItem *pListItem = QListView::selectedItem(); - bool bEnabled = (pMainForm && pMainForm->client()); - m_pNewItemAction->setEnabled(bEnabled); - bEnabled = (bEnabled && pListItem != NULL); - m_pEditItemAction->setEnabled(bEnabled && pListItem->rtti() == Item); - m_pRenameAction->setEnabled(bEnabled); - m_pDeleteAction->setEnabled(bEnabled); -} - - -// In-place activation slot. -void qsamplerInstrumentList::activatedSlot ( QListViewItem *pListItem ) -{ - // FIXME: Hope the list view item is the one selected. - if (pListItem->rtti() == Item) - editItemSlot(); -} - - -// In-place aliasing slot. -void qsamplerInstrumentList::renamedSlot ( QListViewItem *pListItem ) -{ - if (pListItem->rtti() == Item) { - qsamplerInstrumentItem *pItem - = static_cast (pListItem); - if (pItem && pItem->instrument()) { - pItem->instrument()->setName(pListItem->text(0)); - pItem->instrument()->map(); - emit instrumentsChanged(); - pItem->update(); - } - } -} - - -// Context menu request event handler. -void qsamplerInstrumentList::contextMenuEvent ( - QContextMenuEvent *pContextMenuEvent ) -{ - QPopupMenu menu(this); - - // Construct context menu. - m_pNewItemAction->addTo(&menu); -// m_pNewGroupAction->addTo(&menu); - menu.insertSeparator(); - m_pEditItemAction->addTo(&menu); - m_pRenameAction->addTo(&menu); - m_pDeleteAction->addTo(&menu); - menu.insertSeparator(); - m_pRefreshAction->addTo(&menu); - - menu.exec(pContextMenuEvent->globalPos()); -} - - -// General reloader. -void qsamplerInstrumentList::refresh (void) -{ - clear(); - - qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance(); - if (pMainForm == NULL) - return; - if (pMainForm->client() == NULL) - return; - - qsamplerInstrumentItem *pItem = NULL; - lscp_midi_instrument_t *pInstrs - = ::lscp_list_midi_instruments(pMainForm->client()); - for (int iInstr = 0; pInstrs && pInstrs[iInstr].program >= 0; ++iInstr) { - int iBank = (pInstrs[iInstr].bank_msb << 7) | pInstrs[iInstr].bank_lsb; - int iProgram = pInstrs[iInstr].program; - qsamplerInstrument *pInstrument - = new qsamplerInstrument(iBank, iProgram); - if (pInstrument->get()) - pItem = new qsamplerInstrumentItem(this, pInstrument, pItem); - } - - if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) { - pMainForm->appendMessagesClient("lscp_list_midi_instruments"); - pMainForm->appendMessagesError(tr("Could not get current list of MIDI instrument mappings.\n\nSorry.")); - } - - selectionChangedSlot(); -} - - -// end of qsamplerInstrumentList.cpp - +// qsamplerInstrumentList.cpp +// +/**************************************************************************** + Copyright (C) 2003-2010, rncbc aka Rui Nuno Capela. All rights reserved. + Copyright (C) 2007, Christian Schoenebeck + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*****************************************************************************/ + +#include "qsamplerAbout.h" +#include "qsamplerInstrumentList.h" + +#include "qsamplerInstrument.h" + +#include "qsamplerOptions.h" +#include "qsamplerMainForm.h" + +#include +#include + + +namespace QSampler { + +//------------------------------------------------------------------------- +// QSampler::InstrumentListModel - data model for MIDI prog mappings +// + +InstrumentListModel::InstrumentListModel ( QObject *pParent ) + : QAbstractItemModel(pParent), m_iMidiMap(LSCP_MIDI_MAP_ALL) +{ +// QAbstractItemModel::reset(); +} + +InstrumentListModel::~InstrumentListModel (void) +{ + clear(); +} + + +int InstrumentListModel::rowCount ( const QModelIndex& /*parent*/) const +{ + int nrows = 0; + + if (m_iMidiMap == LSCP_MIDI_MAP_ALL) { + InstrumentMap::const_iterator itMap = m_instruments.constBegin(); + for ( ; itMap != m_instruments.constEnd(); ++itMap) + nrows += (*itMap).size(); + } else { + InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap); + if (itMap != m_instruments.constEnd()) + nrows += (*itMap).size(); + } + + return nrows; +} + + +int InstrumentListModel::columnCount ( const QModelIndex& /*parent*/) const +{ + return 9; +} + + +QVariant InstrumentListModel::data ( + const QModelIndex &index, int role ) const +{ + if (!index.isValid()) + return QVariant(); + const Instrument *pInstr + = static_cast (index.internalPointer()); + + if (pInstr && role == Qt::DisplayRole) { + switch (index.column()) { + case 0: return pInstr->name(); + case 1: return QVariant::fromValue(pInstr->map()); + case 2: return QVariant::fromValue(pInstr->bank()); + case 3: return QVariant::fromValue(pInstr->prog() + 1); + case 4: return pInstr->engineName(); + case 5: return pInstr->instrumentFile(); + case 6: return QVariant::fromValue(pInstr->instrumentNr()); + case 7: return QString::number(pInstr->volume() * 100.0) + " %"; + case 8: { + switch (pInstr->loadMode()) { + case 3: return tr("Persistent"); + case 2: return tr("On Demand Hold"); + case 1: return tr("On Demand"); + } + } + default: + break; + } + } + + return QVariant(); +} + + +QModelIndex InstrumentListModel::index ( + int row, int col, const QModelIndex& /*parent*/ ) const +{ + const Instrument *pInstr = NULL; + + if (m_iMidiMap == LSCP_MIDI_MAP_ALL) { + int nrows = 0; + InstrumentMap::const_iterator itMap = m_instruments.constBegin(); + for ( ; itMap != m_instruments.constEnd(); ++itMap) { + const InstrumentList& list = *itMap; + nrows += list.size(); + if (row < nrows) { + pInstr = list.at(row + list.size() - nrows); + break; + } + } + } else { + // Resolve MIDI instrument map... + InstrumentMap::const_iterator itMap = m_instruments.find(m_iMidiMap); + if (itMap != m_instruments.constEnd()) { + const InstrumentList& list = *itMap; + if (row < list.size()) + pInstr = list.at(row); + } + } + + if (pInstr) + return createIndex(row, col, (void *) pInstr); + else + return QModelIndex(); +} + + +QModelIndex InstrumentListModel::parent ( const QModelIndex& /*child*/ ) const +{ + return QModelIndex(); +} + + +QVariant InstrumentListModel::headerData ( + int section, Qt::Orientation orientation, int role ) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + switch (section) { + case 0: return tr("Name"); + case 1: return tr("Map"); + case 2: return tr("Bank"); + case 3: return tr("Prog"); + case 4: return tr("Engine"); + case 5: return tr("File"); + case 6: return tr("Nr"); + case 7: return tr("Vol"); + case 8: return tr("Mode"); + } + } + + return QAbstractItemModel::headerData(section, orientation, role); +} + + +void InstrumentListModel::setMidiMap ( int iMidiMap ) +{ + if (iMidiMap < 0) + iMidiMap = LSCP_MIDI_MAP_ALL; + + m_iMidiMap = iMidiMap; +} + + +int InstrumentListModel::midiMap (void) const +{ + return m_iMidiMap; +} + + +const Instrument *InstrumentListModel::addInstrument ( + int iMap, int iBank, int iProg ) +{ + // Check it there's already one instrument item + // with the very same key (bank, program); + // if yes, just remove it without prejudice... + InstrumentList& list = m_instruments[iMap]; + for (int i = 0; i < list.size(); ++i) { + const Instrument *pInstr = list.at(i); + if (pInstr->bank() == iBank && pInstr->prog() == iProg) { + delete pInstr; + list.removeAt(i); + break; + } + } + + // Resolve the appropriate place, we keep the list sorted that way... + int i = 0; + for ( ; i < list.size(); ++i) { + const Instrument *pInstr = list.at(i); + if (iBank < pInstr->bank() + || (iBank == pInstr->bank() && iProg < pInstr->prog())) { + break; + } + } + + Instrument *pInstr = new Instrument(iMap, iBank, iProg); + if (pInstr->getInstrument()) { + list.insert(i, pInstr); + } else { + delete pInstr; + pInstr = NULL; + } + + return pInstr; +} + + +void InstrumentListModel::removeInstrument ( const Instrument *pInstrument ) +{ + const int iMap = pInstrument->map(); + const int iBank = pInstrument->bank(); + const int iProg = pInstrument->prog(); + + if (m_instruments.contains(iMap)) { + InstrumentList& list = m_instruments[iMap]; + for (int i = 0; i < list.size(); ++i) { + const Instrument *pInstr = list.at(i); + if (pInstr->bank() == iBank && pInstr->prog() == iProg) { + delete pInstr; + list.removeAt(i); + break; + } + } + } +} + + +// Reposition the instrument in the model (called when map/bank/prg changed) +void InstrumentListModel::updateInstrument ( const Instrument *pInstrument ) +{ + const int iMap = pInstrument->map(); + const int iBank = pInstrument->bank(); + const int iProg = pInstrument->prog(); + + // Remove given instrument from its current list... + removeInstrument(pInstrument); + + // Re-add the instrument... + addInstrument(iMap, iBank, iProg); +} + + +void InstrumentListModel::refresh (void) +{ + MainForm *pMainForm = MainForm::getInstance(); + if (pMainForm == NULL) + return; + if (pMainForm->client() == NULL) + return; + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + clear(); + + // Load the whole bunch of instrument items... + lscp_midi_instrument_t *pInstrs + = ::lscp_list_midi_instruments(pMainForm->client(), m_iMidiMap); + for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; ++iInstr) { + const int iMap = pInstrs[iInstr].map; + const int iBank = pInstrs[iInstr].bank; + const int iProg = pInstrs[iInstr].prog; + addInstrument(iMap, iBank, iProg); + // Try to keep it snappy :) + QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + + QApplication::restoreOverrideCursor(); + + if (pInstrs == NULL && ::lscp_client_get_errno(pMainForm->client())) { + pMainForm->appendMessagesClient("lscp_list_midi_instruments"); + pMainForm->appendMessagesError( + tr("Could not get current list of MIDI instrument mappings.\n\nSorry.")); + } +} + +void InstrumentListModel::beginReset (void) +{ +#if QT_VERSION >= 0x040600 + QAbstractItemModel::beginResetModel(); +#endif +} + +void InstrumentListModel::endReset (void) +{ +#if QT_VERSION >= 0x040600 + QAbstractItemModel::endResetModel(); +#else + QAbstractItemModel::reset(); +#endif +} + + +// Map clear. +void InstrumentListModel::clear (void) +{ + InstrumentMap::iterator itMap = m_instruments.begin(); + for ( ; itMap != m_instruments.end(); ++itMap) { + InstrumentList& list = itMap.value(); + qDeleteAll(list); + list.clear(); + } + + m_instruments.clear(); +} + + +//------------------------------------------------------------------------- +// QSampler::InstrumentListView - list view for MIDI prog mappings +// + +// Constructor. +InstrumentListView::InstrumentListView ( QWidget *pParent ) + : QTreeView(pParent) +{ + m_pListModel = new InstrumentListModel(this); + + QTreeView::setModel(m_pListModel); + + QTreeView::setRootIsDecorated(false); + QTreeView::setUniformRowHeights(true); + QTreeView::setAlternatingRowColors(true); + QTreeView::setSelectionBehavior(QAbstractItemView::SelectRows); + QTreeView::setSelectionMode(QAbstractItemView::SingleSelection); + QTreeView::setItemsExpandable(false); + + QHeaderView *pHeader = QTreeView::header(); + pHeader->setDefaultAlignment(Qt::AlignLeft); + pHeader->setMovable(false); + pHeader->setStretchLastSection(true); + pHeader->resizeSection(0, 120); // Name + QTreeView::resizeColumnToContents(1); // Map + QTreeView::resizeColumnToContents(2); // Bank + QTreeView::resizeColumnToContents(3); // Prog + QTreeView::resizeColumnToContents(4); // Engine + pHeader->resizeSection(5, 240); // File + QTreeView::resizeColumnToContents(6); // Nr + pHeader->resizeSection(7, 60); // Vol +} + + +// Destructor. +InstrumentListView::~InstrumentListView (void) +{ + delete m_pListModel; +} + + +void InstrumentListView::setMidiMap ( int iMidiMap ) +{ + m_pListModel->setMidiMap(iMidiMap); +} + + +int InstrumentListView::midiMap (void) const +{ + return m_pListModel->midiMap(); +} + + +const Instrument *InstrumentListView::addInstrument ( + int iMap, int iBank, int iProg ) +{ + m_pListModel->beginReset(); + const Instrument *pInstrument + = m_pListModel->addInstrument(iMap, iBank, iProg); + m_pListModel->endReset(); + + return pInstrument; +} + + +void InstrumentListView::removeInstrument ( const Instrument *pInstrument ) +{ + m_pListModel->beginReset(); + m_pListModel->removeInstrument(pInstrument); + m_pListModel->endReset(); +} + + +// Reposition the instrument in the model (called when map/bank/prg changed) +void InstrumentListView::updateInstrument ( const Instrument *pInstrument ) +{ + m_pListModel->beginReset(); + m_pListModel->updateInstrument(pInstrument); + m_pListModel->endReset(); +} + + +// Refreshener. +void InstrumentListView::refresh (void) +{ + m_pListModel->beginReset(); + m_pListModel->refresh(); + m_pListModel->endReset(); +} + + +} // namespace QSampler + + +// end of qsamplerInstrumentList.cpp