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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

  ViewVC Help
Powered by ViewVC