1
//=========================================================
4
// $Id: listedit.cpp,v 1.1 2002/01/30 12:08:38 muse Exp $
5
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
6
//=========================================================
10
#include "scrollscale.h"
15
#include "editevent.h"
19
#include "pitchedit.h"
23
#include "midithread.h"
27
#include <qtoolbutton.h>
31
#include <qsizegrip.h>
32
#include <qscrollbar.h>
34
#include <qpushbutton.h>
35
#include <qradiobutton.h>
36
#include <qbuttongroup.h>
38
#include <qlistview.h>
39
#include <qcombobox.h>
41
#include <qpopupmenu.h>
45
//---------------------------------------------------------
47
//---------------------------------------------------------
49
class EventListItem : public QListViewItem {
54
EventListItem(QListView* parent, MidiEvent* ev, MidiPart* p)
55
: QListViewItem(parent), event(ev), part(p) {}
56
virtual QString text(int col) const;
57
virtual int compare(QListViewItem*i, int, bool) const {
58
return event->posTick() - ((EventListItem*)i)->event->posTick();
62
/*---------------------------------------------------------
64
*---------------------------------------------------------*/
66
static QString midiMetaComment(const MidiEvent* ev)
68
int meta = ev->dataA();
69
QString s = midiMetaName(meta);
98
const char* txt = (char*)(ev->data());
99
int len = ev->dataLen();
101
memcpy(buffer, txt, len);
104
for (int i = 0; i < len; ++i) {
105
if (buffer[i] == '\n' || buffer[i] == '\r')
117
int len = ev->lenTick();
118
int n = len > 10 ? 10 : len;
119
for (i = 0; i < n; ++i) {
120
if (i >= ev->dataLen())
124
k.setNum(ev->data()[i] & 0xff, 16);
134
//---------------------------------------------------------
136
//---------------------------------------------------------
138
void ListEdit::closeEvent(QCloseEvent* e)
140
emit deleted((int)this);
144
//---------------------------------------------------------
146
//---------------------------------------------------------
148
void ListEdit::songChanged(int type)
152
if (type & (SC_PART_REMOVED | SC_PART_MODIFIED
153
| SC_PART_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED
154
| SC_EVENT_INSERTED | SC_SELECTION)) {
155
if (type & (SC_PART_REMOVED | SC_PART_INSERTED))
157
// close window if editor has no parts anymore
158
if (parts()->empty()) {
162
if (type == SC_SELECTION) {
164
QListViewItem* ci = 0;
165
for (QListViewItem* i = liste->firstChild(); i; i = i->nextSibling()) {
166
if (i->isSelected() ^ ((EventListItem*)i)->event->selected()) {
167
i->setSelected(((EventListItem*)i)->event->selected());
175
liste->setCurrentItem(ci);
176
liste->triggerUpdate();
183
for (iPart p = parts()->begin(); p != parts()->end(); ++p) {
184
MidiPart* part = (MidiPart*) (p->second);
185
if (part->sn() == curPartId)
187
EventList* el = part->events();
188
for (iEvent i = el->begin(); i != el->end(); ++i) {
189
EventListItem* item = new EventListItem(liste, (MidiEvent*)(i->second), part);
190
item->setSelected(i->second->selected());
195
curPart = (MidiPart*)(parts()->begin()->second);
196
curTrack = curPart->track();
200
//---------------------------------------------------------
202
//---------------------------------------------------------
204
QString EventListItem::text(int col) const
207
QString commentLabel;
210
s.setNum(event->posTick());
214
int t = event->posTick();
216
sigmap.tickValues(t, &bar, &beat, &tick);
217
s.sprintf("%04d.%02d.%03d", bar+1, beat+1, tick);
221
switch(event->type()) {
222
case MidiEvent::Note:
225
case MidiEvent::NoteOff:
228
case MidiEvent::Program:
231
case MidiEvent::Ctrl7:
232
commentLabel = midiCtrl7Name(event->dataA());
235
case MidiEvent::Ctrl14:
236
commentLabel = midiCtrl14Name(event->dataA(), event->dataC());
239
case MidiEvent::Sysex:
241
commentLabel = "len ";
243
k.setNum(event->dataLen());
247
commentLabel += nameSysex(event->dataLen(), event->data());
249
for (i = 0; i < 10; ++i) {
250
if (i >= event->dataLen())
252
commentLabel += " 0x";
254
k.setNum(event->data()[i] & 0xff, 16);
258
commentLabel += "...";
262
case MidiEvent::PAfter:
265
case MidiEvent::CAfter:
268
case MidiEvent::Pitch:
271
case MidiEvent::Meta:
272
commentLabel = midiMetaComment(event);
275
case MidiEvent::NRPN:
281
case MidiEvent::NoEvent:
282
case MidiEvent::Symbol:
283
case MidiEvent::Quantize:
284
case MidiEvent::Clock:
290
s.setNum(event->channel() + 1);
293
if (event->type() == MidiEvent::Note || event->type() == MidiEvent::NoteOff) {
294
s = pitch2string(event->dataA());
297
s.setNum(event->dataA());
301
s.setNum(event->dataB());
304
s.setNum(event->dataC());
307
s.setNum(event->lenTick());
310
switch(event->type()) {
311
case MidiEvent::Ctrl7:
312
s = midiCtrl7Name(event->dataA());
314
case MidiEvent::Ctrl14:
315
s = midiCtrl14Name(event->dataA(), event->dataC());
317
case MidiEvent::Sysex:
321
k.setNum(event->dataLen());
325
commentLabel += nameSysex(event->dataLen(), event->data());
327
for (i = 0; i < 10; ++i) {
328
if (i >= event->dataLen())
332
k.setNum(event->data()[i] & 0xff, 16);
339
case MidiEvent::Meta:
340
s = midiMetaComment(event);
351
//---------------------------------------------------------
353
//---------------------------------------------------------
355
ListEdit::ListEdit(PartList* pl)
356
: MidiEditor(0, 0, pl)
358
insertItems = new QActionGroup(this, "InsertItems", false);
359
QAction* insertNote = new QAction("Insert Note", QIconSet(*note1Icon), "insert Note",
360
CTRL+Key_N, insertItems);
361
QAction* insertSysEx = new QAction("Insert SysEx", QIconSet(*sysexIcon), "insert SysEx",
362
CTRL+Key_S, insertItems);
363
QAction* insertCtrl = new QAction("Insert Ctrl", QIconSet(*ctrlIcon), "insert Ctrl",
364
CTRL+Key_T, insertItems);
365
QAction* insertMeta = new QAction("Insert Meta", QIconSet(*metaIcon), "insert Meta",
367
QAction* insertPitch = new QAction("Insert Pitch", QIconSet(*pitchIcon), "insert Pitch",
368
CTRL+Key_E, insertItems);
369
QAction* insertCAfter = new QAction("Insert Channel Aftertouch", QIconSet(*cafterIcon), "insert Channel Aftertouch",
370
CTRL+Key_A, insertItems);
371
QAction* insertPAfter = new QAction("Insert Key Aftertouch", QIconSet(*pafterIcon), "insert Poly Aftertouch",
372
CTRL+Key_P, insertItems);
374
connect(insertNote, SIGNAL(activated()), SLOT(editInsertNote()));
375
connect(insertSysEx, SIGNAL(activated()), SLOT(editInsertSysEx()));
376
connect(insertCtrl, SIGNAL(activated()), SLOT(editInsertCtrl7()));
377
connect(insertMeta, SIGNAL(activated()), SLOT(editInsertMeta()));
378
connect(insertPitch, SIGNAL(activated()), SLOT(editInsertPitch()));
379
connect(insertCAfter, SIGNAL(activated()), SLOT(editInsertCAfter()));
380
connect(insertPAfter, SIGNAL(activated()), SLOT(editInsertPAfter()));
382
//---------Pulldown Menu----------------------------
383
menuEdit = new QPopupMenu(this);
384
menuBar()->insertItem(tr("&Edit"), menuEdit);
385
undoRedo->addTo(menuEdit);
386
menuEdit->insertSeparator();
388
menuEdit->insertItem(tr("Cut"), EList::CMD_CUT);
389
menuEdit->setAccel(CTRL+Key_X, EList::CMD_CUT);
390
menuEdit->insertItem(tr("Copy"), EList::CMD_COPY);
391
menuEdit->setAccel(CTRL+Key_C, EList::CMD_COPY);
392
menuEdit->insertItem(tr("Paste"), EList::CMD_PASTE);
393
menuEdit->setAccel(CTRL+Key_V, EList::CMD_PASTE);
394
menuEdit->insertSeparator();
396
menuEdit->insertItem(tr("Delete Events"), CMD_DELETE);
397
menuEdit->setAccel(Key_Delete, CMD_DELETE);
398
menuEdit->insertSeparator();
400
insertItems->addTo(menuEdit);
402
connect(menuEdit, SIGNAL(activated(int)), SLOT(cmd(int)));
404
//---------ToolBar----------------------------------
405
listTools = new QToolBar(this, "list-tools");
406
listTools->setLabel(tr("List Tools"));
407
undoRedo->addTo(listTools);
408
QToolBar* insertTools = new QToolBar(this, "insert");
409
insertTools->setLabel(tr("Insert Tools"));
410
insertItems->addTo(insertTools);
413
//---------------------------------------------------
415
//---------------------------------------------------
418
liste = new QListView(mainw);
419
QFontMetrics fm(liste->font());
420
int n = fm.width('9');
422
int c = fm.width("Val B");
423
liste->setAllColumnsShowFocus(true);
424
liste->setSorting(0);
425
liste->setSelectionMode(QListView::Extended);
427
liste->addColumn("Tick", n * 6 + b);
428
liste->addColumn("Bar", fm.width("9999.99.999") + b);
429
liste->addColumn("Typ", fm.width("SysEx") + b);
430
liste->addColumn("Ch", n * 2 + b);
431
liste->addColumn("Val A", c + b);
432
liste->addColumn("Val B", c + b);
433
liste->addColumn("Val C", c + b);
434
liste->addColumn("Len", n * 4 + b);
435
liste->addColumn("Comment");
436
liste->setResizeMode(QListView::LastColumn);
437
connect(liste, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
438
connect(liste, SIGNAL(doubleClicked(QListViewItem*)), SLOT(doubleClicked(QListViewItem*)));
440
//---------------------------------------------------
442
//---------------------------------------------------
444
mainGrid->setRowStretch(1, 100);
445
mainGrid->setColStretch(0, 100);
446
mainGrid->addMultiCellWidget(liste, 1, 2, 0, 0);
447
connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
450
curPart = (MidiPart*)(pl->begin()->second);
451
curPartId = curPart->sn();
454
//---------------------------------------------------------
456
//---------------------------------------------------------
458
ListEdit::~ListEdit()
460
undoRedo->removeFrom(listTools);
463
//---------------------------------------------------------
465
//---------------------------------------------------------
467
void ListEdit::editInsertNote()
469
MidiEvent* event = EditNoteDialog::getEvent(0, 0, this);
471
event->setPort(curTrack->outPort());
472
event->setChannel(curTrack->outChannel());
473
midiThread->msgAddEvent(event, curPart);
477
//---------------------------------------------------------
479
//---------------------------------------------------------
481
void ListEdit::editInsertSysEx()
483
MidiEvent* event = EditSysexDialog::getEvent(0, 0, this);
485
event->setPort(curTrack->outPort());
486
event->setChannel(curTrack->outChannel());
487
midiThread->msgAddEvent(event, curPart);
491
//---------------------------------------------------------
493
//---------------------------------------------------------
495
void ListEdit::editInsertCtrl7()
497
MidiEvent* event = EditCtrl7Dialog::getEvent(0, 0, this);
499
event->setPort(curTrack->outPort());
500
event->setChannel(curTrack->outChannel());
501
midiThread->msgAddEvent(event, curPart);
505
//---------------------------------------------------------
507
//---------------------------------------------------------
509
void ListEdit::editInsertCtrl14()
511
MidiEvent* event = EditCtrl14Dialog::getEvent(0, 0, this);
513
event->setPort(curTrack->outPort());
514
event->setChannel(curTrack->outChannel());
515
midiThread->msgAddEvent(event, curPart);
519
//---------------------------------------------------------
521
//---------------------------------------------------------
523
void ListEdit::editInsertMeta()
525
MidiEvent* event = EditMetaDialog::getEvent(0, 0, this);
527
event->setPort(curTrack->outPort());
528
event->setChannel(curTrack->outChannel());
529
midiThread->msgAddEvent(event, curPart);
533
//---------------------------------------------------------
535
//---------------------------------------------------------
537
void ListEdit::editInsertPitch()
539
MidiEvent* event = EditPitchDialog::getEvent(0, 0, this);
541
event->setPort(curTrack->outPort());
542
event->setChannel(curTrack->outChannel());
543
midiThread->msgAddEvent(event, curPart);
547
//---------------------------------------------------------
549
//---------------------------------------------------------
551
void ListEdit::editInsertCAfter()
553
MidiEvent* event = EditCAfterDialog::getEvent(0, 0, this);
555
event->setPort(curTrack->outPort());
556
event->setChannel(curTrack->outChannel());
557
midiThread->msgAddEvent(event, curPart);
561
//---------------------------------------------------------
563
//---------------------------------------------------------
565
void ListEdit::editInsertPAfter()
567
MidiEvent* event = EditPAfterDialog::getEvent(0, 0, this);
569
event->setPort(curTrack->outPort());
570
event->setChannel(curTrack->outChannel());
571
midiThread->msgAddEvent(event, curPart);
575
//---------------------------------------------------------
577
//---------------------------------------------------------
579
void ListEdit::editEvent(MidiEvent* event, MidiPart* part)
581
int tick = event->posTick();
582
MidiEvent* nevent = 0;
583
switch(event->type()) {
584
case MidiEvent::Note:
585
nevent = EditNoteDialog::getEvent(tick, event, this);
587
case MidiEvent::Ctrl7:
588
nevent = EditCtrl7Dialog::getEvent(tick, event, this);
590
case MidiEvent::Ctrl14:
591
nevent = EditCtrl14Dialog::getEvent(tick, event, this);
593
case MidiEvent::Sysex:
594
nevent = EditSysexDialog::getEvent(tick, event, this);
596
case MidiEvent::PAfter:
597
nevent = EditPAfterDialog::getEvent(tick, event, this);
599
case MidiEvent::CAfter:
600
nevent = EditCAfterDialog::getEvent(tick, event, this);
602
case MidiEvent::Pitch:
603
nevent = EditPitchDialog::getEvent(tick, event, this);
605
case MidiEvent::Meta:
606
nevent = EditMetaDialog::getEvent(tick, event, this);
608
case MidiEvent::Program:
613
// TODO: check for event != nevent
614
nevent->setPort(event->port());
615
nevent->setChannel(event->channel());
616
midiThread->msgChangeEvent(event, nevent, part);
620
//---------------------------------------------------------
622
//---------------------------------------------------------
624
void ListEdit::readStatus(Xml& xml)
627
Xml::Token token = xml.parse();
628
const QString& tag = xml.s1();
629
if (token == Xml::Error || token == Xml::End)
633
if (tag == "midieditor")
634
MidiEditor::readStatus(xml);
636
xml.unknown("ListEdit");
639
if (tag == "listeditor")
647
//---------------------------------------------------------
649
//---------------------------------------------------------
651
void ListEdit::writeStatus(int level, Xml& xml) const
653
writePartList(level, xml);
654
xml.tag(level++, "listeditor");
655
MidiEditor::writeStatus(level, xml);
656
xml.tag(level, "/listeditor");
659
//---------------------------------------------------------
661
//---------------------------------------------------------
663
void ListEdit::selectionChanged()
666
for (QListViewItem* i = liste->firstChild(); i; i = i->nextSibling()) {
667
if (i->isSelected() ^ ((EventListItem*)i)->event->selected()) {
668
((EventListItem*)i)->event->setSelected(i->isSelected());
673
song->update(SC_SELECTION);
676
//---------------------------------------------------------
678
//---------------------------------------------------------
680
void ListEdit::doubleClicked(QListViewItem* item)
682
EventListItem* ev = (EventListItem*) item;
683
editEvent(ev->event, ev->part);
686
//---------------------------------------------------------
688
//---------------------------------------------------------
690
void ListEdit::cmd(int cmd)
695
for (QListViewItem* i = liste->firstChild(); i; i = i->nextSibling()) {
696
EventListItem *item = (EventListItem *) i;
698
if (i->isSelected() || item->event->selected())
699
midiThread->msgDeleteEvent(item->event, item->part, false);
702
song->endUndo(SC_EVENT_MODIFIED);