From f2eb59ac0522568a8591149566cdc947f71b8835 Mon Sep 17 00:00:00 2001 From: Nil Geisweiller Date: Sat, 27 Jan 2007 13:53:48 +0000 Subject: see ChangeLog --- muse/ChangeLog | 4 +++ muse/al/pos.cpp | 11 ++++++ muse/al/pos.h | 2 ++ muse/muse/evdata.h | 9 +++++ muse/muse/event.cpp | 3 +- muse/muse/eventbase.h | 2 ++ muse/muse/liste/ieventdialog.cpp | 72 +++++++++++++++++++++++++++++++++----- muse/muse/liste/ieventdialog.h | 22 ++++++++++-- muse/muse/liste/partlistedit.cpp | 75 +++++++++++++++++++++++++++++++++++----- muse/muse/liste/partlistedit.h | 3 +- muse/muse/liste/partlistedit.ui | 15 ++++++++ muse/muse/midieventbase.cpp | 15 ++++++++ muse/muse/midieventbase.h | 3 ++ muse/muse/waveevent.cpp | 16 +++++++++ muse/muse/waveevent.h | 3 ++ 15 files changed, 233 insertions(+), 22 deletions(-) diff --git a/muse/ChangeLog b/muse/ChangeLog index b2ff5ca5..fafab130 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,7 @@ +27.01 (ng) + - added operator== for EventBase, MidiEventBase and PosLen + - modified Event::operator== to match on the content instead of the pointer + - added insert note event and delete note and sysex event in List Editor 23.01 (ng) - added insert sysex event update I - replaced bzip2 by Qt compression in deicsonze diff --git a/muse/al/pos.cpp b/muse/al/pos.cpp index 31770727..e723c2f7 100644 --- a/muse/al/pos.cpp +++ b/muse/al/pos.cpp @@ -490,6 +490,17 @@ void PosLen::setPos(const Pos& pos) } } +//--------------------------------------------------------- +// operator== +//--------------------------------------------------------- + +bool PosLen::operator==(const PosLen& pl) const { + if(type()==TICKS) + return (_lenTick==pl._lenTick && Pos::operator==((const Pos&)pl)); + else + return (_lenFrame==pl._lenFrame && Pos::operator==((const Pos&)pl)); +} + //--------------------------------------------------------- // mbt //--------------------------------------------------------- diff --git a/muse/al/pos.h b/muse/al/pos.h index 6d69cc52..6226cfef 100644 --- a/muse/al/pos.h +++ b/muse/al/pos.h @@ -121,6 +121,8 @@ class PosLen : public Pos { unsigned endTick() const { return end().tick(); } unsigned endFrame() const { return end().frame(); } void setPos(const Pos&); + + bool operator==(const PosLen& s) const; }; } diff --git a/muse/muse/evdata.h b/muse/muse/evdata.h index 8e7ae643..629b9e9a 100644 --- a/muse/muse/evdata.h +++ b/muse/muse/evdata.h @@ -21,6 +21,8 @@ #ifndef __EVDATA_H__ #define __EVDATA_H__ +#include + //--------------------------------------------------------- // EvData // variable len event data (sysex, meta etc.) @@ -59,6 +61,13 @@ class EvData { return *this; } + bool operator==(const EvData& ed) const { + if(dataLen==ed.dataLen) { + return memcmp(data, ed.data, sizeof(unsigned char) * dataLen)==0; + } + else return false; + } + ~EvData() { if (--(*refCount) == 0) { delete[] data; diff --git a/muse/muse/event.cpp b/muse/muse/event.cpp index 9c485d0a..525938b9 100644 --- a/muse/muse/event.cpp +++ b/muse/muse/event.cpp @@ -137,9 +137,10 @@ Event& Event::operator=(const Event& e) } bool Event::operator==(const Event& e) const { - return ev == e.ev; + return *ev == *e.ev; } + int Event::getRefCount() const { return ev->getRefCount(); } bool Event::selected() const { return ev->_selected; } void Event::setSelected(bool val) { ev->_selected = val; } diff --git a/muse/muse/eventbase.h b/muse/muse/eventbase.h index 763843eb..7a2f438b 100644 --- a/muse/muse/eventbase.h +++ b/muse/muse/eventbase.h @@ -89,6 +89,8 @@ class EventBase : public AL::PosLen { virtual void setSndFile(SndFileR&) { } virtual EventBase* clone() const = 0; virtual void read(unsigned /*offset*/, float** /*bpp*/, int /*channels*/, int /*nn*/) {} + + virtual bool operator==(const EventBase&) const { return false; } }; #endif diff --git a/muse/muse/liste/ieventdialog.cpp b/muse/muse/liste/ieventdialog.cpp index 09256b20..da830cd9 100644 --- a/muse/muse/liste/ieventdialog.cpp +++ b/muse/muse/liste/ieventdialog.cpp @@ -22,7 +22,7 @@ #include #include "ieventdialog.h" -InsertEventDialog::InsertEventDialog(const Pos& time, +InsertEventDialog::InsertEventDialog(const Pos& time, Part* part, QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) { setWindowTitle("Insert Event Dialog"); @@ -30,6 +30,8 @@ InsertEventDialog::InsertEventDialog(const Pos& time, _selectedType = -1; + _part = part; + _lastDir = QDir::currentPath(); _mainLayout = new QGridLayout(parent); @@ -42,10 +44,42 @@ InsertEventDialog::InsertEventDialog(const Pos& time, QGridLayout* tLayout = new QGridLayout(_typeWidget[i]); if(i == IED_Note) { _eventTypeComboBox->addItem(NoteSTR); - //TODO - QLabel* noteEventTODO = - new QLabel("TODO : Note event", _typeWidget[i]); - tLayout->addWidget(noteEventTODO, 0, 0, 1, 2); + //pitch + QLabel* pitchLabel = new QLabel("Pitch", _typeWidget[i]); + tLayout->addWidget(pitchLabel, 0, 0); + /*_noteLabel = new QLabel("C4", _typeWidget[i]); + _noteLabel->setFrameShape(QFrame::Panel); + _noteLabel->setFrameShadow(QFrame::Sunken); + tLayout->addWidget(_noteLabel, 0, 1);*/ + _pitchSpinBox = new QSpinBox(_typeWidget[i]); + _pitchSpinBox->setMaximum(127); + _pitchSpinBox->setMinimum(0); + _pitchSpinBox->setValue(72); //C4 + tLayout->addWidget(_pitchSpinBox, 0, 1); + //Velocity + QLabel* velocityLabel = new QLabel("Velocity", _typeWidget[i]); + tLayout->addWidget(velocityLabel, 1, 0); + _velocitySpinBox = new QSpinBox(_typeWidget[i]); + _velocitySpinBox->setMaximum(127); + _velocitySpinBox->setMinimum(0); + _velocitySpinBox->setValue(70); + tLayout->addWidget(_velocitySpinBox, 1, 1); + //Velocity Off + /*QLabel* veloOffLabel = new QLabel("Velocity Off", _typeWidget[i]); + tLayout->addWidget(veloOffLabel, 2, 0); + _veloOffSpinBox = new QSpinBox(_typeWidget[i]); + _veloOffSpinBox->setMaximum(127); + _veloOffSpinBox->setMinimum(0); + _veloOffSpinBox->setValue(0); + tLayout->addWidget(_veloOffSpinBox, 2, 1);*/ + //Length + QLabel* lengthLabel = new QLabel("Length", _typeWidget[i]); + tLayout->addWidget(lengthLabel, 2, 0); + _lengthSpinBox = new QSpinBox(_typeWidget[i]); + _lengthSpinBox->setMaximum(32768); + _lengthSpinBox->setMinimum(1); + _lengthSpinBox->setValue(384); + tLayout->addWidget(_lengthSpinBox, 2, 1); } else if(i == IED_ProgramChange) { _eventTypeComboBox->addItem(ProgramChangeSTR); @@ -149,10 +183,23 @@ InsertEventDialog::~InsertEventDialog() { } EventList* InsertEventDialog::elResult() { + unsigned evTick; + evTick = (unsigned)IED_MAX(0, (int)_timePosEdit->pos().tick() + - (int)_part->tick()); + Pos evPos(evTick); + EventList* res = new EventList; + int curType = _eventTypeComboBox->currentIndex(); + if(curType == IED_Note) { - //TODO - return NULL; + Event evNote(Note); + evNote.setPos(evPos); + evNote.setPitch(_pitchSpinBox->value()); + evNote.setVelo(_velocitySpinBox->value()); + //evNote.setVeloOff(_veloOffSpinBox->value()); + evNote.setLenTick(_lengthSpinBox->value()); + res->add(evNote); + return res; } else if(curType == IED_ProgramChange) { //TODO @@ -163,10 +210,9 @@ EventList* InsertEventDialog::elResult() { return NULL; } else if(curType == IED_Sysex) { - EventList* res = new EventList; for(unsigned i = 0; (int)i < _sysexCountSpinBox->value(); i++) { Event evSysex(Sysex); - evSysex.setPos(_timePosEdit->pos()); + evSysex.setPos(evPos); evSysex.setData((const unsigned char*) _dataSysex[i].data(), _dataSysex[i].size()); res->add(evSysex); @@ -179,6 +225,9 @@ EventList* InsertEventDialog::elResult() { int InsertEventDialog::sysexLength() { return _dataSysex[_curSysexSpinBox->value()].size(); } +QString InsertEventDialog::charArray2Str(const char* s, int length) { + return ByteArray2Str(QByteArray(s, length)); +} QString InsertEventDialog::ByteArray2Str(const QByteArray& ba) { QString res = "F0 "; for(int i = 0; i < ba.size(); i++) { @@ -198,6 +247,10 @@ QByteArray InsertEventDialog::Str2ByteArray(const QString& s) { } return ba; } +char* InsertEventDialog::Str2CharArray(const QString& s) { + return Str2ByteArray(s).data(); +} + void InsertEventDialog::setSysexTextEdit() { QString s = _dataSysexStr[_curSysexSpinBox->value()].toUpper(); _sysexTextEdit->blockSignals(true); @@ -358,5 +411,6 @@ void InsertEventDialog::updateType(int type) { else _typeWidget[i]->hide(); } _selectedType = type; + resize(1, 1); } } diff --git a/muse/muse/liste/ieventdialog.h b/muse/muse/liste/ieventdialog.h index 27be67d1..68ec92cd 100644 --- a/muse/muse/liste/ieventdialog.h +++ b/muse/muse/liste/ieventdialog.h @@ -32,6 +32,7 @@ #include "midievent.h" #include "al/pos.h" #include "muse/event.h" +#include "muse/part.h" class QDialog; using Awl::PosEdit; @@ -42,6 +43,8 @@ using AL::Pos; #define ControlChangeSTR "Control change" #define SysexSTR "Sysex" +#define IED_MAX(x, y) (x > y? x : y) + class InsertEventDialog : public QDialog { Q_OBJECT @@ -51,12 +54,22 @@ class InsertEventDialog : public QDialog { QString _lastDir; + Part* _part; + + //event type QComboBox* _eventTypeComboBox; //time PosEdit* _timePosEdit; + //Note + QSpinBox* _pitchSpinBox; + QSpinBox* _velocitySpinBox; + QSpinBox* _veloOffSpinBox; + QSpinBox* _lengthSpinBox; + //QLabel* _noteLabel; + //Sysex QSpinBox* _sysexCountSpinBox; QSpinBox* _curSysexSpinBox; @@ -77,17 +90,20 @@ class InsertEventDialog : public QDialog { IED_TypeCount }; int sysexLength(); //return the length of the current sysex - QString ByteArray2Str(const QByteArray& ba); //add F0 and F7 - QByteArray Str2ByteArray(const QString& s); //skip F0 and F7 void setSysexTextEdit(); //set the display of sysexTextEdit public: - InsertEventDialog(const Pos& time, + InsertEventDialog(const Pos& time, Part* part, QWidget* parent = 0, Qt::WindowFlags f = 0); ~InsertEventDialog(); EventList* elResult(); + static QString charArray2Str(const char* s, int length); + static QString ByteArray2Str(const QByteArray& ba); //add F0 and F7 + static QByteArray Str2ByteArray(const QString& s); //skip F0 and F7 + static char* Str2CharArray(const QString& s); + private slots: void updateSysexTextEdit(); void updateSysexCursor(); diff --git a/muse/muse/liste/partlistedit.cpp b/muse/muse/liste/partlistedit.cpp index 5b0b39fa..50fbc5f3 100644 --- a/muse/muse/liste/partlistedit.cpp +++ b/muse/muse/liste/partlistedit.cpp @@ -49,6 +49,7 @@ PartListEditor::PartListEditor(ListEdit* e, QWidget* parent) part = 0; connect(le.insertButton, SIGNAL(clicked()), SLOT(insertClicked())); + connect(le.deleteButton, SIGNAL(clicked()), SLOT(deleteClicked())); } //--------------------------------------------------------- @@ -85,12 +86,19 @@ void PartListEditor::updateList() QTreeWidgetItem* item = new QTreeWidgetItem; item->setData(TICK_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter)); item->setData(TIME_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter)); - item->setData(TICK_COL, Qt::DisplayRole, e.tick()); - item->setData(TIME_COL, Qt::DisplayRole, e.tick()); - - item->setData(2, Qt::DisplayRole, e.eventTypeName()); - item->setData(3, Qt::DisplayRole, e.dataA()); - item->setData(4, Qt::DisplayRole, e.dataB()); + item->setData(TICK_COL, Qt::DisplayRole, e.tick() + part->tick()); + item->setData(TIME_COL, Qt::DisplayRole, e.tick() + part->tick()); + item->setData(TYPE_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter)); + item->setData(TYPE_COL, Qt::DisplayRole, e.eventTypeName()); + item->setData(A_COL, Qt::TextAlignmentRole, int(Qt::AlignHCenter | Qt::AlignVCenter)); + item->setData(A_COL, Qt::DisplayRole, e.dataA()); + item->setData(B_COL, Qt::TextAlignmentRole, int(Qt::AlignHCenter | Qt::AlignVCenter)); + item->setData(B_COL, Qt::DisplayRole, e.dataB()); + item->setData(C_COL, Qt::TextAlignmentRole, int(Qt::AlignHCenter | Qt::AlignVCenter)); + item->setData(C_COL, Qt::DisplayRole, e.dataC()); + item->setData(LEN_COL, Qt::TextAlignmentRole, int(Qt::AlignHCenter | Qt::AlignVCenter)); + item->setData(LEN_COL, Qt::DisplayRole, (e.type()==Sysex?e.dataLen():e.lenTick())); + item->setText(DATA_COL, (e.type()==Sysex?InsertEventDialog::charArray2Str((const char*)e.data(), e.dataLen()):"")); le.eventList->insertTopLevelItem(idx, item); } } @@ -102,11 +110,16 @@ void PartListEditor::updateList() void PartListEditor::insertClicked() { + QTreeWidgetItem* cur = le.eventList->currentItem(); AL::Pos time; - + if(cur) { + int tick = cur->data(TIME_COL, Qt::DisplayRole).toInt(); + time.setTick(tick); + } + EventList* el; - InsertEventDialog dialog(time, this); + InsertEventDialog dialog(time, part, this); if(dialog.exec() == QDialog::Accepted) { el = dialog.elResult(); if(el) { @@ -118,6 +131,40 @@ void PartListEditor::insertClicked() } } +//--------------------------------------------------------- +// deleteClicked +//--------------------------------------------------------- + +void PartListEditor::deleteClicked() + { + QTreeWidgetItem* cur = le.eventList->currentItem(); + if (cur == 0) + return; + int tick = cur->data(TICK_COL, Qt::DisplayRole).toInt(); + int evTick = (unsigned)IED_MAX(0, (int)tick - (int)part->tick()); + QString type = cur->text(TYPE_COL); + if(type == "Note") { + Event ev(Note); + int pitch = cur->data(A_COL, Qt::DisplayRole).toInt(); + int velo = cur->data(B_COL, Qt::DisplayRole).toInt(); + int len = cur->data(LEN_COL, Qt::DisplayRole).toInt(); + ev.setTick(evTick); + ev.setPitch(pitch); + ev.setVelo(velo); + ev.setLenTick(len); + song->deleteEvent(ev, part); + } + else if(type == "Sysex") { + Event ev(Sysex); + QString dataStr = cur->text(DATA_COL); + char* data = InsertEventDialog::Str2CharArray(dataStr); + int len = cur->data(LEN_COL, Qt::DisplayRole).toInt(); + ev.setTick(evTick); + ev.setData((const unsigned char*)data, len); + song->deleteEvent(ev, part); + } + } + //--------------------------------------------------------- // EventDelegate //--------------------------------------------------------- @@ -142,6 +189,9 @@ QWidget* EventDelegate::createEditor(QWidget* pw, case PartListEditor::TYPE_COL: case PartListEditor::A_COL: case PartListEditor::B_COL: + case PartListEditor::C_COL: + case PartListEditor::LEN_COL: + case PartListEditor::DATA_COL: break; } return QItemDelegate::createEditor(pw, option, index); @@ -166,6 +216,9 @@ void EventDelegate::setEditorData(QWidget* editor, case PartListEditor::TYPE_COL: case PartListEditor::A_COL: case PartListEditor::B_COL: + case PartListEditor::C_COL: + case PartListEditor::LEN_COL: + case PartListEditor::DATA_COL: break; } QItemDelegate::setEditorData(editor, index); @@ -190,6 +243,9 @@ void EventDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, case PartListEditor::TYPE_COL: case PartListEditor::A_COL: case PartListEditor::B_COL: + case PartListEditor::C_COL: + case PartListEditor::LEN_COL: + case PartListEditor::DATA_COL: break; } QItemDelegate::setModelData(editor, model, index); @@ -225,6 +281,9 @@ void EventDelegate::paint(QPainter* painter, case PartListEditor::TYPE_COL: case PartListEditor::A_COL: case PartListEditor::B_COL: + case PartListEditor::C_COL: + case PartListEditor::LEN_COL: + case PartListEditor::DATA_COL: QItemDelegate::paint(painter, option, index); return; } diff --git a/muse/muse/liste/partlistedit.h b/muse/muse/liste/partlistedit.h index a232fc64..6a39457c 100644 --- a/muse/muse/liste/partlistedit.h +++ b/muse/muse/liste/partlistedit.h @@ -60,12 +60,13 @@ class PartListEditor : public ListWidget { private slots: void insertClicked(); + void deleteClicked(); public: PartListEditor(ListEdit*, QWidget* parent = 0); virtual void setup(const ListType&); Track* getTrack() const; - enum { TICK_COL, TIME_COL, TYPE_COL, A_COL, B_COL}; + enum { TICK_COL, TIME_COL, TYPE_COL, A_COL, B_COL, C_COL, LEN_COL, DATA_COL}; }; #endif diff --git a/muse/muse/liste/partlistedit.ui b/muse/muse/liste/partlistedit.ui index 022cc305..c575ef03 100644 --- a/muse/muse/liste/partlistedit.ui +++ b/muse/muse/liste/partlistedit.ui @@ -105,6 +105,21 @@ p, li { white-space: pre-wrap; } Val B + + + Val C + + + + + Length + + + + + Data + + diff --git a/muse/muse/midieventbase.cpp b/muse/muse/midieventbase.cpp index a84e31b9..04bec920 100644 --- a/muse/muse/midieventbase.cpp +++ b/muse/muse/midieventbase.cpp @@ -142,3 +142,18 @@ void MidiEventBase::read(QDomNode node) } } +//--------------------------------------------------------- +// MidiEventBase::operator== +//--------------------------------------------------------- + +bool MidiEventBase::operator==(const EventBase& ev) const { + const MidiEventBase* pev = dynamic_cast(&ev); + + if(pev) return operator==(*pev); + else return false; +} + +bool MidiEventBase::operator==(const MidiEventBase& ev) const { + return (ev.a==a && ev.b==b && ev.c==c && ev.edata==edata + && PosLen::operator==((const PosLen&)ev)); +} diff --git a/muse/muse/midieventbase.h b/muse/muse/midieventbase.h index ba812ffa..da6af56b 100644 --- a/muse/muse/midieventbase.h +++ b/muse/muse/midieventbase.h @@ -68,6 +68,9 @@ class MidiEventBase : public EventBase { virtual void read(QDomNode); virtual void write(Xml&, const Pos& offset) const; virtual EventBase* mid(unsigned, unsigned); + + virtual bool operator==(const EventBase&) const; + virtual bool operator==(const MidiEventBase&) const; }; #endif diff --git a/muse/muse/waveevent.cpp b/muse/muse/waveevent.cpp index 45a07562..4aff6a47 100644 --- a/muse/muse/waveevent.cpp +++ b/muse/muse/waveevent.cpp @@ -119,3 +119,19 @@ void WaveEventBase::read(unsigned offset, float** buffer, int channel, int n) f.read(channel, buffer, n); } +//--------------------------------------------------------- +// WaveEventBase::operator== +//--------------------------------------------------------- + +bool WaveEventBase::operator==(const EventBase& ev) const { + + const WaveEventBase* pev = dynamic_cast(&ev); + + if(pev) return operator==(*pev); + else return false; +} + +bool WaveEventBase::operator==(const WaveEventBase& /*ev*/) const { + //TODO + return false; +} diff --git a/muse/muse/waveevent.h b/muse/muse/waveevent.h index 079c4425..476b3a03 100644 --- a/muse/muse/waveevent.h +++ b/muse/muse/waveevent.h @@ -52,6 +52,9 @@ class WaveEventBase : public EventBase { virtual SndFileR sndFile() const { return f; } virtual void setSndFile(SndFileR& sf) { f = sf; } virtual void read(unsigned offset, float** bpp, int channels, int nn); + + virtual bool operator==(const EventBase&) const; + virtual bool operator==(const WaveEventBase&) const; }; #endif -- cgit v1.2.3