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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 962 - (show annotations) (download)
Sun Dec 3 18:27:23 2006 UTC (17 years, 3 months ago) by capela
File size: 15723 byte(s)
* Adding preliminary MIDI instrument mapping support; now
  with an instrument list widget and editing capabilities.

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

  ViewVC Help
Powered by ViewVC