diff options
author | Florian Jung <flo@windfisch.org> | 2011-05-23 20:04:52 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-05-23 20:04:52 +0000 |
commit | 5e04b219a6de8e41f132fcaec26876ecdb5ae9b5 (patch) | |
tree | 0380e5724d80c6ac91bd448868525d372de60e2b /muse2/muse | |
parent | b5bdb59699abd38a3aa90dfb4d9882b2be7f5be0 (diff) | |
parent | a16b4e2746309724086f55d7df8b15da40939b20 (diff) |
merged with deeper_changes. see changelog
Diffstat (limited to 'muse2/muse')
90 files changed, 5680 insertions, 1653 deletions
diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt index d89bb007..e6a90a59 100644 --- a/muse2/muse/CMakeLists.txt +++ b/muse2/muse/CMakeLists.txt @@ -62,7 +62,6 @@ QT4_WRAP_CPP ( muse_moc_headers plugin.h song.h transport.h - transpose.h value.h ) @@ -89,6 +88,7 @@ file (GLOB core_source_files event.cpp eventlist.cpp exportmidi.cpp + functions.cpp gconfig.cpp globals.cpp help.cpp @@ -128,7 +128,6 @@ file (GLOB core_source_files ticksynth.cpp track.cpp transport.cpp - transpose.cpp undo.cpp value.cpp vst.cpp @@ -194,6 +193,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/remote ${CMAKE_CURRENT_BINARY_DIR}/waveedit ${CMAKE_CURRENT_BINARY_DIR}/widgets + ${CMAKE_CURRENT_BINARY_DIR}/widgets/function_dialogs ) ## @@ -234,6 +234,7 @@ target_link_libraries(core synti waveedit widgets + widgets_functiondialogs ${QT_LIBRARIES} ${SNDFILE_LIBRARIES} diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 5b8da28e..f94f4a64 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -31,7 +31,6 @@ #include "didyouknow.h" #include "drumedit.h" #include "filedialog.h" -#include "gatetime.h" #include "gconfig.h" #include "gui.h" #include "icons.h" @@ -49,7 +48,6 @@ #include "songinfo.h" #include "ticksynth.h" #include "transport.h" -#include "transpose.h" #include "waveedit.h" #include "widgets/projectcreateimpl.h" #include "widgets/menutitleitem.h" @@ -1020,7 +1018,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow() midiEdit = new QMenu(tr("Midi"), this); midiEdit->setIcon(QIcon(*edit_midiIcon)); - midiTransposeAction = new QAction(QIcon(*midi_transposeIcon), tr("Transpose"), this); midiTransformerAction = new QAction(QIcon(*midi_transformIcon), tr("Midi &Transform"), this); editSongInfoAction = new QAction(QIcon(*edit_listIcon), tr("Song Info"), this); @@ -1169,7 +1166,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow() connect(masterGraphicAction, SIGNAL(activated()), SLOT(startMasterEditor())); connect(masterListAction, SIGNAL(activated()), SLOT(startLMasterEditor())); - connect(midiTransposeAction, SIGNAL(activated()), SLOT(transpose())); connect(midiTransformerAction, SIGNAL(activated()), SLOT(startMidiTransformer())); connect(editSongInfoAction, SIGNAL(activated()), SLOT(startSongInfo())); @@ -1399,7 +1395,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow() midiEdit->insertItem(tr("Modify Gate Time"), this, SLOT(modifyGateTime())); midiEdit->insertItem(tr("Modify Velocity"), this, SLOT(modifyVelocity())); midiEdit->insertItem(tr("Crescendo"), this, SLOT(crescendo())); - midiEdit->insertItem(tr("Transpose"), this, SLOT(transpose())); midiEdit->insertItem(tr("Thin Out"), this, SLOT(thinOut())); midiEdit->insertItem(tr("Erase Event"), this, SLOT(eraseEvent())); midiEdit->insertItem(tr("Note Shift"), this, SLOT(noteShift())); @@ -1410,7 +1405,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow() midiEdit->insertItem(tr("Create Measure"), this, SLOT(createMeasure())); midiEdit->insertItem(tr("Mix Track"), this, SLOT(mixTrack())); #endif - midiEdit->addAction(midiTransposeAction); midiEdit->addAction(midiTransformerAction); menuEdit->addAction(editSongInfoAction); @@ -3888,15 +3882,6 @@ void MusE::selectionChanged() editCopyAction->setEnabled(flag); } -//--------------------------------------------------------- -// transpose -//--------------------------------------------------------- - -void MusE::transpose() - { - Transpose *w = new Transpose(); - w->show(); - } //--------------------------------------------------------- // modifyGateTime @@ -3904,8 +3889,7 @@ void MusE::transpose() void MusE::modifyGateTime() { - GateTime* w = new GateTime(this); - w->show(); + printf("not implemented\n"); } //--------------------------------------------------------- @@ -4550,7 +4534,6 @@ void MusE::updateConfiguration() masterGraphicAction->setShortcut(shortcuts[SHRT_OPEN_GRAPHIC_MASTER].key); masterListAction->setShortcut(shortcuts[SHRT_OPEN_LIST_MASTER].key); - midiTransposeAction->setShortcut(shortcuts[SHRT_TRANSPOSE].key); midiTransformerAction->setShortcut(shortcuts[SHRT_OPEN_MIDI_TRANSFORM].key); //editSongInfoAction has no acceleration diff --git a/muse2/muse/app.h b/muse2/muse/app.h index 45b2efff..2aa2834f 100644 --- a/muse2/muse/app.h +++ b/muse2/muse/app.h @@ -114,7 +114,6 @@ class MusE : public QMainWindow QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; QAction *trackAInputAction, *trackAAuxAction; QAction *masterGraphicAction, *masterListAction; - QAction *midiTransposeAction; QAction *midiTransformerAction; QAction *editSongInfoAction; public: @@ -295,7 +294,6 @@ class MusE : public QMainWindow void cmd(int); void clipboardChanged(); void selectionChanged(); - void transpose(); void modifyGateTime(); void modifyVelocity(); void crescendo(); diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index df81e3b1..e326e868 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -474,6 +474,7 @@ void Appearance::resetValues() partShownames->setChecked(config->canvasShowPartType & 1); partShowevents->setChecked(config->canvasShowPartType & 2); partShowCakes->setChecked(!(config->canvasShowPartType & 2)); + partCakeStretch->setChecked(config->canvasShowPartType & 4); eventNoteon->setChecked(config->canvasShowPartEvent & (1 << 0)); eventPolypressure->setChecked(config->canvasShowPartEvent & (1 << 1)); @@ -598,8 +599,8 @@ void Appearance::apply() showPartType |= 1; if (partShowevents->isChecked()) showPartType |= 2; - //if (partShowCakes->isChecked()) - // showPartType |= 4; + if (partCakeStretch->isChecked()) + showPartType |= 4; config->canvasShowPartType = showPartType; diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp index d74bed78..e1205d6f 100644 --- a/muse2/muse/arranger/arranger.cpp +++ b/muse2/muse/arranger/arranger.cpp @@ -69,6 +69,7 @@ void Arranger::setHeaderToolTips() header->setToolTip(COL_OPORT, tr("Midi output port or synth midi port")); header->setToolTip(COL_TIMELOCK, tr("Time Lock")); header->setToolTip(COL_AUTOMATION, tr("Automation parameter selection")); + header->setToolTip(COL_CLEF, tr("Notation clef")); } @@ -87,6 +88,7 @@ void Arranger::setHeaderWhatsThis() header->setWhatsThis(COL_OCHANNEL, tr("Midi/drum track: Output channel number.\nAudio track: Channels.\nMid/right-click to change.")); header->setWhatsThis(COL_OPORT, tr("Midi/drum track: Output port.\nSynth track: Assigned midi port.\nLeft-click to change.\nRight-click to show GUI.")); header->setWhatsThis(COL_TIMELOCK, tr("Time lock")); + header->setToolTip(COL_CLEF, tr("Notation clef. Select this tracks notation clef.")); } //--------------------------------------------------------- @@ -290,6 +292,7 @@ Arranger::Arranger(QMainWindow* parent, const char* name) header->setColumnLabel(tr("Ch"), COL_OCHANNEL, 30); header->setColumnLabel(tr("T"), COL_TIMELOCK, fm1.width('T')+fw); header->setColumnLabel(tr("Automation"), COL_AUTOMATION, 75); + header->setColumnLabel(tr("Clef"), COL_CLEF, 75); header->setResizeMode(COL_RECORD, QHeaderView::Fixed); header->setResizeMode(COL_MUTE, QHeaderView::Fixed); header->setResizeMode(COL_SOLO, QHeaderView::Fixed); @@ -299,6 +302,7 @@ Arranger::Arranger(QMainWindow* parent, const char* name) header->setResizeMode(COL_OCHANNEL, QHeaderView::Fixed); header->setResizeMode(COL_TIMELOCK, QHeaderView::Fixed); header->setResizeMode(COL_AUTOMATION, QHeaderView::Interactive); + header->setResizeMode(COL_CLEF, QHeaderView::Interactive); setHeaderToolTips(); setHeaderWhatsThis(); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 35de93ee..9b0a65b9 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -12,6 +12,7 @@ #include <values.h> #include <uuid/uuid.h> #include <math.h> +#include <map> #include <QClipboard> #include <QLineEdit> @@ -40,6 +41,7 @@ #include "mpevent.h" #include "midievent.h" #include "midi.h" +#include "midictrl.h" #include "utils.h" // Moved into global config by Tim. @@ -231,9 +233,9 @@ void PartCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) } QPoint cpos = event->pos(); curItem = items.find(cpos); - bool shift = event->modifiers() & Qt::ShiftModifier; + bool ctrl = event->modifiers() & Qt::ControlModifier; if (curItem) { - if (event->button() == Qt::LeftButton && shift) { + if (event->button() == Qt::LeftButton && ctrl) { editPart = (NPart*)curItem; QRect r = map(curItem->bbox()); if (lineEditor == 0) { @@ -1002,7 +1004,7 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) void PartCanvas::mousePress(QMouseEvent* event) { - if (event->modifiers() & Qt::ShiftModifier) { + if (event->modifiers() & Qt::ControlModifier) { return; } QPoint pt = event->pos(); @@ -1059,7 +1061,7 @@ void PartCanvas::mouseMove(QMouseEvent* event) x = 0; if (_tool == AutomationTool) - processAutomationMovements(event->pos(), event->modifiers() & Qt::ControlModifier); + processAutomationMovements(event->pos(), event->modifiers() & Qt::ShiftModifier); emit timeChanged(AL::sigmap.raster(x, *_raster)); } @@ -1660,36 +1662,34 @@ void PartCanvas::drawMoving(QPainter& p, const CItem* item, const QRect&) //--------------------------------------------------------- -// drawWavePart +// drawMidiPart // bb - bounding box of paint area // pr - part rectangle //--------------------------------------------------------- -void PartCanvas::drawMidiPart(QPainter& p, const QRect& bb, EventList* events, MidiTrack *mt, MidiPart *pt, const QRect& r, int pTick, int from, int to) +void PartCanvas::drawMidiPart(QPainter& p, const QRect&, EventList* events, MidiTrack *mt, MidiPart *pt, const QRect& r, int pTick, int from, int to) { //printf("x=%d y=%d h=%d w=%d\n",r.x(),r.y(),r.height(),r.width()); - + int color_brightness; + if(pt) { int part_r, part_g, part_b, brightness; config.partColors[pt->colorIndex()].getRgb(&part_r, &part_g, &part_b); brightness = part_r*29 + part_g*59 + part_b*12; if (brightness < 12000 || pt->selected()) - //p.setPen(Qt::white); // too dark: use white for color - p.setPen(QColor(192,192,192)); // too dark: use lighter color + color_brightness=192; // too dark: use lighter color else - //p.setPen(Qt::black); // otherwise use black - p.setPen(QColor(64,64,64)); // otherwise use dark color + color_brightness=64; // otherwise use dark color } else - p.setPen(QColor(80,80,80)); + color_brightness=80; if (config.canvasShowPartType & 2) { // show events + p.setPen(QColor(color_brightness,color_brightness,color_brightness)); // Do not allow this, causes segfault. if(from <= to) { - //p.setPen(QColor(80,80,80)); - //EventList* events = mp->events(); iEvent ito(events->lower_bound(to)); for (iEvent i = events->lower_bound(from); i != ito; ++i) { @@ -1710,22 +1710,142 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect& bb, EventList* events, M } } else { // show Cakewalk Style - //p.setPen(QColor(80,80,80)); - //EventList* events = mp->events(); + using std::map; + using std::pair; + iEvent ito(events->lower_bound(to)); - //printf("PartCanvas::drawItem pTick:%d from:%d to:%d\n", pTick, from, to); - bool isdrum = (mt->type() == Track::DRUM); - for (iEvent i = events->begin(); i != ito; ++i) { + + // draw controllers ------------------------------------------ + p.setPen(QColor(192,192,color_brightness/2)); + for (iEvent i = events->begin(); i != ito; ++i) { // PITCH BEND int t = i->first + pTick; - int te = t + i->second.lenTick(); - if (t > (to + pTick)) - { - //printf("PartCanvas::drawItem t:%d > to:%d + pTick:%d i->first:%d\n", t, to, pTick, i->first); + EventType type = i->second.type(); + if (type == Controller) { + int ctrl_type=i->second.dataA(); + int val=i->second.dataB(); + + int th = int(mt->height() * 0.75); // only draw on three quarters + int hoffset = (mt->height() - th ) / 2; // offset from bottom - break; + if (ctrl_type == CTRL_PITCH) + p.drawLine(t, hoffset + r.y() + th/2, t, hoffset + r.y() - val*th/8192/2 + th/2); } + } + + p.setPen(QColor(192,color_brightness/2,color_brightness/2)); + for (iEvent i = events->begin(); i != ito; ++i) { // PAN + int t = i->first + pTick; + + EventType type = i->second.type(); + if (type == Controller) { + int ctrl_type=i->second.dataA(); + int val=i->second.dataB(); + + int th = int(mt->height() * 0.75); // only draw on three quarters + int hoffset = (mt->height() - th ) / 2; // offset from bottom + + if (ctrl_type == 10) + p.drawLine(t, hoffset + r.y() + th - val*th/127, t, hoffset + r.y() + th); + } + } + + p.setPen(QColor(color_brightness/2,192,color_brightness/2)); + for (iEvent i = events->begin(); i != ito; ++i) { // VOLUME + int t = i->first + pTick; + + EventType type = i->second.type(); + if (type == Controller) { + int ctrl_type=i->second.dataA(); + int val=i->second.dataB(); + + int th = int(mt->height() * 0.75); // only draw on three quarters + int hoffset = (mt->height() - th ) / 2; // offset from bottom + + if (ctrl_type == 7) + p.drawLine(t, hoffset + r.y() + th - val*th/127, t, hoffset + r.y() + th); + } + } + + p.setPen(QColor(0,0,255)); + for (iEvent i = events->begin(); i != ito; ++i) { // PROGRAM CHANGE + int t = i->first + pTick; + + EventType type = i->second.type(); + if (type == Controller) { + int ctrl_type=i->second.dataA(); + + int th = int(mt->height() * 0.75); // only draw on three quarters + int hoffset = (mt->height() - th ) / 2; // offset from bottom + + if (ctrl_type == CTRL_PROGRAM) + p.drawLine(t, hoffset + r.y(), t, hoffset + r.y() + th); + } + } + + + + + + // draw notes ------------------------------------------------ + + int lowest_pitch=127; + int highest_pitch=0; + map<int,int> y_mapper; + + if (config.canvasShowPartType & 4) //y-stretch? + { + for (iEvent i = events->begin(); i != ito; ++i) + { + if (i->second.type()==Note) + { + int pitch=i->second.pitch(); + + if (!isdrum) + { + if (pitch > highest_pitch) highest_pitch=pitch; + if (pitch < lowest_pitch) lowest_pitch=pitch; + } + else + { + y_mapper.insert(pair<int,int>(pitch, 0)); + } + } + } + + if (isdrum) + { + int cnt=0; + for (map<int,int>::iterator it=y_mapper.begin(); it!=y_mapper.end(); it++) + { + it->second=cnt; + cnt++; + } + lowest_pitch=0; + highest_pitch=cnt-1; + } + + if (lowest_pitch==highest_pitch) + { + lowest_pitch--; + highest_pitch++; + } + } + else + { + lowest_pitch=0; + highest_pitch=127; + + if (isdrum) + for (int cnt=0;cnt<127;cnt++) + y_mapper[cnt]=cnt; + } + + p.setPen(QColor(color_brightness,color_brightness,color_brightness)); + for (iEvent i = events->begin(); i != ito; ++i) { + int t = i->first + pTick; + int te = t + i->second.lenTick(); if (te < (from + pTick)) continue; @@ -1738,8 +1858,12 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect& bb, EventList* events, M int pitch = i->second.pitch(); int th = int(mt->height() * 0.75); // only draw on three quarters int hoffset = (mt->height() - th ) / 2; // offset from bottom - //int y = hoffset + (r.y() + th - (pitch * (th) / 127)); - int y = hoffset + r.y() + th - (isdrum?127-pitch:pitch) * th / 127; + int y; + if (!isdrum) + y = hoffset + r.y() + th - (pitch-lowest_pitch)*th/(highest_pitch-lowest_pitch); + else + y = hoffset + r.y() + y_mapper[pitch]*th/(highest_pitch-lowest_pitch); + p.drawLine(t, y, te, y); } } diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index ccd213da..2dd19b4d 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -44,6 +44,7 @@ #include "midiedit/drummap.h" #include "synth.h" #include "config.h" +#include "scoreedit.h" #include "popupmenu.h" #ifdef DSSI_SUPPORT @@ -349,7 +350,7 @@ void TList::paint(const QRect& r) if (cl->isVisible()) countVisible++; } - //int count = ((AudioTrack*)track)->controller()->size(); + //int count = ((AudioTrack*)track)->controller()->size(); //commented out by flo: gives a "unused variable" warning s.sprintf(" %d(%d) visible",countVisible, countAll); } @@ -357,6 +358,18 @@ void TList::paint(const QRect& r) p.drawText(r, Qt::AlignVCenter|Qt::AlignLeft, s); } break; + case COL_CLEF: + if (track->isMidiTrack()) { + QString s = "no clef"; + if (((MidiTrack*)track)->getClef() == ScoreEdit::trebleClef) + s="Treble Clef"; + else if (((MidiTrack*)track)->getClef() == ScoreEdit::bassClef) + s="Bass Clef"; + else if (((MidiTrack*)track)->getClef() == ScoreEdit::grandStaff) + s="Grand Staff"; + p.drawText(r, Qt::AlignVCenter|Qt::AlignLeft, s); + } + break; default: break; } @@ -917,7 +930,7 @@ void TList::mousePressEvent(QMouseEvent* ev) int x = ev->x(); int y = ev->y(); int button = ev->button(); - bool shift = ((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier; + bool ctrl = ((QInputEvent*)ev)->modifiers() & Qt::ControlModifier; Track* t = y2Track(y + ypos); @@ -1057,6 +1070,34 @@ void TList::mousePressEvent(QMouseEvent* ev) mode = START_DRAG; switch (col) { + case COL_CLEF: + if (t->isMidiTrack()) { + QMenu* p = new QMenu; + p->addAction("Treble clef")->setData(0); + p->addAction("Bass clef")->setData(1); + p->addAction("Grand Staff")->setData(2); + + // Show the menu + QAction* act = p->exec(ev->globalPos(), 0); + if (act) { + switch (act->data().toInt()) { + case 0: + ((MidiTrack*)t)->setClef(ScoreEdit::trebleClef); + break; + case 1: + ((MidiTrack*)t)->setClef(ScoreEdit::bassClef); + break; + case 2: + ((MidiTrack*)t)->setClef(ScoreEdit::grandStaff); + break; + default: + break; + } + } + delete p; + } + + break; case COL_AUTOMATION: { if (!t->isMidiTrack()) { @@ -1154,7 +1195,7 @@ void TList::mousePressEvent(QMouseEvent* ev) break; case COL_MUTE: // p3.3.29 - if ((button == Qt::RightButton) || (((QInputEvent*)ev)->modifiers() & Qt::ControlModifier)) + if ((button == Qt::RightButton) || (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier)) t->setOff(!t->off()); else { @@ -1172,7 +1213,7 @@ void TList::mousePressEvent(QMouseEvent* ev) case COL_NAME: if (button == Qt::LeftButton) { - if (!shift) { + if (!ctrl) { song->deselectTracks(); t->setSelected(true); @@ -1465,7 +1506,7 @@ void TList::wheelEvent(QWheelEvent* ev) break; case COL_MUTE: // p3.3.29 - if (((QInputEvent*)ev)->modifiers() & Qt::ControlModifier) + if (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier) t->setOff(!t->off()); else { @@ -1662,6 +1703,7 @@ void TList::classesPopupMenu(Track* t, int x, int y) } t->setType(Track::MIDI); audio->msgIdle(false); + song->update(SC_EVENT_MODIFIED); } else if (Track::TrackType(n) == Track::DRUM && t->type() == Track::MIDI) { // @@ -1718,8 +1760,8 @@ void TList::classesPopupMenu(Track* t, int x, int y) // Add all port controller events. //audio->msgChangeAllPortDrumCtrlEvents(true); song->changeAllPortDrumCtrlEvents(true); - audio->msgIdle(false); + song->update(SC_EVENT_MODIFIED); } } diff --git a/muse2/muse/arranger/tlist.h b/muse2/muse/arranger/tlist.h index 4d787030..15be450a 100644 --- a/muse2/muse/arranger/tlist.h +++ b/muse2/muse/arranger/tlist.h @@ -37,6 +37,7 @@ enum TrackColumn { COL_OCHANNEL, COL_TIMELOCK, COL_AUTOMATION, + COL_CLEF, COL_NONE = -1 }; diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 2f391445..e7eef503 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -14,6 +14,7 @@ #include "transport.h" #include "icons.h" #include "globals.h" +#include "functions.h" #include "drumedit.h" #include "pianoroll.h" #include "scoreedit.h" @@ -891,6 +892,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer) MasterEdit::readConfiguration(xml); else if (tag == "waveedit") WaveEdit::readConfiguration(xml); + else if (tag == "dialogs") + read_function_dialog_config(xml); else if (tag == "shortcuts") readShortCuts(xml); else if (tag == "division") @@ -1360,6 +1363,8 @@ void MusE::writeGlobalConfiguration(int level, Xml& xml) const ScoreEdit::write_configuration(level, xml); MasterEdit::writeConfiguration(level, xml); WaveEdit::writeConfiguration(level, xml); + + write_function_dialog_config(level, xml); writeShortCuts(level, xml); xml.etag(level, "configuration"); @@ -1475,6 +1480,8 @@ void MusE::writeConfiguration(int level, Xml& xml) const ScoreEdit::write_configuration(level, xml); MasterEdit::writeConfiguration(level, xml); WaveEdit::writeConfiguration(level, xml); + + write_function_dialog_config(level, xml); writeMidiTransforms(level, xml); writeMidiInputTransforms(level, xml); diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 56f19384..f2f335cf 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -743,7 +743,7 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) start = event->pos(); Tool activeTool = tool; - bool shift = event->modifiers() & Qt::ShiftModifier; + bool ctrlKey = event->modifiers() & Qt::ControlModifier; int xpos = start.x(); int ypos = start.y(); @@ -755,7 +755,7 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) { bool do_redraw = false; - if (!shift) + if (!ctrlKey) { deselectAll(); do_redraw = true; @@ -780,7 +780,7 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) break; if (ev->intersects(_controller, r, tickstep, h)) { - if (shift && ev->selected()) + if (ctrlKey && ev->selected()) deselectItem(ev); else selectItem(ev); @@ -797,13 +797,10 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) break; case PencilTool: - if (shift) { - if (type != MidiController::Velo) { + if ((!ctrlKey) && (type != MidiController::Velo)) { drag = DRAG_NEW; song->startUndo(); - ///newVal(xpos, xpos, ypos); newVal(xpos, ypos); - } } else { drag = DRAG_RESIZE; @@ -824,7 +821,7 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) if (drawLineMode) { line2x = xpos; line2y = ypos; - if (shift) + if ((!ctrlKey) && (type != MidiController::Velo)) newValRamp(line1x, line1y, line2x, line2y); else changeValRamp(line1x, line1y, line2x, line2y); @@ -899,7 +896,7 @@ void CtrlCanvas::viewMouseMoveEvent(QMouseEvent* event) void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) { - bool shift = event->modifiers() & Qt::ShiftModifier; + bool ctrlKey = event->modifiers() & Qt::ControlModifier; switch (drag) { ///case DRAG_RESIZE: @@ -922,7 +919,7 @@ void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) case DRAG_LASSO: { - ///if (!shift) + ///if (!ctrlKey) /// deselectAll(); lasso = lasso.normalized(); int h = height(); @@ -932,9 +929,9 @@ void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) if((*i)->part() != curPart) continue; if ((*i)->intersects(_controller, lasso, tickstep, h)) { - if (shift && (*i)->selected()) + if (ctrlKey && (*i)->selected()) { - //if (!shift) // Shift p4.0.18 + //if (!ctrlKey) // ctrlKey p4.0.18 { ///deselectItem(*i); //do_redraw = true; diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp new file mode 100644 index 00000000..89a66fa7 --- /dev/null +++ b/muse2/muse/functions.cpp @@ -0,0 +1,675 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: functions.cpp,v 1.20.2.19 2011/05/05 20:10 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include "functions.h" +#include "song.h" + +#include "event.h" +#include "audio.h" +#include "gconfig.h" + +#include <iostream> + +#include <QMessageBox> + +using namespace std; + +GateTime* gatetime_dialog=NULL; +Velocity* velocity_dialog=NULL; +Quantize* quantize_dialog=NULL; +Remove* erase_dialog=NULL; +DelOverlaps* del_overlaps_dialog=NULL; +Setlen* set_notelen_dialog=NULL; +Move* move_notes_dialog=NULL; +Transpose* transpose_dialog=NULL; +Crescendo* crescendo_dialog=NULL; +Legato* legato_dialog=NULL; + +void init_function_dialogs(QWidget* parent) +{ + gatetime_dialog = new GateTime(parent); + velocity_dialog = new Velocity(parent); + quantize_dialog = new Quantize(parent); + erase_dialog = new Remove(parent); + del_overlaps_dialog = new DelOverlaps(parent); + set_notelen_dialog = new Setlen(parent); + move_notes_dialog = new Move(parent); + transpose_dialog = new Transpose(parent); + crescendo_dialog = new Crescendo(parent); + legato_dialog = new Legato(parent); +} + +set<Part*> partlist_to_set(PartList* pl) +{ + set<Part*> result; + + for (PartList::iterator it=pl->begin(); it!=pl->end(); it++) + result.insert(it->second); + + return result; +} + +bool is_relevant(const Event& event, const Part* part, int range) +{ + unsigned tick; + + if (event.type()!=Note) return false; + + switch (range) + { + case 0: return true; + case 1: return event.selected(); + case 2: tick=event.tick()+part->tick(); return (tick >= song->lpos()) && (tick < song->rpos()); + case 3: return is_relevant(event,part,1) && is_relevant(event,part,2); + default: cout << "ERROR: ILLEGAL FUNCTION CALL in is_relevant: range is illegal: "<<range<<endl; + return false; + } +} + + +map<Event*, Part*> get_events(const set<Part*>& parts, int range) +{ + map<Event*, Part*> events; + + for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) + for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++) + if (is_relevant(event->second, *part, range)) + events.insert(pair<Event*, Part*>(&event->second, *part)); + + return events; +} + + +bool modify_notelen(const set<Part*>& parts) +{ + if (!gatetime_dialog->exec()) + return false; + + modify_notelen(parts,gatetime_dialog->range,gatetime_dialog->rateVal,gatetime_dialog->offsetVal); + + return true; +} + +bool modify_velocity(const set<Part*>& parts) +{ + if (!velocity_dialog->exec()) + return false; + + modify_velocity(parts,velocity_dialog->range,velocity_dialog->rateVal,velocity_dialog->offsetVal); + + return true; +} + +bool quantize_notes(const set<Part*>& parts) +{ + if (!quantize_dialog->exec()) + return false; + + quantize_notes(parts, quantize_dialog->range, (config.division*4)/(1<<quantize_dialog->raster_power2), + quantize_dialog->quant_len, quantize_dialog->strength, quantize_dialog->swing, + quantize_dialog->threshold); + + return true; +} + +bool erase_notes(const set<Part*>& parts) +{ + if (!erase_dialog->exec()) + return false; + + erase_notes(parts,erase_dialog->range, erase_dialog->velo_threshold, erase_dialog->velo_thres_used, + erase_dialog->len_threshold, erase_dialog->len_thres_used ); + + return true; +} + +bool delete_overlaps(const set<Part*>& parts) +{ + if (!del_overlaps_dialog->exec()) + return false; + + delete_overlaps(parts,erase_dialog->range); + + return true; +} + +bool set_notelen(const set<Part*>& parts) +{ + if (!set_notelen_dialog->exec()) + return false; + + set_notelen(parts,set_notelen_dialog->range,set_notelen_dialog->len); + + return true; +} + +bool move_notes(const set<Part*>& parts) +{ + if (!move_notes_dialog->exec()) + return false; + + move_notes(parts,move_notes_dialog->range,move_notes_dialog->amount); + + return true; +} + +bool transpose_notes(const set<Part*>& parts) +{ + if (!transpose_dialog->exec()) + return false; + + transpose_notes(parts,transpose_dialog->range,transpose_dialog->amount); + + return true; +} + +bool crescendo(const set<Part*>& parts) +{ + if (song->rpos() <= song->lpos()) + { + QMessageBox::warning(NULL, QObject::tr("Error"), QObject::tr("Please first select the range for crescendo with the loop markers.")); + return false; + } + + if (!crescendo_dialog->exec()) + return false; + + crescendo(parts,crescendo_dialog->range,crescendo_dialog->start_val,crescendo_dialog->end_val,crescendo_dialog->absolute); + + return true; +} + +bool legato(const set<Part*>& parts) +{ + if (!legato_dialog->exec()) + return false; + + legato(parts,legato_dialog->range, legato_dialog->min_len, !legato_dialog->allow_shortening); + + return true; +} + + + +void modify_velocity(const set<Part*>& parts, int range, int rate, int offset) +{ + map<Event*, Part*> events = get_events(parts, range); + + if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + int velo = event.velo(); + + velo = (velo * rate) / 100; + velo += offset; + + if (velo <= 0) + velo = 1; + else if (velo > 127) + velo = 127; + + if (event.velo() != velo) + { + Event newEvent = event.clone(); + newEvent.setVelo(velo); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + } + + song->endUndo(SC_EVENT_MODIFIED); + } +} + +void modify_off_velocity(const set<Part*>& parts, int range, int rate, int offset) +{ + map<Event*, Part*> events = get_events(parts, range); + + if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + int velo = event.veloOff(); + + velo = (velo * rate) / 100; + velo += offset; + + if (velo <= 0) + velo = 1; + else if (velo > 127) + velo = 127; + + if (event.veloOff() != velo) + { + Event newEvent = event.clone(); + newEvent.setVeloOff(velo); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + } + + song->endUndo(SC_EVENT_MODIFIED); + } +} + +void modify_notelen(const set<Part*>& parts, int range, int rate, int offset) +{ + map<Event*, Part*> events = get_events(parts, range); + + if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned + + len = (len * rate) / 100; + len += offset; + + if (len <= 0) + len = 1; + + if (event.lenTick() != len) + { + Event newEvent = event.clone(); + newEvent.setLenTick(len); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + } + + song->endUndo(SC_EVENT_MODIFIED); + } +} + +void set_notelen(const set<Part*>& parts, int range, int len) +{ + modify_notelen(parts, range, 0, len); +} + +unsigned quantize_tick(unsigned tick, unsigned raster, int swing) +{ + //find out the nearest tick and the distance to it: + //this is so complicated because this function supports + //swing: if swing is 50, the resulting rhythm is not + //"daa daa daa daa" but "daaaa da daaaa da"... + int tick_dest1 = AL::sigmap.raster1(tick, raster*2); //round down + int tick_dest2 = tick_dest1 + raster + raster*swing/100; + int tick_dest3 = tick_dest1 + raster*2; + + int tick_diff1 = tick_dest1 - tick; + int tick_diff2 = tick_dest2 - tick; + int tick_diff3 = tick_dest3 - tick; + + if ((abs(tick_diff1) <= abs(tick_diff2)) && (abs(tick_diff1) <= abs(tick_diff3))) //tick_dest1 is the nearest tick + return tick_dest1; + else if ((abs(tick_diff2) <= abs(tick_diff1)) && (abs(tick_diff2) <= abs(tick_diff3))) //tick_dest2 is the nearest tick + return tick_dest2; + else + return tick_dest3; +} + +void quantize_notes(const set<Part*>& parts, int range, int raster, bool quant_len, int strength, int swing, int threshold) +{ + map<Event*, Part*> events = get_events(parts, range); + bool undo_started=false; + + if (!events.empty()) + { + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + unsigned begin_tick = event.tick() + part->tick(); + int begin_diff = quantize_tick(begin_tick, raster, swing) - begin_tick; + + if (abs(begin_diff) > threshold) + begin_tick = begin_tick + begin_diff*strength/100; + + + unsigned len=event.lenTick(); + + unsigned end_tick = begin_tick + len; + int len_diff = quantize_tick(end_tick, raster, swing) - end_tick; + + if ((abs(len_diff) > threshold) && quant_len) + len = len + len_diff*strength/100; + + if (len <= 0) + len = 1; + + + if ( (event.lenTick() != len) || (event.tick() + part->tick() != begin_tick) ) + { + if (!undo_started) + { + song->startUndo(); + undo_started=true; + } + + Event newEvent = event.clone(); + newEvent.setTick(begin_tick - part->tick()); + newEvent.setLenTick(len); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + } + + if (undo_started) song->endUndo(SC_EVENT_MODIFIED); + } +} + +void erase_notes(const set<Part*>& parts, int range, int velo_threshold, bool velo_thres_used, int len_threshold, bool len_thres_used) +{ + map<Event*, Part*> events = get_events(parts, range); + + if (!events.empty()) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + if ( (!velo_thres_used && !len_thres_used) || + (velo_thres_used && event.velo() < velo_threshold) || + (len_thres_used && int(event.lenTick()) < len_threshold) ) + audio->msgDeleteEvent(event, part, false, false, false); + } + + song->endUndo(SC_EVENT_REMOVED); + } +} + +void transpose_notes(const set<Part*>& parts, int range, signed int halftonesteps) +{ + map<Event*, Part*> events = get_events(parts, range); + + if ( (!events.empty()) && (halftonesteps!=0) ) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + Event newEvent = event.clone(); + int pitch = event.pitch()+halftonesteps; + if (pitch > 127) pitch=127; + if (pitch < 0) pitch=0; + newEvent.setPitch(pitch); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + + song->endUndo(SC_EVENT_MODIFIED); + } +} + +void crescendo(const set<Part*>& parts, int range, int start_val, int end_val, bool absolute) +{ + map<Event*, Part*> events = get_events(parts, range); + + int from=song->lpos(); + int to=song->rpos(); + + if ( (!events.empty()) && (to>from) ) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + unsigned tick = event.tick() + part->tick(); + float curr_val= (float)start_val + (float)(end_val-start_val) * (tick-from) / (to-from); + + Event newEvent = event.clone(); + int velo = event.velo(); + + if (absolute) + velo=curr_val; + else + velo=curr_val*velo/100; + + if (velo > 127) velo=127; + if (velo <= 0) velo=1; + newEvent.setVelo(velo); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + + song->endUndo(SC_EVENT_MODIFIED); + } +} + +void move_notes(const set<Part*>& parts, int range, signed int ticks) //TODO FINDMICH: safety checks +{ + map<Event*, Part*> events = get_events(parts, range); + + if ( (!events.empty()) && (ticks!=0) ) + { + song->startUndo(); + + for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + Event newEvent = event.clone(); + newEvent.setTick(event.tick()+ticks); + // Indicate no undo, and do not do port controller values and clone parts. + audio->msgChangeEvent(event, newEvent, part, false, false, false); + } + + song->endUndo(SC_EVENT_MODIFIED); + } +} + +void delete_overlaps(const set<Part*>& parts, int range) +{ + map<Event*, Part*> events = get_events(parts, range); + bool undo_started=false; + + set<Event*> deleted_events; + + if (!events.empty()) + { + for (map<Event*, Part*>::iterator it1=events.begin(); it1!=events.end(); it1++) + { + Event& event1=*(it1->first); + Part* part1=it1->second; + + // we may NOT optimize by letting it2 start at (it1 +1); this optimisation + // is only allowed when events was sorted by time. it is, however, sorted + // randomly by pointer. + for (map<Event*, Part*>::iterator it2=events.begin(); it2!=events.end(); it2++) + { + Event& event2=*(it2->first); + Part* part2=it2->second; + + if ( (part1->events()==part2->events()) && // part1 and part2 are the same or are duplicates + (&event1 != &event2) && // and event1 and event2 aren't the same + (deleted_events.find(&event2) == deleted_events.end()) ) //and event2 hasn't been deleted before + { + if ( (event1.pitch() == event2.pitch()) && + (event1.tick() <= event2.tick()) && + (event1.endTick() > event2.tick()) ) //they overlap + { + if (undo_started==false) + { + song->startUndo(); + undo_started=true; + } + + int new_len = event2.tick() - event1.tick(); + + if (new_len==0) + { + audio->msgDeleteEvent(event1, part1, false, false, false); + deleted_events.insert(&event1); + } + else + { + Event new_event1 = event1.clone(); + new_event1.setLenTick(new_len); + + audio->msgChangeEvent(event1, new_event1, part1, false, false, false); + } + } + } + } + } + + if (undo_started) song->endUndo(SC_EVENT_MODIFIED); + } +} + +void legato(const set<Part*>& parts, int range, int min_len, bool dont_shorten) +{ + map<Event*, Part*> events = get_events(parts, range); + bool undo_started=false; + + if (min_len<=0) min_len=1; + + if (!events.empty()) + { + for (map<Event*, Part*>::iterator it1=events.begin(); it1!=events.end(); it1++) + { + Event& event1=*(it1->first); + Part* part1=it1->second; + + unsigned len=MAXINT; + // we may NOT optimize by letting it2 start at (it1 +1); this optimisation + // is only allowed when events was sorted by time. it is, however, sorted + // randomly by pointer. + for (map<Event*, Part*>::iterator it2=events.begin(); it2!=events.end(); it2++) + { + Event& event2=*(it2->first); + Part* part2=it2->second; + + bool relevant = (event2.tick() >= event1.tick() + min_len); + if (dont_shorten) + relevant = relevant && (event2.tick() >= event1.endTick()); + + if ( (part1->events()==part2->events()) && // part1 and part2 are the same or are duplicates + relevant && // they're not too near (respect min_len and dont_shorten) + (event2.tick()-event1.tick() < len ) ) // that's the nearest relevant following note + len=event2.tick()-event1.tick(); + } + + if (len==MAXINT) len=event1.lenTick(); // if no following note was found, keep the length + + if (event1.lenTick() != len) + { + if (undo_started==false) + { + song->startUndo(); + undo_started=true; + } + + Event new_event1 = event1.clone(); + new_event1.setLenTick(len); + + audio->msgChangeEvent(event1, new_event1, part1, false, false, false); + } + } + + if (undo_started) song->endUndo(SC_EVENT_MODIFIED); + } +} + + + +void read_function_dialog_config(Xml& xml) +{ + if (erase_dialog==NULL) + { + cout << "ERROR: THIS SHOULD NEVER HAPPEN: read_function_dialog_config() called, but\n" + " dialogs are still uninitalized (NULL)!"<<endl; + return; + } + + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "mod_len") + gatetime_dialog->read_configuration(xml); + else if (tag == "mod_velo") + velocity_dialog->read_configuration(xml); + else if (tag == "quantize") + quantize_dialog->read_configuration(xml); + else if (tag == "erase") + erase_dialog->read_configuration(xml); + else if (tag == "del_overlaps") + del_overlaps_dialog->read_configuration(xml); + else if (tag == "setlen") + set_notelen_dialog->read_configuration(xml); + else if (tag == "move") + move_notes_dialog->read_configuration(xml); + else if (tag == "transpose") + transpose_dialog->read_configuration(xml); + else if (tag == "crescendo") + crescendo_dialog->read_configuration(xml); + else if (tag == "legato") + legato_dialog->read_configuration(xml); + else + xml.unknown("function_dialogs"); + break; + + case Xml::TagEnd: + if (tag == "dialogs") + return; + + default: + break; + } + } +} + +void write_function_dialog_config(int level, Xml& xml) +{ + xml.tag(level++, "dialogs"); + + gatetime_dialog->write_configuration(level, xml); + velocity_dialog->write_configuration(level, xml); + quantize_dialog->write_configuration(level, xml); + erase_dialog->write_configuration(level, xml); + del_overlaps_dialog->write_configuration(level, xml); + set_notelen_dialog->write_configuration(level, xml); + move_notes_dialog->write_configuration(level, xml); + transpose_dialog->write_configuration(level, xml); + crescendo_dialog->write_configuration(level, xml); + legato_dialog->write_configuration(level, xml); + + xml.tag(level, "/dialogs"); +} diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h new file mode 100644 index 00000000..40e5f0e0 --- /dev/null +++ b/muse2/muse/functions.h @@ -0,0 +1,77 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: functions.h,v 1.20.2.19 2011/05/05 20:10 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __FUNCTIONS_H__ +#define __FUNCTIONS_H__ + +#include "widgets/function_dialogs/velocity.h" +#include "widgets/function_dialogs/quantize.h" +#include "widgets/function_dialogs/crescendo.h" +#include "widgets/function_dialogs/gatetime.h" +#include "widgets/function_dialogs/remove.h" +#include "widgets/function_dialogs/transpose.h" +#include "widgets/function_dialogs/setlen.h" +#include "widgets/function_dialogs/move.h" +#include "widgets/function_dialogs/deloverlaps.h" +#include "widgets/function_dialogs/legato.h" + +#include <set> +#include "part.h" + + +extern GateTime* gatetime_dialog; +extern Velocity* velocity_dialog; +extern Quantize* quantize_dialog; +extern Remove* erase_dialog; +extern DelOverlaps* del_overlaps_dialog; +extern Setlen* set_notelen_dialog; +extern Move* move_notes_dialog; +extern Transpose* transpose_dialog; +extern Crescendo* crescendo_dialog; +extern Legato* legato_dialog; + +void init_function_dialogs(QWidget* parent); + + +std::set<Part*> partlist_to_set(PartList* pl); +std::map<Event*, Part*> get_events(const std::set<Part*>& parts, int range); + +//these functions simply do their job, non-interactively +void modify_velocity(const std::set<Part*>& parts, int range, int rate, int offset=0); +void modify_off_velocity(const std::set<Part*>& parts, int range, int rate, int offset=0); +void modify_notelen(const std::set<Part*>& parts, int range, int rate, int offset=0); +void quantize_notes(const std::set<Part*>& parts, int range, int raster, bool len=false, int strength=100, int swing=0, int threshold=0); +void erase_notes(const std::set<Part*>& parts, int range, int velo_threshold=0, bool velo_thres_used=false, int len_threshold=0, bool len_thres_used=false); +void delete_overlaps(const std::set<Part*>& parts, int range); +void set_notelen(const std::set<Part*>& parts, int range, int len); +void move_notes(const std::set<Part*>& parts, int range, signed int ticks); +void transpose_notes(const std::set<Part*>& parts, int range, signed int halftonesteps); +void crescendo(const std::set<Part*>& parts, int range, int start_val, int end_val, bool absolute); +void legato(const std::set<Part*>& parts, int range, int min_len=1, bool dont_shorten=false); + + +//the below functions automatically open the dialog +//they return true if you click "ok" and false if "abort" +bool modify_velocity(const std::set<Part*>& parts); +bool modify_notelen(const std::set<Part*>& parts); +bool quantize_notes(const std::set<Part*>& parts); +bool set_notelen(const std::set<Part*>& parts); +bool move_notes(const std::set<Part*>& parts); +bool transpose_notes(const std::set<Part*>& parts); +bool crescendo(const std::set<Part*>& parts); +bool erase_notes(const std::set<Part*>& parts); +bool delete_overlaps(const std::set<Part*>& parts); +bool legato(const std::set<Part*>& parts); + + + +//functions for reading and writing default values +class Xml; +void read_function_dialog_config(Xml& xml); +void write_function_dialog_config(int level, Xml& xml); + +#endif diff --git a/muse2/muse/globals.cpp b/muse2/muse/globals.cpp index 6c0bbbc6..f8ae4454 100644 --- a/muse2/muse/globals.cpp +++ b/muse2/muse/globals.cpp @@ -174,10 +174,12 @@ const char* med_file_save_pattern[] = { */ const QStringList med_file_pattern = QT_TRANSLATE_NOOP("@default", + QString("all known files (*.med *.med.gz *.med.bz2 *.mid *.midi *.kar);;") + QString("med Files (*.med *.med.gz *.med.bz2);;") + QString("Uncompressed med Files (*.med);;") + QString("gzip compressed med Files (*.med.gz);;") + QString("bzip2 compressed med Files (*.med.bz2);;") + + QString("mid Files (*.mid *.midi *.kar);;") + QString("All Files (*)")).split(";;"); const QStringList med_file_save_pattern = QT_TRANSLATE_NOOP("@default", diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index 6917a0fd..3e4e641e 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -10,6 +10,9 @@ #include <errno.h> #include <values.h> +#include <set> +#include <utility> + #include <QMessageBox> #include "app.h" @@ -32,6 +35,9 @@ #include "audio.h" #include "gconfig.h" +using std::set; +using std::pair; + //--------------------------------------------------------- // importMidi //--------------------------------------------------------- @@ -137,26 +143,27 @@ bool MusE::importMidi(const QString name, bool merge) // the first target track bool first = true; - // somewhat silly and slooow: - for (int port = 0; port < MIDI_PORTS; ++port) { - for (int channel = 0; channel < MIDI_CHANNELS; ++channel) { - // - // check if there are any events for port/channel in track: - // - iMPEvent i; - for (i = el->begin(); i != el->end(); ++i) { - MidiPlayEvent ev = *i; - if (ev.type() != ME_SYSEX && ev.type() != ME_META - && ev.channel() == channel && ev.port() == port) - break; - } - if (i == el->end()) - continue; + + // vastly changed by flo: replaced that silly loop + // with that already_processed-set-check. + // this makes stuff really fast :) + + iMPEvent ev; + set< pair<int,int> > already_processed; + for (ev = el->begin(); ev != el->end(); ++ev) + { + if (ev->type() != ME_SYSEX && ev->type() != ME_META) + { + int channel=ev->channel(); + int port=ev->port(); + + if (already_processed.find(pair<int,int>(channel, port)) == already_processed.end()) + { + already_processed.insert(pair<int,int>(channel, port)); + MidiTrack* track = new MidiTrack(); if ((*t)->isDrumTrack) - { track->setType(Track::DRUM); - } track->setOutChannel(channel); track->setOutPort(port); @@ -171,15 +178,6 @@ bool MusE::importMidi(const QString name, bool merge) buildMidiEventList(mel, el, track, division, first, false); first = false; - // Removed by T356. Handled by addPortCtrlEvents() below. - //for (iEvent i = mel->begin(); i != mel->end(); ++i) { - // Event event = i->second; - // if (event.type() == Controller) { - // importController(channel, mport, event.dataA()); - // midiPorts[track->outPort()].setCtrl(channel, event.tick(), event.dataA(), event.dataB()); - // } - // } - // Comment Added by T356. // Hmm. buildMidiEventList already takes care of this. // But it seems to work. How? Must test. @@ -208,13 +206,11 @@ bool MusE::importMidi(const QString name, bool merge) processTrack(track); - // Added by T356. Send all controller values to the port's controller value list. - // No, done in song->insertTrack2() now. - //track->addPortCtrlEvents(); - song->insertTrack0(track, -1); - } - } + } + } + } + if (first) { // // track does only contain non-channel messages diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp index 11e9cfc5..080ee01c 100644 --- a/muse2/muse/liste/listedit.cpp +++ b/muse2/muse/liste/listedit.cpp @@ -445,7 +445,7 @@ QString EventListItem::text(int col) const //--------------------------------------------------------- ListEdit::ListEdit(PartList* pl) - : MidiEditor(0, 0, pl) + : MidiEditor(0, pl) { insertItems = new QActionGroup(this); insertItems->setExclusive(false); diff --git a/muse2/muse/main.cpp b/muse2/muse/main.cpp index 53f8961b..192c0bd3 100644 --- a/muse2/muse/main.cpp +++ b/muse2/muse/main.cpp @@ -27,6 +27,7 @@ #include "globals.h" #include "icons.h" #include "sync.h" +#include "functions.h" extern bool initDummyAudio(); extern void initIcons(); @@ -253,6 +254,7 @@ int main(int argc, char* argv[]) QApplication::setColorSpec(QApplication::ManyColor); MuseApplication app(argc, argv); + init_function_dialogs(muse); initShortCuts(); readConfiguration(); @@ -471,6 +473,7 @@ int main(int argc, char* argv[]) app.setMuse(muse); muse->setWindowIcon(*museIcon); + // Added by Tim. p3.3.22 if (!debugMode) { if (mlockall(MCL_CURRENT | MCL_FUTURE)) diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp index 2f921cdc..9083c024 100644 --- a/muse2/muse/master/lmaster.cpp +++ b/muse2/muse/master/lmaster.cpp @@ -125,6 +125,7 @@ LMaster::LMaster() setWindowTitle(tr("MusE: Mastertrack")); setMinimumHeight(100); setFixedWidth(400); + setFocusPolicy(Qt::StrongFocus); //---------Pulldown Menu---------------------------- menuEdit = menuBar()->addMenu(tr("&Edit")); diff --git a/muse2/muse/master/masteredit.cpp b/muse2/muse/master/masteredit.cpp index 2b91ae90..9053f3a8 100644 --- a/muse2/muse/master/masteredit.cpp +++ b/muse2/muse/master/masteredit.cpp @@ -33,6 +33,9 @@ #include <QToolButton> int MasterEdit::_rasterInit = 0; +int MasterEdit::_widthInit = 600; +int MasterEdit::_heightInit = 400; +QByteArray MasterEdit::_toolbarInit; //--------------------------------------------------------- // closeEvent @@ -77,12 +80,12 @@ void MasterEdit::songChanged(int type) //--------------------------------------------------------- MasterEdit::MasterEdit() - : MidiEditor(0, _rasterInit, 0) + : MidiEditor(_rasterInit, 0) { setWindowTitle(tr("MusE: Mastertrack")); _raster = 0; // measure setMinimumSize(400, 300); - resize(500, 350); + resize(_widthInit, _heightInit); //---------Pulldown Menu---------------------------- // QPopupMenu* file = new QPopupMenu(this); @@ -229,6 +232,9 @@ MasterEdit::MasterEdit() connect(canvas, SIGNAL(followEvent(int)), hscroll, SLOT(setOffset(int))); connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); + + if (!_toolbarInit.isEmpty()) + restoreState(_toolbarInit); } //--------------------------------------------------------- @@ -317,6 +323,12 @@ void MasterEdit::readConfiguration(Xml& xml) case Xml::TagStart: if (tag == "raster") _rasterInit = xml.parseInt(); + else if (tag == "width") + _widthInit = xml.parseInt(); + else if (tag == "height") + _heightInit = xml.parseInt(); + else if (tag == "toolbars") + _toolbarInit = QByteArray::fromHex(xml.parse1().toAscii()); else xml.unknown("MasterEdit"); break; @@ -337,6 +349,9 @@ void MasterEdit::writeConfiguration(int level, Xml& xml) { xml.tag(level++, "masteredit"); xml.intTag(level, "raster", _rasterInit); + xml.intTag(level, "width", _widthInit); + xml.intTag(level, "height", _heightInit); + xml.strTag(level, "toolbars", _toolbarInit.toHex().data()); xml.tag(level, "/masteredit"); } @@ -404,3 +419,35 @@ void MasterEdit::setTempo(int val) } } + +//--------------------------------------------------------- +// resizeEvent +//--------------------------------------------------------- + +void MasterEdit::resizeEvent(QResizeEvent* ev) + { + QWidget::resizeEvent(ev); + storeInitialState(); + } + +//--------------------------------------------------------- +// focusOutEvent +//--------------------------------------------------------- + +void MasterEdit::focusOutEvent(QFocusEvent* ev) + { + QWidget::focusOutEvent(ev); + storeInitialState(); + } + + +//--------------------------------------------------------- +// storeInitialState +//--------------------------------------------------------- + +void MasterEdit::storeInitialState() + { + _widthInit = width(); + _heightInit = height(); + _toolbarInit=saveState(); + } diff --git a/muse2/muse/master/masteredit.h b/muse2/muse/master/masteredit.h index af43c7b0..59a5ab05 100644 --- a/muse2/muse/master/masteredit.h +++ b/muse2/muse/master/masteredit.h @@ -8,6 +8,9 @@ #ifndef __MASTER_EDIT_H__ #define __MASTER_EDIT_H__ +#include <QByteArray> +#include <QResizeEvent> + #include "midieditor.h" #include "noteinfo.h" #include "cobject.h" @@ -56,9 +59,14 @@ class MasterEdit : public MidiEditor { QToolButton* enableButton; static int _rasterInit; + static int _widthInit, _heightInit; + static QByteArray _toolbarInit; Q_OBJECT virtual void closeEvent(QCloseEvent*); + virtual void resizeEvent(QResizeEvent*); + virtual void focusOutEvent(QFocusEvent*); + void storeInitialState(); private slots: void _setRaster(int); diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 7087b342..39ae7874 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -14,7 +14,6 @@ #include "song.h" #include "midi.h" #include "drummap.h" -//#include "midiedit/drummap.h" // p4.0.2 #include "event.h" #include "globals.h" #include "midictrl.h" @@ -220,12 +219,8 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, if(!(ev.isNoteOff() && loopn == 0)) { if(cmode == Song::CYCLE_REPLACE && loopn < loopc) - { - // Added by Tim. p3.3.8 - //printf("buildMidiEventList: CYCLE_REPLACE t:%d type:%d A:%d B:%d ln:%d lc:%d\n", tick, ev.type(), ev.dataA(), ev.dataB(), loopn, loopc); - continue; - } + // If we want NORMAL, same as REPLACE except keep all events from the previous loop // from rec stop position to right marker (and beyond). if(cmode == Song::CYCLE_NORMAL) @@ -233,12 +228,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, // Not sure of accuracy here. Adjust? Adjusted when used elsewhere? unsigned endRec = audio->getEndRecordPos().tick(); if((tick < endRec && loopn < loopc) || (tick >= endRec && loopn < (loopc - 1))) - { - // Added by Tim. p3.3.8 - //printf("buildMidiEventList: CYCLE_NORMAL t:%d type:%d A:%d B:%d ln:%d lc:%d\n", tick, ev.type(), ev.dataA(), ev.dataB(), loopn, loopc); - continue; - } } } } @@ -451,8 +441,6 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, } break; case 0x59: // Key Signature - // track->scale.set(data[0]); - // track->scale.setMajorMinor(data[1]); break; default: printf("unknown Meta 0x%x %d\n", ev.dataA(), ev.dataA()); @@ -462,74 +450,27 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, } // switch(ev.type() if (!e.empty()) { e.setTick(tick); - // Added by Tim. p3.3.8 - //printf("buildMidiEventList: mel adding t:%d type:%d A:%d B:%d C:%d\n", tick, e.type(), e.dataA(), e.dataB(), e.dataC()); - mel.add(e); } } // i != el->end() + //--------------------------------------------------- - // resolve NoteOff events + // read NoteOn events and remove corresponding NoteOffs //--------------------------------------------------- -// for (iEvent i = mel.begin(); i != mel.end(); ++i) { -// Event event = i->second; -// if (event.isNote()) -// event.setLenTick(0); -// } - // Added by Tim. p3.3.8 - - // The loop is a safe way to delete while iterating. - bool loop; - do - { - loop = false; - + // Loop removed by flo for (iEvent i = mel.begin(); i != mel.end(); ++i) { Event ev = i->second; if (ev.isNote()) { - if (ev.isNoteOff()) { - iEvent k; - bool found = false; - for (k = i; k != mel.end(); ++k) { - Event event = k->second; - if (event.tick() > ev.tick()) - break; - if (event.isNoteOff(ev)) { - ev.setLenTick(1); - ev.setVelo(event.velo()); - ev.setVeloOff(0); - // Added by Tim. p3.3.8 - //printf("buildMidiEventList: found note off: event t:%d len:%d type:%d A:%d B:%d C:%d ev t:%d len:%d type:%d A:%d B:%d C:%d\n", event.tick(), event.lenTick(), event.type(), event.dataA(), event.dataB(), event.dataC(), ev.tick(), ev.lenTick(), ev.type(), ev.dataA(), ev.dataB(), ev.dataC()); - - found = true; - break; - } - } - if (!found) { - printf("NOTE OFF without Note ON tick %d type %d %d %d\n", - ev.tick(), ev.type(), ev.pitch(), ev.velo()); - } - else { - mel.erase(k); - - // Changed by Tim. p3.3.8 - //continue; - loop = true; - break; - - } - } + if (!ev.isNoteOff()) { // Added by Tim. p3.3.8 // If the event length is not zero, it means the event and its // note on/off have already been taken care of. So ignore it. if(ev.lenTick() != 0) - { continue; - } iEvent k; for (k = mel.lower_bound(ev.tick()); k != mel.end(); ++k) { @@ -547,9 +488,6 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, } ev.setLenTick(t); ev.setVeloOff(event.veloOff()); - // Added by Tim. p3.3.8 - //printf("buildMidiEventList: set len and velOff: event t:%d len:%d type:%d A:%d B:%d C:%d ev t:%d len:%d type:%d A:%d B:%d C:%d\n", event.tick(), event.lenTick(), event.type(), event.dataA(), event.dataB(), event.dataC(), ev.tick(), ev.lenTick(), ev.type(), ev.dataA(), ev.dataB(), ev.dataC()); - break; } } @@ -563,35 +501,25 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, ev.setLenTick(endTick-ev.tick()); } else { - mel.erase(k); - // Added by Tim. p3.3.8 - loop = true; - break; + if (k==i) + //this will never happen, because i->second has to be a NOTE ON, + //while k has to be a NOTE OFF. but in case something changes: + printf("ERROR: THIS SHOULD NEVER HAPPEN: k==i in midi.cpp:buildMidiEventList()\n"); + else + mel.erase(k); + continue; } } + } } - } - while (loop); - -// DEBUG: any note offs left? - - // Removed by Tim. p3.3.8 - //for (iEvent i = mel.begin(); i != mel.end(); ++i) { - // Event ev = i->second; - // if (ev.isNoteOff()) { - // printf("+extra note-off! %d pitch %d velo %d\n", - // i->first, ev.pitch(), ev.velo()); -// ev.dump(); - // } - // } + for (iEvent i = mel.begin(); i != mel.end(); ++i) { Event ev = i->second; if (ev.isNoteOff()) { printf("+extra note-off! %d pitch %d velo %d\n", i->first, ev.pitch(), ev.velo()); -// ev.dump(); continue; } int tick = CALC_TICK(ev.tick()); //(ev.tick() * config.division + div/2) / div; @@ -870,8 +798,6 @@ void Audio::collectEvents(MidiTrack* track, unsigned int cts, unsigned int nts) // Added by T356. case Controller: { - //int len = ev.lenTick(); - //int pitch = ev.pitch(); if (track->type() == Track::DRUM) { int ctl = ev.dataA(); @@ -894,8 +820,6 @@ void Audio::collectEvents(MidiTrack* track, unsigned int cts, unsigned int nts) mdAlt->playEvents()->add(MidiPlayEvent(tick, port, channel, ME_CONTROLLER, ctl | pitch, ev.dataB())); else - - //playEvents->add(MidiPlayEvent(frame, port, channel, ev)); mdAlt->playEvents()->add(MidiPlayEvent(frame, port, channel, ME_CONTROLLER, ctl | pitch, ev.dataB())); diff --git a/muse2/muse/midiedit/CMakeLists.txt b/muse2/muse/midiedit/CMakeLists.txt index 7e973aaa..9c3441e9 100644 --- a/muse2/muse/midiedit/CMakeLists.txt +++ b/muse2/muse/midiedit/CMakeLists.txt @@ -35,7 +35,6 @@ QT4_WRAP_CPP ( midiedit_mocs piano.h pianoroll.h prcanvas.h - quantconfig.h scoreedit.h ) @@ -58,7 +57,6 @@ file (GLOB midiedit_source_files piano.cpp pianoroll.cpp prcanvas.cpp - quantconfig.cpp scoreedit.cpp ) @@ -96,6 +94,7 @@ target_link_libraries ( midiedit ctrl icons widgets + widgets_functiondialogs ) ## diff --git a/muse2/muse/midiedit/cmd.h b/muse2/muse/midiedit/cmd.h index 8339b7ae..b72166b1 100644 --- a/muse2/muse/midiedit/cmd.h +++ b/muse2/muse/midiedit/cmd.h @@ -12,17 +12,18 @@ #define CMD_RIGHT 1 #define CMD_INSERT 2 #define CMD_DELETE 3 -#define CMD_1 4 -#define CMD_2 5 -#define CMD_3 6 -#define CMD_4 7 -#define CMD_5 8 -#define CMD_6 9 -#define CMD_7 10 -#define CMD_T 11 -#define CMD_period 12 -#define CMD_LEFT_NOSNAP 13 -#define CMD_RIGHT_NOSNAP 14 +#define CMD_BACKSPACE 4 +#define CMD_1 5 +#define CMD_2 6 +#define CMD_3 7 +#define CMD_4 8 +#define CMD_5 9 +#define CMD_6 10 +#define CMD_7 11 +#define CMD_T 12 +#define CMD_period 13 +#define CMD_LEFT_NOSNAP 14 +#define CMD_RIGHT_NOSNAP 15 #endif diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 1303c189..eea29b46 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -19,6 +19,7 @@ #include <stdio.h> #include <values.h> #include <errno.h> +#include <set> //#include <sys/stat.h> //#include <sys/mman.h> @@ -31,7 +32,6 @@ #include "globals.h" #include "midiport.h" #include "audio.h" -#include "velocity.h" #include "shortcuts.h" #include "icons.h" @@ -608,7 +608,7 @@ void DrumCanvas::drawCanvas(QPainter& p, const QRect& rect) //--------------------------------------------------------- // drawTopItem //--------------------------------------------------------- -void DrumCanvas::drawTopItem(QPainter &p, const QRect &r) +void DrumCanvas::drawTopItem(QPainter& p, const QRect&) { // draw cursor if (_tool == CursorTool) { @@ -743,20 +743,6 @@ void DrumCanvas::cmd(int cmd) editor->setCurCanvasPart(newpt); } break; - case CMD_DEL: - if (selectionSize()) { - song->startUndo(); - for (iCItem i = items.begin(); i != items.end(); ++i) { - if (!i->second->isSelected()) - continue; - Event ev = i->second->event(); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(ev, i->second->part(), false); - audio->msgDeleteEvent(ev, i->second->part(), false, false, false); - } - song->endUndo(SC_EVENT_REMOVED); - } - return; case CMD_SAVE: case CMD_LOAD: @@ -819,52 +805,6 @@ void DrumCanvas::cmd(int cmd) song->setPos(0, p, true, true, true); //CDW } break; - case CMD_MODIFY_VELOCITY: - { - Velocity w; - w.setRange(0); //TODO: Make this work! Probably put _to & _toInit in ecanvas instead - if (!w.exec()) - break; - int range = w.range(); // all, selected, looped, sel+loop - int rate = w.rateVal(); - int offset = w.offsetVal(); - - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); ++k) { - DEvent* devent = (DEvent*)(k->second); - Event event = devent->event(); - if (event.type() != Note) - continue; - unsigned tick = event.tick(); - bool selected = k->second->isSelected(); - bool inLoop = (tick >= song->lpos()) && (tick < song->rpos()); - - if ((range == 0) - || (range == 1 && selected) - || (range == 2 && inLoop) - || (range == 3 && selected && inLoop)) { - int velo = event.velo(); - - //velo = rate ? (velo * 100) / rate : 64; - velo = (velo * rate) / 100; - velo += offset; - - if (velo <= 0) - velo = 1; - if (velo > 127) - velo = 127; - if (event.velo() != velo) { - Event newEvent = event.clone(); - newEvent.setVelo(velo); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, newEvent, devent->part(), false); - audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false); - } - } - } - song->endUndo(SC_EVENT_MODIFIED); - } - break; } updateSelection(); redraw(); @@ -1399,13 +1339,10 @@ void DrumCanvas::keyPress(QKeyEvent* event) if (_tool == CursorTool) { int key = event->key(); - ///if (event->state() & Qt::ShiftButton) if (((QInputEvent*)event)->modifiers() & Qt::ShiftModifier) key += Qt::SHIFT; - ///if (event->state() & Qt::AltButton) if (((QInputEvent*)event)->modifiers() & Qt::AltModifier) key += Qt::ALT; - ///if (event->state() & Qt::ControlButton) if (((QInputEvent*)event)->modifiers() & Qt::ControlModifier) key+= Qt::CTRL; @@ -1538,3 +1475,31 @@ void DrumCanvas::selectCursorEvent(Event *ev) } updateSelection(); } + + +void DrumCanvas::moveAwayUnused() +{ + using std::set; + + set<int> used; + for (iCItem it=items.begin(); it!=items.end(); it++) + { + const Event& ev=it->second->event(); + + if (ev.type()==Note) + used.insert(ev.pitch()); + } + + int count=0; + for (set<int>::iterator it=used.begin(); it!=used.end();) + { + while ((*it != count) && (used.find(count)!=used.end())) count++; + + if (*it != count) + mapChanged(*it, count); + + count++; + + used.erase(it++); + } +} diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 4e05a422..b86bc2d7 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -84,13 +84,15 @@ class DrumCanvas : public EventCanvas { void setTool2(int); void setCurDrumInstrument(int); virtual void setStep(int); + void moveAwayUnused(); public: enum { CMD_CUT, CMD_COPY, CMD_PASTE, CMD_SAVE, CMD_LOAD, CMD_RESET, CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT, CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PREV_PART, CMD_SELECT_NEXT_PART, - CMD_DEL, CMD_FIXED_LEN, CMD_RIGHT, CMD_LEFT, CMD_RIGHT_NOSNAP, CMD_LEFT_NOSNAP, CMD_MODIFY_VELOCITY + CMD_DEL, CMD_FIXED_LEN, CMD_RIGHT, CMD_LEFT, CMD_RIGHT_NOSNAP, CMD_LEFT_NOSNAP, CMD_MODIFY_VELOCITY, CMD_CRESCENDO, + CMD_QUANTIZE, CMD_ERASE_EVENT, CMD_NOTE_SHIFT, CMD_DELETE_OVERLAPS, CMD_REORDER_LIST }; DrumCanvas(MidiEditor*, QWidget*, int, int, const char* name = 0); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 3736d6aa..3b8670db 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -220,8 +220,6 @@ void DList::viewMousePressEvent(QMouseEvent* ev) int x = ev->x(); int y = ev->y(); int button = ev->button(); - ///bool shift = ev->state() & Qt::ShiftButton; - //bool shift = ev->modifiers() & Qt::ShiftModifier; unsigned pitch = y / TH; DrumMap* dm = &drumMap[pitch]; @@ -259,7 +257,6 @@ void DList::viewMousePressEvent(QMouseEvent* ev) break; case COL_PORT: if (button == Qt::RightButton) { - ///bool changeAll = ev->state() & Qt::ControlButton; bool changeAll = ev->modifiers() & Qt::ControlModifier; devicesPopupMenu(dm, mapx(x), mapy(pitch * TH), changeAll); } @@ -328,7 +325,6 @@ void DList::viewMousePressEvent(QMouseEvent* ev) else if (val > 127) val = 127; - ///if (ev->state() & Qt::ControlButton) { if (ev->modifiers() & Qt::ControlModifier) { audio->msgIdle(true); // Delete all port controller events. @@ -724,7 +720,6 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev) editor->setFocus(); int x = ev->x(); int y = ev->y(); - ///bool shift = ev->state() & Qt::ShiftButton; bool shift = ev->modifiers() & Qt::ShiftModifier; unsigned pitch = y / TH; diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 5cd4c130..97ab092e 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -43,6 +43,7 @@ #include "drummap.h" #include "audio.h" #include "gconfig.h" +#include "functions.h" /* static const char* map_file_pattern[] = { @@ -59,17 +60,16 @@ static const char* map_file_save_pattern[] = { }; */ -int DrumEdit::_quantInit = 96; int DrumEdit::_rasterInit = 96; int DrumEdit::_widthInit = 600; int DrumEdit::_heightInit = 400; int DrumEdit::_dlistWidthInit = 50; int DrumEdit::_dcanvasWidthInit = 300; -int DrumEdit::_toInit = 0; +QByteArray DrumEdit::_toolbarInit; static const int xscale = -10; static const int yscale = 1; -static const int drumeditTools = PointerTool | PencilTool | RubberTool | CursorTool; +static const int drumeditTools = PointerTool | PencilTool | RubberTool | CursorTool | DrawTool; enum DrumColumn { COL_MUTE = 0, @@ -155,12 +155,12 @@ void DrumEdit::closeEvent(QCloseEvent* e) //--------------------------------------------------------- DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned initPos) - : MidiEditor(_quantInit, _rasterInit, pl, parent, name) + : MidiEditor(_rasterInit, pl, parent, name) { + setFocusPolicy(Qt::StrongFocus); split1w1 = 0; resize(_widthInit, _heightInit); selPart = 0; - _to = _toInit; QSignalMapper *signalMapper = new QSignalMapper(this); //---------Pulldown Menu---------------------------- @@ -233,14 +233,33 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini menuFunctions->setTearOffEnabled(true); + QAction* reorderListAction = menuFunctions->addAction(tr("Re-order list")); + menuFunctions->addSeparator(); fixedAction = menuFunctions->addAction(tr("Set Fixed Length")); veloAction = menuFunctions->addAction(tr("Modify Velocity")); + crescAction = menuFunctions->addAction(tr("Crescendo/Decrescendo")); + quantizeAction = menuFunctions->addAction(tr("Quantize")); + QAction* eraseEventAction = menuFunctions->addAction(tr("Erase Event")); + QAction* noteShiftAction = menuFunctions->addAction(tr("Move Notes")); + QAction* delOverlapsAction = menuFunctions->addAction(tr("Delete Overlaps")); + connect(reorderListAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(fixedAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(veloAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(crescAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(quantizeAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(eraseEventAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(noteShiftAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(delOverlapsAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + signalMapper->setMapping(reorderListAction, DrumCanvas::CMD_REORDER_LIST); signalMapper->setMapping(fixedAction, DrumCanvas::CMD_FIXED_LEN); signalMapper->setMapping(veloAction, DrumCanvas::CMD_MODIFY_VELOCITY); + signalMapper->setMapping(crescAction, DrumCanvas::CMD_CRESCENDO); + signalMapper->setMapping(quantizeAction, DrumCanvas::CMD_QUANTIZE); + signalMapper->setMapping(eraseEventAction, DrumCanvas::CMD_ERASE_EVENT); + signalMapper->setMapping(noteShiftAction, DrumCanvas::CMD_NOTE_SHIFT); + signalMapper->setMapping(delOverlapsAction, DrumCanvas::CMD_DELETE_OVERLAPS); QMenu* menuScriptPlugins = menuBar()->addMenu(tr("&Plugins")); song->populateScriptMenu(menuScriptPlugins, this); @@ -317,7 +336,7 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini addToolBarBreak(); // don't show pitch value in toolbar - toolbar = new Toolbar1(this, _rasterInit, _quantInit, false); + toolbar = new Toolbar1(this, _rasterInit, false); addToolBar(toolbar); addToolBarBreak(); @@ -456,13 +475,15 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini // connect toolbar connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); connect(time, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); - connect(toolbar, SIGNAL(quantChanged(int)), SLOT(setQuant(int))); connect(toolbar, SIGNAL(rasterChanged(int)), SLOT(setRaster(int))); connect(toolbar, SIGNAL(soloChanged(bool)), SLOT(soloChanged(bool))); connect(info, SIGNAL(valueChanged(NoteInfo::ValType, int)), SLOT(noteinfoChanged(NoteInfo::ValType, int))); connect(ctrl, SIGNAL(clicked()), SLOT(addCtrl())); + if (!_toolbarInit.isEmpty()) + restoreState(_toolbarInit); + QClipboard* cb = QApplication::clipboard(); connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged())); @@ -603,16 +624,6 @@ void DrumEdit::setRaster(int val) } //--------------------------------------------------------- -// setQuant -//--------------------------------------------------------- - -void DrumEdit::setQuant(int val) - { - _quantInit = val; - MidiEditor::setQuant(val); - } - -//--------------------------------------------------------- // edit currently selected Event //--------------------------------------------------------- @@ -722,10 +733,8 @@ void DrumEdit::readStatus(Xml& xml) break; case Xml::TagEnd: if (tag == "drumedit") { - _quantInit = _quant; _rasterInit = _raster; toolbar->setRaster(_raster); - toolbar->setQuant(_quant); canvas->redrawGrid(); return; } @@ -749,9 +758,7 @@ void DrumEdit::readConfiguration(Xml& xml) case Xml::End: return; case Xml::TagStart: - if (tag == "quant") - _quantInit = xml.parseInt(); - else if (tag == "raster") + if (tag == "raster") _rasterInit = xml.parseInt(); else if (tag == "width") _widthInit = xml.parseInt(); @@ -761,9 +768,8 @@ void DrumEdit::readConfiguration(Xml& xml) _dcanvasWidthInit = xml.parseInt(); else if (tag == "dlistwidth") _dlistWidthInit = xml.parseInt(); - else if (tag == "to") { - _toInit = xml.parseInt(); - } + else if (tag == "toolbars") + _toolbarInit = QByteArray::fromHex(xml.parse1().toAscii()); else xml.unknown("DrumEdit"); break; @@ -784,13 +790,12 @@ void DrumEdit::readConfiguration(Xml& xml) void DrumEdit::writeConfiguration(int level, Xml& xml) { xml.tag(level++, "drumedit"); - xml.intTag(level, "quant", _quantInit); xml.intTag(level, "raster", _rasterInit); xml.intTag(level, "width", _widthInit); xml.intTag(level, "height", _heightInit); xml.intTag(level, "dlistwidth", _dlistWidthInit); xml.intTag(level, "dcanvaswidth", _dcanvasWidthInit); - xml.intTag(level, "to", _toInit); + xml.strTag(level, "toolbars", _toolbarInit.toHex().data()); xml.tag(level, "/drumedit"); } @@ -898,18 +903,27 @@ void DrumEdit::reset() void DrumEdit::cmd(int cmd) { switch(cmd) { - case DrumCanvas::CMD_LOAD: - load(); - break; - case DrumCanvas::CMD_SAVE: - save(); - break; - case DrumCanvas::CMD_RESET: - reset(); - break; - default: - ((DrumCanvas*)(canvas))->cmd(cmd); + case DrumCanvas::CMD_LOAD: load(); break; + case DrumCanvas::CMD_SAVE: save(); break; + case DrumCanvas::CMD_RESET: reset(); break; + case DrumCanvas::CMD_MODIFY_VELOCITY: modify_velocity(partlist_to_set(parts())); break; + case DrumCanvas::CMD_CRESCENDO: crescendo(partlist_to_set(parts())); break; + case DrumCanvas::CMD_QUANTIZE: + if (quantize_dialog->exec()) + quantize_notes(partlist_to_set(parts()), quantize_dialog->range, + (config.division*4)/(1<<quantize_dialog->raster_power2), + /* quant_len= */false, quantize_dialog->strength, + quantize_dialog->swing, quantize_dialog->threshold); break; + case DrumCanvas::CMD_ERASE_EVENT: erase_notes(partlist_to_set(parts())); break; + case DrumCanvas::CMD_DEL: erase_notes(partlist_to_set(parts()),1); break; //delete selected events + case DrumCanvas::CMD_DELETE_OVERLAPS: delete_overlaps(partlist_to_set(parts())); break; + case DrumCanvas::CMD_NOTE_SHIFT: move_notes(partlist_to_set(parts())); break; + case DrumCanvas::CMD_REORDER_LIST: ((DrumCanvas*)(canvas))->moveAwayUnused(); break; + //case DrumCanvas::CMD_FIXED_LEN: // this must be handled by the drum canvas, due to its + // special nature (each drum has its own length) + + default: ((DrumCanvas*)(canvas))->cmd(cmd); } } @@ -1028,12 +1042,31 @@ void DrumEdit::newCanvasWidth(int w) void DrumEdit::resizeEvent(QResizeEvent* ev) { QWidget::resizeEvent(ev); - _widthInit = ev->size().width(); - _heightInit = ev->size().height(); - + storeInitialState(); //TODO: Make the dlist not expand/shrink, but the canvas instead } +//--------------------------------------------------------- +// focusOutEvent +//--------------------------------------------------------- + +void DrumEdit::focusOutEvent(QFocusEvent* ev) + { + QWidget::focusOutEvent(ev); + storeInitialState(); + } + +//--------------------------------------------------------- +// storeInitialState +//--------------------------------------------------------- + +void DrumEdit::storeInitialState() + { + _widthInit = width(); + _heightInit = height(); + _toolbarInit=saveState(); + } + //--------------------------------------------------------- // configChanged @@ -1229,9 +1262,7 @@ void DrumEdit::keyPressEvent(QKeyEvent* event) event->ignore(); return; } - setQuant(val); setRaster(val); - toolbar->setQuant(_quant); toolbar->setRaster(_raster); } @@ -1271,7 +1302,7 @@ void DrumEdit::execDeliveredScript(int id) { //QString scriptfile = QString(INSTPREFIX) + SCRIPTSSUFFIX + deliveredScriptNames[id]; QString scriptfile = song->getScriptPath(id, true); - song->executeScript(scriptfile.toLatin1().constData(), parts(), quant(), true); + song->executeScript(scriptfile.toLatin1().constData(), parts(), raster(), true); } //--------------------------------------------------------- @@ -1280,7 +1311,7 @@ void DrumEdit::execDeliveredScript(int id) void DrumEdit::execUserScript(int id) { QString scriptfile = song->getScriptPath(id, false); - song->executeScript(scriptfile.toLatin1().constData(), parts(), quant(), true); + song->executeScript(scriptfile.toLatin1().constData(), parts(), raster(), true); } void DrumEdit::setStep(QString v) diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 02a1a5cc..30fe8487 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -8,6 +8,8 @@ #ifndef __DRUM_EDIT_H__ #define __DRUM_EDIT_H__ +#include <QByteArray> + #include <values.h> #include "midieditor.h" #include "noteinfo.h" @@ -66,15 +68,14 @@ class DrumEdit : public MidiEditor { QToolBar* tools; QComboBox *stepLenWidget; - static int _quantInit, _rasterInit; + static int _rasterInit; static int _widthInit, _heightInit; static int _dlistWidthInit, _dcanvasWidthInit; - - static int _toInit; //Used in function dialog for applying modification to selection + static QByteArray _toolbarInit; QAction *loadAction, *saveAction, *resetAction; QAction *cutAction, *copyAction, *pasteAction, *deleteAction; - QAction *fixedAction, *veloAction; + QAction *fixedAction, *veloAction, *crescAction, *quantizeAction; QAction *sallAction, *snoneAction, *invAction, *inAction , *outAction; QAction *prevAction, *nextAction; @@ -83,15 +84,17 @@ class DrumEdit : public MidiEditor { virtual void closeEvent(QCloseEvent*); QWidget* genToolbar(QWidget* parent); - virtual void resizeEvent(QResizeEvent*); virtual void keyPressEvent(QKeyEvent*); - int _to;//TODO: Make this work + + virtual void resizeEvent(QResizeEvent*); + virtual void focusOutEvent(QFocusEvent*); + void storeInitialState(); + void setHeaderToolTips(); void setHeaderWhatsThis(); private slots: void setRaster(int); - void setQuant(int); void noteinfoChanged(NoteInfo::ValType type, int val); //CtrlEdit* addCtrl(); void removeCtrl(CtrlEdit* ctrl); diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp index f02b10a6..ab83e85f 100644 --- a/muse2/muse/midiedit/pianoroll.cpp +++ b/muse2/muse/midiedit/pianoroll.cpp @@ -44,22 +44,19 @@ #include "gconfig.h" #include "icons.h" #include "audio.h" +#include "functions.h" + #include "cmd.h" -#include "quantconfig.h" #include "shortcuts.h" #include "mtrackinfo.h" -int PianoRoll::_quantInit = 96; int PianoRoll::_rasterInit = 96; int PianoRoll::_widthInit = 600; int PianoRoll::_heightInit = 400; -int PianoRoll::_quantStrengthInit = 80; // 1 - 100% -int PianoRoll::_quantLimitInit = 50; // tick value -bool PianoRoll::_quantLenInit = false; -int PianoRoll::_toInit = 0; int PianoRoll::colorModeInit = 0; +QByteArray PianoRoll::_toolbarInit; static const int xscale = -10; static const int yscale = 1; @@ -72,17 +69,12 @@ static int pianorollTools = PointerTool | PencilTool | RubberTool | DrawTool; //--------------------------------------------------------- PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned initPos) - : MidiEditor(_quantInit, _rasterInit, pl, parent, name) + : MidiEditor(_rasterInit, pl, parent, name) { deltaMode = false; resize(_widthInit, _heightInit); selPart = 0; - quantConfig = 0; _playEvents = false; - _quantStrength = _quantStrengthInit; - _quantLimit = _quantLimitInit; - _quantLen = _quantLenInit; - _to = _toInit; colorMode = colorModeInit; QSignalMapper* mapper = new QSignalMapper(this); @@ -186,30 +178,11 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i menuFunctions->setTearOffEnabled(true); - funcOverQuantAction = menuFunctions->addAction(tr("Over Quantize")); - mapper->setMapping(funcOverQuantAction, PianoCanvas::CMD_OVER_QUANTIZE); - connect(funcOverQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcNoteOnQuantAction = menuFunctions->addAction(tr("Note On Quantize")); - mapper->setMapping(funcNoteOnQuantAction, PianoCanvas::CMD_ON_QUANTIZE); - connect(funcNoteOnQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcNoteOnOffQuantAction = menuFunctions->addAction(tr("Note On/Off Quantize")); - mapper->setMapping(funcNoteOnOffQuantAction, PianoCanvas::CMD_ONOFF_QUANTIZE); - connect(funcNoteOnOffQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcIterQuantAction = menuFunctions->addAction(tr("Iterative Quantize")); - mapper->setMapping(funcIterQuantAction, PianoCanvas::CMD_ITERATIVE_QUANTIZE); - connect(funcIterQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuFunctions->addSeparator(); - - funcConfigQuantAction = menuFunctions->addAction(tr("Config Quant...")); - connect(funcConfigQuantAction, SIGNAL(triggered()), this, SLOT(configQuant())); - - menuFunctions->addSeparator(); + funcQuantizeAction = menuFunctions->addAction(tr("Quantize")); + mapper->setMapping(funcQuantizeAction, PianoCanvas::CMD_QUANTIZE); + connect(funcQuantizeAction, SIGNAL(triggered()), mapper, SLOT(map())); - funcGateTimeAction = menuFunctions->addAction(tr("Modify Gate Time")); + funcGateTimeAction = menuFunctions->addAction(tr("Modify Note Length")); mapper->setMapping(funcGateTimeAction, PianoCanvas::CMD_MODIFY_GATE_TIME); connect(funcGateTimeAction, SIGNAL(triggered()), mapper, SLOT(map())); @@ -217,56 +190,22 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i mapper->setMapping(funcModVelAction, PianoCanvas::CMD_MODIFY_VELOCITY); connect(funcModVelAction, SIGNAL(triggered()), mapper, SLOT(map())); - funcCrescendoAction = menuFunctions->addAction(tr("Crescendo")); - mapper->setMapping(funcCrescendoAction, PianoCanvas::CMD_CRESCENDO); - funcCrescendoAction->setEnabled(false); - connect(funcCrescendoAction, SIGNAL(triggered()), mapper, SLOT(map())); + funcCrescAction = menuFunctions->addAction(tr("Crescendo/Decrescendo")); + mapper->setMapping(funcCrescAction, PianoCanvas::CMD_CRESCENDO); + connect(funcCrescAction, SIGNAL(triggered()), mapper, SLOT(map())); funcTransposeAction = menuFunctions->addAction(tr("Transpose")); mapper->setMapping(funcTransposeAction, PianoCanvas::CMD_TRANSPOSE); - funcTransposeAction->setEnabled(false); connect(funcTransposeAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcThinOutAction = menuFunctions->addAction(tr("Thin Out")); - mapper->setMapping(funcThinOutAction, PianoCanvas::CMD_THIN_OUT); - funcThinOutAction->setEnabled(false); - connect(funcThinOutAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcEraseEventAction = menuFunctions->addAction(tr("Erase Event")); + + funcEraseEventAction = menuFunctions->addAction(tr("Erase Events")); mapper->setMapping(funcEraseEventAction, PianoCanvas::CMD_ERASE_EVENT); - funcEraseEventAction->setEnabled(false); connect(funcEraseEventAction, SIGNAL(triggered()), mapper, SLOT(map())); - funcNoteShiftAction = menuFunctions->addAction(tr("Note Shift")); + funcNoteShiftAction = menuFunctions->addAction(tr("Move Notes")); mapper->setMapping(funcNoteShiftAction, PianoCanvas::CMD_NOTE_SHIFT); - funcNoteShiftAction->setEnabled(false); connect(funcNoteShiftAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcMoveClockAction = menuFunctions->addAction(tr("Move Clock")); - mapper->setMapping(funcMoveClockAction, PianoCanvas::CMD_MOVE_CLOCK); - funcMoveClockAction->setEnabled(false); - connect(funcMoveClockAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcCopyMeasureAction = menuFunctions->addAction(tr("Copy Measure")); - mapper->setMapping(funcCopyMeasureAction, PianoCanvas::CMD_COPY_MEASURE); - funcCopyMeasureAction->setEnabled(false); - connect(funcCopyMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcEraseMeasureAction = menuFunctions->addAction(tr("Erase Measure")); - mapper->setMapping(funcEraseMeasureAction, PianoCanvas::CMD_ERASE_MEASURE); - funcEraseMeasureAction->setEnabled(false); - connect(funcEraseMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcDelMeasureAction = menuFunctions->addAction(tr("Delete Measure")); - mapper->setMapping(funcDelMeasureAction, PianoCanvas::CMD_DELETE_MEASURE); - funcDelMeasureAction->setEnabled(false); - connect(funcDelMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcCreateMeasureAction = menuFunctions->addAction(tr("Create Measure")); - mapper->setMapping(funcCreateMeasureAction, PianoCanvas::CMD_CREATE_MEASURE); - funcCreateMeasureAction->setEnabled(false); - connect(funcCreateMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - + funcSetFixedLenAction = menuFunctions->addAction(tr("Set Fixed Length")); mapper->setMapping(funcSetFixedLenAction, PianoCanvas::CMD_FIXED_LEN); connect(funcSetFixedLenAction, SIGNAL(triggered()), mapper, SLOT(map())); @@ -274,7 +213,12 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i funcDelOverlapsAction = menuFunctions->addAction(tr("Delete Overlaps")); mapper->setMapping(funcDelOverlapsAction, PianoCanvas::CMD_DELETE_OVERLAPS); connect(funcDelOverlapsAction, SIGNAL(triggered()), mapper, SLOT(map())); - + + QAction* funcLegatoAction = menuFunctions->addAction(tr("Legato")); + mapper->setMapping(funcLegatoAction, PianoCanvas::CMD_LEGATO); + connect(funcLegatoAction, SIGNAL(triggered()), mapper, SLOT(map())); + + menuPlugins = menuBar()->addMenu(tr("&Plugins")); song->populateScriptMenu(menuPlugins, this); @@ -318,7 +262,7 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i transport->addActions(transportAction->actions()); addToolBarBreak(); - toolbar = new Toolbar1(this, _rasterInit, _quantInit); + toolbar = new Toolbar1(this, _rasterInit); addToolBar(toolbar); addToolBarBreak(); @@ -518,14 +462,16 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); connect(piano, SIGNAL(pitchChanged(int)), toolbar, SLOT(setPitch(int))); connect(time, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); - connect(toolbar, SIGNAL(quantChanged(int)), SLOT(setQuant(int))); connect(toolbar, SIGNAL(rasterChanged(int)),SLOT(setRaster(int))); - connect(toolbar, SIGNAL(toChanged(int)), SLOT(setTo(int))); connect(toolbar, SIGNAL(soloChanged(bool)), SLOT(soloChanged(bool))); setFocusPolicy(Qt::StrongFocus); setEventColorMode(colorMode); + if (!_toolbarInit.isEmpty()) + restoreState(_toolbarInit); + + QClipboard* cb = QApplication::clipboard(); connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged())); @@ -657,7 +603,22 @@ PianoRoll::~PianoRoll() void PianoRoll::cmd(int cmd) { - ((PianoCanvas*)canvas)->cmd(cmd, _quantStrength, _quantLimit, _quantLen, _to); + switch (cmd) + { + case PianoCanvas::CMD_MODIFY_GATE_TIME: modify_notelen(partlist_to_set(parts())); break; + case PianoCanvas::CMD_MODIFY_VELOCITY: modify_velocity(partlist_to_set(parts())); break; + case PianoCanvas::CMD_CRESCENDO: crescendo(partlist_to_set(parts())); break; + case PianoCanvas::CMD_QUANTIZE: quantize_notes(partlist_to_set(parts())); break; + case PianoCanvas::CMD_TRANSPOSE: transpose_notes(partlist_to_set(parts())); break; + case PianoCanvas::CMD_ERASE_EVENT: erase_notes(partlist_to_set(parts())); break; + case PianoCanvas::CMD_DEL: erase_notes(partlist_to_set(parts()),1); break; + case PianoCanvas::CMD_NOTE_SHIFT: move_notes(partlist_to_set(parts())); break; + case PianoCanvas::CMD_FIXED_LEN: set_notelen(partlist_to_set(parts())); break; + case PianoCanvas::CMD_DELETE_OVERLAPS: delete_overlaps(partlist_to_set(parts())); break; + case PianoCanvas::CMD_LEGATO: legato(partlist_to_set(parts())); break; + + default: ((PianoCanvas*)canvas)->cmd(cmd); + } } //--------------------------------------------------------- @@ -835,24 +796,16 @@ void PianoRoll::readConfiguration(Xml& xml) const QString& tag = xml.s1(); switch (token) { case Xml::TagStart: - if (tag == "quant") - _quantInit = xml.parseInt(); - else if (tag == "raster") + if (tag == "raster") _rasterInit = xml.parseInt(); - else if (tag == "quantStrength") - _quantStrengthInit = xml.parseInt(); - else if (tag == "quantLimit") - _quantLimitInit = xml.parseInt(); - else if (tag == "quantLen") - _quantLenInit = xml.parseInt(); - else if (tag == "to") - _toInit = xml.parseInt(); else if (tag == "colormode") colorModeInit = xml.parseInt(); else if (tag == "width") _widthInit = xml.parseInt(); else if (tag == "height") _heightInit = xml.parseInt(); + else if (tag == "toolbars") + _toolbarInit = QByteArray::fromHex(xml.parse1().toAscii()); else xml.unknown("PianoRoll"); break; @@ -872,15 +825,11 @@ void PianoRoll::readConfiguration(Xml& xml) void PianoRoll::writeConfiguration(int level, Xml& xml) { xml.tag(level++, "pianoroll"); - xml.intTag(level, "quant", _quantInit); xml.intTag(level, "raster", _rasterInit); - xml.intTag(level, "quantStrength", _quantStrengthInit); - xml.intTag(level, "quantLimit", _quantLimitInit); - xml.intTag(level, "quantLen", _quantLenInit); - xml.intTag(level, "to", _toInit); xml.intTag(level, "width", _widthInit); xml.intTag(level, "height", _heightInit); xml.intTag(level, "colormode", colorModeInit); + xml.strTag(level, "toolbars", _toolbarInit.toHex().data()); xml.etag(level, "pianoroll"); } @@ -908,17 +857,6 @@ void PianoRoll::setRaster(int val) } //--------------------------------------------------------- -// setQuant -//--------------------------------------------------------- - -void PianoRoll::setQuant(int val) - { - _quantInit = val; - MidiEditor::setQuant(val); - canvas->setFocus(); - } - -//--------------------------------------------------------- // writeStatus //--------------------------------------------------------- @@ -938,9 +876,6 @@ void PianoRoll::writeStatus(int level, Xml& xml) const xml.intTag(level, "steprec", canvas->steprec()); xml.intTag(level, "midiin", canvas->midiin()); xml.intTag(level, "tool", int(canvas->tool())); - xml.intTag(level, "quantStrength", _quantStrength); - xml.intTag(level, "quantLimit", _quantLimit); - xml.intTag(level, "quantLen", _quantLen); xml.intTag(level, "playEvents", _playEvents); xml.intTag(level, "xpos", hscroll->pos()); xml.intTag(level, "xmag", hscroll->mag()); @@ -987,12 +922,6 @@ void PianoRoll::readStatus(Xml& xml) splitter->readStatus(xml); else if (tag == hsplitter->objectName()) hsplitter->readStatus(xml); - else if (tag == "quantStrength") - _quantStrength = xml.parseInt(); - else if (tag == "quantLimit") - _quantLimit = xml.parseInt(); - else if (tag == "quantLen") - _quantLen = xml.parseInt(); else if (tag == "playEvents") { _playEvents = xml.parseInt(); canvas->playEvents(_playEvents); @@ -1011,10 +940,8 @@ void PianoRoll::readStatus(Xml& xml) break; case Xml::TagEnd: if (tag == "pianoroll") { - _quantInit = _quant; _rasterInit = _raster; toolbar->setRaster(_raster); - toolbar->setQuant(_quant); canvas->redrawGrid(); return; } @@ -1059,13 +986,10 @@ void PianoRoll::keyPressEvent(QKeyEvent* event) PianoCanvas* pc = (PianoCanvas*)canvas; int key = event->key(); - //if (event->state() & Qt::ShiftButton) if (((QInputEvent*)event)->modifiers() & Qt::ShiftModifier) key += Qt::SHIFT; - //if (event->state() & Qt::AltButton) if (((QInputEvent*)event)->modifiers() & Qt::AltModifier) key += Qt::ALT; - //if (event->state() & Qt::ControlButton) if (((QInputEvent*)event)->modifiers() & Qt::ControlModifier) key+= Qt::CTRL; @@ -1109,8 +1033,8 @@ void PianoRoll::keyPressEvent(QKeyEvent* event) pc->pianoCmd(CMD_INSERT); return; } - else if (key == Qt::Key_Delete) { - pc->pianoCmd(CMD_DELETE); + else if (key == Qt::Key_Backspace) { + pc->pianoCmd(CMD_BACKSPACE); return; } else if (key == shortcuts[SHRT_ZOOM_IN].key) { @@ -1196,28 +1120,11 @@ void PianoRoll::keyPressEvent(QKeyEvent* event) event->ignore(); return; } - setQuant(val); setRaster(val); - toolbar->setQuant(_quant); toolbar->setRaster(_raster); } //--------------------------------------------------------- -// configQuant -//--------------------------------------------------------- - -void PianoRoll::configQuant() - { - if (!quantConfig) { - quantConfig = new QuantConfig(_quantStrength, _quantLimit, _quantLen); - connect(quantConfig, SIGNAL(setQuantStrength(int)), SLOT(setQuantStrength(int))); - connect(quantConfig, SIGNAL(setQuantLimit(int)), SLOT(setQuantLimit(int))); - connect(quantConfig, SIGNAL(setQuantLen(bool)), SLOT(setQuantLen(bool))); - } - quantConfig->show(); - } - -//--------------------------------------------------------- // setSteprec //--------------------------------------------------------- @@ -1297,8 +1204,30 @@ void PianoRoll::setSpeaker(bool val) void PianoRoll::resizeEvent(QResizeEvent* ev) { QWidget::resizeEvent(ev); - _widthInit = ev->size().width(); - _heightInit = ev->size().height(); + storeInitialState(); + } + + +//--------------------------------------------------------- +// focusOutEvent +//--------------------------------------------------------- + +void PianoRoll::focusOutEvent(QFocusEvent* ev) + { + QWidget::focusOutEvent(ev); + storeInitialState(); + } + + +//--------------------------------------------------------- +// storeInitialState +//--------------------------------------------------------- + +void PianoRoll::storeInitialState() + { + _widthInit = width(); + _heightInit = height(); + _toolbarInit=saveState(); } @@ -1338,25 +1267,13 @@ void PianoRoll::initShortcuts() //evColorPitchAction->setShortcut(shortcuts[ ].key); //evColorVelAction->setShortcut(shortcuts[ ].key); - funcOverQuantAction->setShortcut(shortcuts[SHRT_OVER_QUANTIZE].key); - funcNoteOnQuantAction->setShortcut(shortcuts[SHRT_ON_QUANTIZE].key); - funcNoteOnOffQuantAction->setShortcut(shortcuts[SHRT_ONOFF_QUANTIZE].key); - funcIterQuantAction->setShortcut(shortcuts[SHRT_ITERATIVE_QUANTIZE].key); - - funcConfigQuantAction->setShortcut(shortcuts[SHRT_CONFIG_QUANT].key); + funcQuantizeAction->setShortcut(shortcuts[SHRT_QUANTIZE].key); funcGateTimeAction->setShortcut(shortcuts[SHRT_MODIFY_GATE_TIME].key); funcModVelAction->setShortcut(shortcuts[SHRT_MODIFY_VELOCITY].key); - funcCrescendoAction->setShortcut(shortcuts[SHRT_CRESCENDO].key); funcTransposeAction->setShortcut(shortcuts[SHRT_TRANSPOSE].key); - funcThinOutAction->setShortcut(shortcuts[SHRT_THIN_OUT].key); funcEraseEventAction->setShortcut(shortcuts[SHRT_ERASE_EVENT].key); funcNoteShiftAction->setShortcut(shortcuts[SHRT_NOTE_SHIFT].key); - funcMoveClockAction->setShortcut(shortcuts[SHRT_MOVE_CLOCK].key); - funcCopyMeasureAction->setShortcut(shortcuts[SHRT_COPY_MEASURE].key); - funcEraseMeasureAction->setShortcut(shortcuts[SHRT_ERASE_MEASURE].key); - funcDelMeasureAction->setShortcut(shortcuts[SHRT_DELETE_MEASURE].key); - funcCreateMeasureAction->setShortcut(shortcuts[SHRT_CREATE_MEASURE].key); funcSetFixedLenAction->setShortcut(shortcuts[SHRT_FIXED_LEN].key); funcDelOverlapsAction->setShortcut(shortcuts[SHRT_DELETE_OVERLAPS].key); @@ -1369,7 +1286,7 @@ void PianoRoll::execDeliveredScript(int id) { //QString scriptfile = QString(INSTPREFIX) + SCRIPTSSUFFIX + deliveredScriptNames[id]; QString scriptfile = song->getScriptPath(id, true); - song->executeScript(scriptfile.toAscii().data(), parts(), quant(), true); + song->executeScript(scriptfile.toAscii().data(), parts(), raster(), true); } //--------------------------------------------------------- @@ -1378,7 +1295,7 @@ void PianoRoll::execDeliveredScript(int id) void PianoRoll::execUserScript(int id) { QString scriptfile = song->getScriptPath(id, false); - song->executeScript(scriptfile.toAscii().data(), parts(), quant(), true); + song->executeScript(scriptfile.toAscii().data(), parts(), raster(), true); } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h index 2bfa9324..58c2487a 100644 --- a/muse2/muse/midiedit/pianoroll.h +++ b/muse2/muse/midiedit/pianoroll.h @@ -12,6 +12,7 @@ #include <QResizeEvent> #include <QLabel> #include <QKeyEvent> +#include <QByteArray> #include <values.h> #include "noteinfo.h" @@ -35,7 +36,6 @@ class Splitter; class PartList; class Toolbar1; class Xml; -class QuantConfig; class ScrollScale; class Part; class SNode; @@ -81,23 +81,13 @@ class PianoRoll : public MidiEditor { QAction* evColorPitchAction; QAction* evColorVelAction; - QAction* funcOverQuantAction; - QAction* funcNoteOnQuantAction; - QAction* funcNoteOnOffQuantAction; - QAction* funcIterQuantAction; - QAction* funcConfigQuantAction; + QAction* funcQuantizeAction; QAction* funcGateTimeAction; QAction* funcModVelAction; - QAction* funcCrescendoAction; + QAction* funcCrescAction; QAction* funcTransposeAction; - QAction* funcThinOutAction; QAction* funcEraseEventAction; QAction* funcNoteShiftAction; - QAction* funcMoveClockAction; - QAction* funcCopyMeasureAction; - QAction* funcEraseMeasureAction; - QAction* funcDelMeasureAction; - QAction* funcCreateMeasureAction; QAction* funcSetFixedLenAction; QAction* funcDelOverlapsAction; @@ -124,20 +114,12 @@ class PianoRoll : public MidiEditor { int colorMode; - static int _quantInit, _rasterInit; + static int _rasterInit; static int _widthInit, _heightInit; + static QByteArray _toolbarInit; - static int _quantStrengthInit; - static int _quantLimitInit; - static bool _quantLenInit; - static int _toInit; static int colorModeInit; - int _quantStrength; - int _quantLimit; - int _to; - bool _quantLen; - QuantConfig* quantConfig; bool _playEvents; //QScrollBar* infoScroll; @@ -150,6 +132,8 @@ class PianoRoll : public MidiEditor { virtual void closeEvent(QCloseEvent*); virtual void keyPressEvent(QKeyEvent*); virtual void resizeEvent(QResizeEvent*); + virtual void focusOutEvent(QFocusEvent*); + void storeInitialState(); private slots: void setSelection(int, Event&, Part*); @@ -159,14 +143,8 @@ class PianoRoll : public MidiEditor { void soloChanged(bool flag); //void trackInfoScroll(int); void setRaster(int); - void setQuant(int); - void configQuant(); - void setQuantStrength(int val) { _quantStrength = val; } - void setQuantLimit(int val) { _quantLimit = val; } - void setQuantLen(bool val) { _quantLen = val; } void cmd(int); void setSteprec(bool); - void setTo(int val) { _to = val; } void eventColorModeChanged(int); void clipboardChanged(); // enable/disable "Paste" void selectionChanged(); // enable/disable "Copy" & "Paste" diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index a0ffdcaf..84cac135 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -32,11 +32,11 @@ #include "mpevent.h" #include "globals.h" #include "cmd.h" -#include "gatetime.h" -#include "velocity.h" #include "song.h" #include "audio.h" +#define CHORD_TIMEOUT 75 + //--------------------------------------------------------- // NEvent //--------------------------------------------------------- @@ -82,8 +82,14 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy) : EventCanvas(pr, parent, sx, sy) { colorMode = 0; - cmdRange = 0; // all Events playedPitch = -1; + + chordTimer = new QTimer(this); + chordTimer->setSingleShot(true); + chordTimer->setInterval(CHORD_TIMEOUT); + chordTimer->stop(); + + connect(chordTimer, SIGNAL(timeout()), SLOT(chordTimerTimedOut())); songChanged(SC_TRACK_INSERTED); connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int))); @@ -726,7 +732,7 @@ void PianoCanvas::pianoCmd(int cmd) song->setPos(0, p, true, false, true); } return; - case CMD_DELETE: + case CMD_BACKSPACE: if (pos[0] < start() || pos[0] >= end()) break; { @@ -771,8 +777,7 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift) audio->msgPlayMidiEvent(&e); if (_steprec && pos[0] >= start_tick && pos[0] < end_tick) { - if (curPart == 0) - return; + if (curPart) { int len = editor->raster(); unsigned tick = pos[0] - curPart->tick(); //CDW if (shift) @@ -791,6 +796,8 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift) song->setPos(0, p, true, false, true); } } + } + } //--------------------------------------------------------- @@ -907,10 +914,8 @@ void PianoCanvas::drawCanvas(QPainter& p, const QRect& rect) // pulldown menu commands //--------------------------------------------------------- -void PianoCanvas::cmd(int cmd, int quantStrength, - int quantLimit, bool quantLen, int range) +void PianoCanvas::cmd(int cmd) { - cmdRange = range; switch (cmd) { case CMD_CUT: copy(); @@ -932,32 +937,6 @@ void PianoCanvas::cmd(int cmd, int quantStrength, case CMD_PASTE: paste(); break; - case CMD_DEL: - if (selectionSize()) { - song->startUndo(); - for (iCItem i = items.begin(); i != items.end(); ++i) { - if (!i->second->isSelected()) - continue; - Event ev = i->second->event(); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(ev, i->second->part(), false); - audio->msgDeleteEvent(ev, i->second->part(), false, false, false); - } - song->endUndo(SC_EVENT_REMOVED); - } - return; - case CMD_OVER_QUANTIZE: // over quantize - quantize(100, 1, quantLen); - break; - case CMD_ON_QUANTIZE: // note on quantize - quantize(50, 1, false); - break; - case CMD_ONOFF_QUANTIZE: // note on/off quantize - quantize(50, 1, true); - break; - case CMD_ITERATIVE_QUANTIZE: // Iterative Quantize - quantize(quantStrength, quantLimit, quantLen); - break; case CMD_SELECT_ALL: // select all for (iCItem k = items.begin(); k != items.end(); ++k) { if (!k->second->isSelected()) @@ -1032,96 +1011,6 @@ void PianoCanvas::cmd(int cmd, int quantStrength, editor->setCurCanvasPart(newpt); } break; - case CMD_MODIFY_GATE_TIME: - { - GateTime w(this); - w.setRange(range); - if (!w.exec()) - break; - int range = w.range(); // all, selected, looped, sel+loop - int rate = w.rateVal(); - int offset = w.offsetVal(); - - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); ++k) { - NEvent* nevent =(NEvent*)(k->second); - Event event = nevent->event(); - if (event.type() != Note) - continue; - unsigned tick = event.tick(); - bool selected = k->second->isSelected(); - bool inLoop = (tick >= song->lpos()) && (tick < song->rpos()); - - if ((range == 0) - || (range == 1 && selected) - || (range == 2 && inLoop) - || (range == 3 && selected && inLoop)) { - unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned - - len = rate ? (len * 100) / rate : 1; - len += offset; - if (len < 1) - len = 1; - - if (event.lenTick() != len) { - Event newEvent = event.clone(); - newEvent.setLenTick(len); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, newEvent, nevent->part(), false); - audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false); - } - } - } - song->endUndo(SC_EVENT_MODIFIED); - } - break; - - case CMD_MODIFY_VELOCITY: - { - Velocity w; - w.setRange(range); - if (!w.exec()) - break; - int range = w.range(); // all, selected, looped, sel+loop - int rate = w.rateVal(); - int offset = w.offsetVal(); - - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); ++k) { - NEvent* nevent = (NEvent*)(k->second); - Event event = nevent->event(); - if (event.type() != Note) - continue; - unsigned tick = event.tick(); - bool selected = k->second->isSelected(); - bool inLoop = (tick >= song->lpos()) && (tick < song->rpos()); - - if ((range == 0) - || (range == 1 && selected) - || (range == 2 && inLoop) - || (range == 3 && selected && inLoop)) { - int velo = event.velo(); - - //velo = rate ? (velo * 100) / rate : 64; - velo = (velo * rate) / 100; - velo += offset; - - if (velo <= 0) - velo = 1; - if (velo > 127) - velo = 127; - if (event.velo() != velo) { - Event newEvent = event.clone(); - newEvent.setVelo(velo); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, newEvent, nevent->part(), false); - audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false); - } - } - } - song->endUndo(SC_EVENT_MODIFIED); - } - break; case CMD_FIXED_LEN: //Set notes to the length specified in the drummap if (!selectionSize()) @@ -1141,76 +1030,6 @@ void PianoCanvas::cmd(int cmd, int quantStrength, song->endUndo(SC_EVENT_MODIFIED); break; - case CMD_DELETE_OVERLAPS: - if (!selectionSize()) - break; - - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); k++) { - if (k->second->isSelected() == false) - continue; - - NEvent* e1 = (NEvent*) (k->second); // first note - NEvent* e2 = NULL; // ptr to next selected note (which will be checked for overlap) - Event ce1 = e1->event(); - Event ce2; - - if (ce1.type() != Note) - continue; - - // Find next selected item on the same pitch - iCItem l = k; l++; - for (; l != items.end(); l++) { - if (l->second->isSelected() == false) - continue; - - e2 = (NEvent*) l->second; - ce2 = e2->event(); - - // Same pitch? - if (ce1.dataA() == ce2.dataA()) - break; - - // If the note has the same len and place we treat it as a duplicate note and not a following note - // The best thing to do would probably be to delete the duplicate note, we just want to avoid - // matching against the same note - if ( ce1.tick() + e1->part()->tick() == ce2.tick() + e2->part()->tick() - && ce1.lenTick() + e1->part()->tick() == ce2.lenTick() + e2->part()->tick()) - { - e2 = NULL; // this wasn't what we were looking for - continue; - } - - } - - if (e2 == NULL) // None found - break; - - Part* part1 = e1->part(); - Part* part2 = e2->part(); - if (ce2.type() != Note) - continue; - - - unsigned event1pos = ce1.tick() + part1->tick(); - unsigned event1end = event1pos + ce1.lenTick(); - unsigned event2pos = ce2.tick() + part2->tick(); - - //printf("event1pos %u event1end %u event2pos %u\n", event1pos, event1end, event2pos); - if (event1end > event2pos) { - Event newEvent = ce1.clone(); - unsigned newlen = ce1.lenTick() - (event1end - event2pos); - //printf("newlen: %u\n", newlen); - newEvent.setLenTick(newlen); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(ce1, newEvent, e1->part(), false); - audio->msgChangeEvent(ce1, newEvent, e1->part(), false, false, false); - } - } - song->endUndo(SC_EVENT_MODIFIED); - break; - - case CMD_CRESCENDO: case CMD_TRANSPOSE: case CMD_THIN_OUT: @@ -1231,55 +1050,6 @@ void PianoCanvas::cmd(int cmd, int quantStrength, } //--------------------------------------------------------- -// quantize -//--------------------------------------------------------- - -void PianoCanvas::quantize(int strength, int limit, bool quantLen) - { - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); ++k) { - NEvent* nevent = (NEvent*)(k->second); - Event event = nevent->event(); - Part* part = nevent->part(); - if (event.type() != Note) - continue; - - if ((cmdRange & CMD_RANGE_SELECTED) && !k->second->isSelected()) - continue; - - unsigned tick = event.tick() + part->tick(); - - if ((cmdRange & CMD_RANGE_LOOP) - && ((tick < song->lpos() || tick >= song->rpos()))) - continue; - - unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned - int tick2 = tick + len; - - // quant start position - int diff = AL::sigmap.raster(tick, editor->quant()) - tick; - if (abs(diff) > limit) - tick += ((diff * strength) / 100); - - // quant len - diff = AL::sigmap.raster(tick2, editor->quant()) - tick2; - if (quantLen && (abs(diff) > limit)) - len += ((diff * strength) / 100); - - // something changed? - if (((event.tick() + part->tick()) != tick) || (event.lenTick() != len)) { - Event newEvent = event.clone(); - newEvent.setTick(tick - part->tick()); - newEvent.setLenTick(len); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, newEvent, part, false); - audio->msgChangeEvent(event, newEvent, part, false, false, false); - } - } - song->endUndo(SC_EVENT_MODIFIED); - } - -//--------------------------------------------------------- // midiNote //--------------------------------------------------------- @@ -1289,11 +1059,15 @@ void PianoCanvas::midiNote(int pitch, int velo) && !audio->isPlaying() && velo && pos[0] >= start_tick && pos[0] < end_tick && !(globalKeyState & Qt::AltModifier)) { - unsigned int len = editor->quant();//prevent compiler warning: comparison singed/unsigned + chordTimer->stop(); + + //len has been changed by flo: set to raster() instead of quant() + //reason: the quant-toolbar has been removed; the flexibility you + //lose with this can be re-gained by applying a "modify note len" + //on the notes you have entered. + unsigned int len = editor->raster();//prevent compiler warning: comparison singed/unsigned unsigned tick = pos[0]; //CDW unsigned starttick = tick; - if (globalKeyState & Qt::ShiftModifier) - tick -= editor->rasterStep(tick); // // extend len of last note? @@ -1310,10 +1084,10 @@ void PianoCanvas::midiNote(int pitch, int velo) // Indicate do undo, and do not do port controller values and clone parts. //audio->msgChangeEvent(ev, e, curPart); audio->msgChangeEvent(ev, e, curPart, true, false, false); - tick += editor->rasterStep(tick); - if (tick != song->cpos()) { - Pos p(tick, true); - song->setPos(0, p, true, false, true); + + if (! (globalKeyState & Qt::ShiftModifier)) { + chordTimer_setToTick = tick + editor->rasterStep(tick); + chordTimer->start(); } return; } @@ -1330,8 +1104,12 @@ void PianoCanvas::midiNote(int pitch, int velo) // Indicate do undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(ev, curPart); audio->msgDeleteEvent(ev, curPart, true, false, false); - if (globalKeyState & Qt::ShiftModifier) - tick += editor->rasterStep(tick); + + if (! (globalKeyState & Qt::ShiftModifier)) { + chordTimer_setToTick = tick + editor->rasterStep(tick); + chordTimer->start(); + } + return; } } @@ -1343,14 +1121,23 @@ void PianoCanvas::midiNote(int pitch, int velo) // Indicate do undo, and do not do port controller values and clone parts. //audio->msgAddEvent(e, curPart); audio->msgAddEvent(e, curPart, true, false, false); - tick += editor->rasterStep(tick); - if (tick != song->cpos()) { - Pos p(tick, true); - song->setPos(0, p, true, false, true); + + if (! (globalKeyState & Qt::ShiftModifier)) { + chordTimer_setToTick = tick + editor->rasterStep(tick); + chordTimer->start(); } } } +void PianoCanvas::chordTimerTimedOut() +{ + if (chordTimer_setToTick != song->cpos()) + { + Pos p(chordTimer_setToTick, true); + song->setPos(0, p, true, false, true); + } +} + /* //--------------------------------------------------------- // getTextDrag diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index bda22fc3..3ca9ab52 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -15,6 +15,7 @@ #include <QMouseEvent> #include <QDragMoveEvent> #include <QDragLeaveEvent> +#include <QTimer> #define KH 13 @@ -37,9 +38,11 @@ class QRect; //--------------------------------------------------------- class PianoCanvas : public EventCanvas { - int cmdRange; int colorMode; int playedPitch; + + QTimer* chordTimer; + unsigned chordTimer_setToTick; Q_OBJECT virtual void viewMouseDoubleClickEvent(QMouseEvent*); @@ -63,7 +66,6 @@ class PianoCanvas : public EventCanvas { int y2pitch(int) const; int pitch2y(int) const; virtual void drawCanvas(QPainter&, const QRect&); - void quantize(int, int, bool); void copy(); void paste(); virtual void itemPressed(const CItem*); @@ -74,6 +76,7 @@ class PianoCanvas : public EventCanvas { private slots: void midiNote(int pitch, int velo); + void chordTimerTimedOut(); signals: void quantChanged(int); @@ -88,19 +91,18 @@ class PianoCanvas : public EventCanvas { public: enum { CMD_CUT, CMD_COPY, CMD_PASTE, CMD_DEL, - CMD_OVER_QUANTIZE, CMD_ON_QUANTIZE, CMD_ONOFF_QUANTIZE, - CMD_ITERATIVE_QUANTIZE, + CMD_QUANTIZE, CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT, CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PREV_PART, CMD_SELECT_NEXT_PART, - CMD_MODIFY_GATE_TIME, CMD_MODIFY_VELOCITY, - CMD_CRESCENDO, CMD_TRANSPOSE, CMD_THIN_OUT, CMD_ERASE_EVENT, + CMD_MODIFY_GATE_TIME, CMD_MODIFY_VELOCITY, CMD_CRESCENDO, + CMD_TRANSPOSE, CMD_THIN_OUT, CMD_ERASE_EVENT, CMD_NOTE_SHIFT, CMD_MOVE_CLOCK, CMD_COPY_MEASURE, CMD_ERASE_MEASURE, CMD_DELETE_MEASURE, CMD_CREATE_MEASURE, - CMD_FIXED_LEN, CMD_DELETE_OVERLAPS + CMD_FIXED_LEN, CMD_DELETE_OVERLAPS, CMD_LEGATO }; PianoCanvas(MidiEditor*, QWidget*, int, int); - void cmd(int, int, int, bool, int); + void cmd(int cmd); void setColorMode(int mode) { colorMode = mode; redraw(); diff --git a/muse2/muse/midiedit/quantconfig.cpp b/muse2/muse/midiedit/quantconfig.cpp deleted file mode 100644 index 2f413e6a..00000000 --- a/muse2/muse/midiedit/quantconfig.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: quantconfig.cpp,v 1.2 2004/04/24 14:58:52 wschweer Exp $ -// -// (C) Copyright 1999/2003 Werner Schweer (ws@seh.de) -//========================================================= - -#include <QCheckBox> -#include <QGroupBox> -#include <QLabel> -#include <QSpinBox> -#include <QVBoxLayout> - -#include "quantconfig.h" - -const char* wtStrengthTxt = QT_TRANSLATE_NOOP("@default", "sets amount of quantization:\n" - "0 - no quantization\n" - "100 - full quantization"); -const char* wtQLimitTxt = QT_TRANSLATE_NOOP("@default", "don't quantize notes above this tick limit"); -const char* wtQLenTxt = QT_TRANSLATE_NOOP("@default", "quantize also note len as default"); - -//--------------------------------------------------------- -// QuantConfig -//--------------------------------------------------------- - -QuantConfig::QuantConfig(int s, int l, bool lenFlag) - : QDialog() - { - setWindowTitle(tr("MusE: Config Quantize")); - QVBoxLayout *mainlayout = new QVBoxLayout; - - QGridLayout* layout = new QGridLayout; - QGroupBox* gb = new QGroupBox(tr("Config Quantize")); - - QLabel* l1 = new QLabel(tr("Strength")); - layout->addWidget(l1, 0, 0); - QSpinBox* sb1 = new QSpinBox; - sb1->setMinimum(0); - sb1->setMaximum(100); - sb1->setSingleStep(1); - sb1->setSuffix(QString("%")); - sb1->setValue(s); - layout->addWidget(sb1, 0, 1); - - QLabel* l2 = new QLabel(tr("Don´t Quantize")); - layout->addWidget(l2, 1, 0); - QSpinBox* sb2 = new QSpinBox; - sb2->setMinimum(0); - sb2->setMaximum(500); - sb2->setSingleStep(1); - sb2->setValue(l); - layout->addWidget(sb2, 1, 1); - - QLabel* l3 = new QLabel(tr("Quant Len")); - layout->addWidget(l3, 2, 0); - QCheckBox* but = new QCheckBox; - but->setChecked(lenFlag); - layout->addWidget(but, 2, 1); - - connect(sb1, SIGNAL(valueChanged(int)), SIGNAL(setQuantStrength(int))); - connect(sb2, SIGNAL(valueChanged(int)), SIGNAL(setQuantLimit(int))); - connect(but, SIGNAL(toggled(bool)), SIGNAL(setQuantLen(bool))); - - gb->setLayout(layout); - mainlayout->addWidget(gb); - setLayout(mainlayout); - - l1->setWhatsThis(tr(wtStrengthTxt)); - l1->setToolTip(tr(wtStrengthTxt)); - sb1->setWhatsThis(tr(wtStrengthTxt)); - l2->setWhatsThis(tr(wtQLimitTxt)); - l2->setToolTip(tr(wtQLimitTxt)); - sb2->setWhatsThis(tr(wtQLimitTxt)); - l3->setWhatsThis(tr(wtQLenTxt)); - l3->setToolTip(tr(wtQLenTxt)); - but->setWhatsThis(tr(wtQLenTxt)); - } - diff --git a/muse2/muse/midiedit/quantconfig.h b/muse2/muse/midiedit/quantconfig.h deleted file mode 100644 index 4466cdf0..00000000 --- a/muse2/muse/midiedit/quantconfig.h +++ /dev/null @@ -1,32 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: quantconfig.h,v 1.1.1.1 2003/10/27 18:52:23 wschweer Exp $ -// -// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de) -//========================================================= - -#ifndef __QCONFIG_H__ -#define __QCONFIG_H__ - -#include <QDialog> - -//--------------------------------------------------------- -// QuantConfig -//--------------------------------------------------------- - -class QuantConfig : public QDialog { - Q_OBJECT - - signals: - void setQuantStrength(int); - void setQuantLimit(int); - void setQuantLen(bool); - - public: - QuantConfig(int, int, bool); - }; - - -#endif - diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 31f0f325..f8815185 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -41,27 +41,23 @@ using namespace std; #include "app.h" #include "xml.h" #include "mtscale.h" -#include "prcanvas.h" +#include "al/sig.h" #include "scoreedit.h" -#include "scrollscale.h" -#include "piano.h" -#include "../ctrl/ctrledit.h" -#include "splitter.h" +#include "tools.h" #include "ttoolbar.h" #include "tb1.h" -#include "utils.h" #include "globals.h" #include "gconfig.h" #include "icons.h" #include "audio.h" +#include "functions.h" #include "cmd.h" -#include "quantconfig.h" -#include "shortcuts.h" - -#include "mtrackinfo.h" - #include "sig.h" +#include "song.h" + +//#include "../ctrl/ctrledit.h" +//#include "shortcuts.h" string IntToStr(int i); @@ -72,7 +68,8 @@ QString IntToQStr(int i); - +#define APPLY_TO_SELECTED_STRING tr("Apply to selected notes:") +#define APPLY_TO_NEW_STRING tr("Apply to new notes:") //PIXELS_PER_NOTEPOS must be greater or equal to 3*NOTE_XLEN + 2*NOTE_SHIFT @@ -109,6 +106,10 @@ QString IntToQStr(int i); #define STAFF_DISTANCE (10*YLEN) #define GRANDSTAFF_DISTANCE (8*YLEN) +#define NOTE_YDIST 20 +//NOTE_YDIST is the number of pixels which are between two notes +//which exceed their staves' y-boundaries, so that these boundaries +//must be expanded. QString create_random_string(int len=8) { @@ -141,6 +142,7 @@ QColor* mycolors; // array [NUM_MYCOLORS] set<QString> ScoreEdit::names; int ScoreEdit::width_init = 600; int ScoreEdit::height_init = 400; +QByteArray ScoreEdit::default_toolbar_state; //--------------------------------------------------------- @@ -151,6 +153,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) : TopWin(parent, name) { setAttribute(Qt::WA_DeleteOnClose); + setFocusPolicy(Qt::StrongFocus); resize(width_init, height_init); @@ -164,12 +167,13 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) setCentralWidget(mainw); - + apply_velo=false; - score_canvas=new ScoreCanvas(this, mainw, 1, 1); + score_canvas=new ScoreCanvas(this, mainw); xscroll = new QScrollBar(Qt::Horizontal, mainw); yscroll = new QScrollBar(Qt::Vertical, mainw); + time_bar = new MTScaleFlo(score_canvas, mainw); connect(xscroll, SIGNAL(valueChanged(int)), score_canvas, SLOT(x_scroll_event(int))); connect(score_canvas, SIGNAL(xscroll_changed(int)), xscroll, SLOT(setValue(int))); @@ -184,9 +188,14 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) connect(song, SIGNAL(songChanged(int)), score_canvas, SLOT(song_changed(int))); - mainGrid->addWidget(score_canvas, 0, 0); - mainGrid->addWidget(xscroll,1,0); - mainGrid->addWidget(yscroll,0,1); + connect(xscroll, SIGNAL(valueChanged(int)), time_bar, SLOT(set_xpos(int))); + connect(score_canvas, SIGNAL(pos_add_changed()), time_bar, SLOT(pos_add_changed())); + connect(score_canvas, SIGNAL(preamble_width_changed(int)), time_bar, SLOT(set_xoffset(int))); + + mainGrid->addWidget(time_bar, 0,0); + mainGrid->addWidget(score_canvas, 1,0); + mainGrid->addWidget(xscroll,2,0); + mainGrid->addWidget(yscroll,1,1); xscroll->setMinimum(0); yscroll->setMinimum(0); @@ -216,17 +225,20 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) transport_toolbar->setObjectName("transport"); transport_toolbar->addActions(transportAction->actions()); - QToolBar* newnote_toolbar = addToolBar(tr("New note settings")); - newnote_toolbar->setObjectName("New note settings"); - newnote_toolbar->addWidget(new QLabel(tr("Note length:"), newnote_toolbar)); + addToolBarBreak(); + + QToolBar* note_settings_toolbar = addToolBar(tr("Note settings")); + //don't change that name, or you will lose toolbar settings + note_settings_toolbar->setObjectName("New note settings"); + note_settings_toolbar->addWidget(new QLabel(tr("Note length:"), note_settings_toolbar)); len_actions=new QActionGroup(this); - n1_action = newnote_toolbar->addAction("1", menu_mapper, SLOT(map())); - n2_action = newnote_toolbar->addAction("2", menu_mapper, SLOT(map())); - n4_action = newnote_toolbar->addAction("4", menu_mapper, SLOT(map())); - n8_action = newnote_toolbar->addAction("8", menu_mapper, SLOT(map())); - n16_action = newnote_toolbar->addAction("16", menu_mapper, SLOT(map())); - n32_action = newnote_toolbar->addAction("32", menu_mapper, SLOT(map())); - nlast_action = newnote_toolbar->addAction(tr("last"), menu_mapper, SLOT(map())); + n1_action = note_settings_toolbar->addAction("1", menu_mapper, SLOT(map())); + n2_action = note_settings_toolbar->addAction("2", menu_mapper, SLOT(map())); + n4_action = note_settings_toolbar->addAction("4", menu_mapper, SLOT(map())); + n8_action = note_settings_toolbar->addAction("8", menu_mapper, SLOT(map())); + n16_action = note_settings_toolbar->addAction("16", menu_mapper, SLOT(map())); + n32_action = note_settings_toolbar->addAction("32", menu_mapper, SLOT(map())); + nlast_action = note_settings_toolbar->addAction(tr("last"), menu_mapper, SLOT(map())); menu_mapper->setMapping(n1_action, CMD_NOTELEN_1); menu_mapper->setMapping(n2_action, CMD_NOTELEN_2); menu_mapper->setMapping(n4_action, CMD_NOTELEN_4); @@ -252,22 +264,37 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) nlast_action->setChecked(true); menu_command(CMD_NOTELEN_LAST); - newnote_toolbar->addSeparator(); + note_settings_toolbar->addSeparator(); - newnote_toolbar->addWidget(new QLabel(tr("Velocity:"), newnote_toolbar)); + apply_velo_to_label = new QLabel(APPLY_TO_NEW_STRING, note_settings_toolbar); + int w1 = apply_velo_to_label->fontMetrics().width(APPLY_TO_NEW_STRING); + int w2 = apply_velo_to_label->fontMetrics().width(APPLY_TO_SELECTED_STRING); + if (w1>w2) + apply_velo_to_label->setFixedWidth(w1+5); + else + apply_velo_to_label->setFixedWidth(w2+5); + + note_settings_toolbar->addWidget(apply_velo_to_label); + note_settings_toolbar->addWidget(new QLabel(tr("Velocity:"), note_settings_toolbar)); velo_spinbox = new QSpinBox(this); velo_spinbox->setRange(0, 127); velo_spinbox->setSingleStep(1); - connect(velo_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_newnote_velo(int))); - newnote_toolbar->addWidget(velo_spinbox); + //we do not use the valueChanged signal, because that would generate + //many many undos when using the spin buttons. + connect(velo_spinbox, SIGNAL(editingFinished()), SLOT(velo_box_changed())); + connect(this,SIGNAL(velo_changed(int)), score_canvas, SLOT(set_velo(int))); + note_settings_toolbar->addWidget(velo_spinbox); velo_spinbox->setValue(64); - newnote_toolbar->addWidget(new QLabel(tr("Off-Velocity:"), newnote_toolbar)); + note_settings_toolbar->addWidget(new QLabel(tr("Off-Velocity:"), note_settings_toolbar)); velo_off_spinbox = new QSpinBox(this); velo_off_spinbox->setRange(0, 127); velo_off_spinbox->setSingleStep(1); - connect(velo_off_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_newnote_velo_off(int))); - newnote_toolbar->addWidget(velo_off_spinbox); + //we do not use the valueChanged signal, because that would generate + //many many undos when using the spin buttons. + connect(velo_off_spinbox, SIGNAL(editingFinished()), SLOT(velo_off_box_changed())); + connect(this,SIGNAL(velo_off_changed(int)), score_canvas, SLOT(set_velo_off(int))); + note_settings_toolbar->addWidget(velo_off_spinbox); velo_off_spinbox->setValue(64); @@ -331,21 +358,48 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) QAction* set_name_action = settings_menu->addAction(tr("Set Score &name"), menu_mapper, SLOT(map())); menu_mapper->setMapping(set_name_action, CMD_SET_NAME); - - - - - score_canvas->song_changed(SC_EVENT_INSERTED); + QMenu* functions_menu = menuBar()->addMenu(tr("&Functions")); + + QAction* func_quantize_action = functions_menu->addAction(tr("&Quantize"), menu_mapper, SLOT(map())); + QAction* func_notelen_action = functions_menu->addAction(tr("Change note &length"), menu_mapper, SLOT(map())); + QAction* func_velocity_action = functions_menu->addAction(tr("Change note &velocity"), menu_mapper, SLOT(map())); + QAction* func_cresc_action = functions_menu->addAction(tr("Crescendo/Decrescendo"), menu_mapper, SLOT(map())); + QAction* func_transpose_action = functions_menu->addAction(tr("Transpose"), menu_mapper, SLOT(map())); + QAction* func_erase_action = functions_menu->addAction(tr("Erase Events"), menu_mapper, SLOT(map())); + QAction* func_move_action = functions_menu->addAction(tr("Move Notes"), menu_mapper, SLOT(map())); + QAction* func_fixed_len_action = functions_menu->addAction(tr("Set Fixed Length"), menu_mapper, SLOT(map())); + QAction* func_del_overlaps_action = functions_menu->addAction(tr("Delete Overlaps"), menu_mapper, SLOT(map())); + QAction* func_legato_action = functions_menu->addAction(tr("Legato"), menu_mapper, SLOT(map())); + menu_mapper->setMapping(func_quantize_action, CMD_QUANTIZE); + menu_mapper->setMapping(func_notelen_action, CMD_NOTELEN); + menu_mapper->setMapping(func_velocity_action, CMD_VELOCITY); + menu_mapper->setMapping(func_cresc_action, CMD_CRESCENDO); + menu_mapper->setMapping(func_transpose_action, CMD_TRANSPOSE); + menu_mapper->setMapping(func_erase_action, CMD_ERASE); + menu_mapper->setMapping(func_move_action, CMD_MOVE); + menu_mapper->setMapping(func_fixed_len_action, CMD_FIXED_LEN); + menu_mapper->setMapping(func_del_overlaps_action, CMD_DELETE_OVERLAPS); + menu_mapper->setMapping(func_legato_action, CMD_LEGATO); + + + if (!default_toolbar_state.isEmpty()) + restoreState(default_toolbar_state); + + connect(song, SIGNAL(songChanged(int)), SLOT(song_changed(int))); + + score_canvas->fully_recalculate(); score_canvas->goto_tick(initPos,true); if (name!=NULL) set_name(name, false, true); else init_name(); -} + apply_velo=true; +} + void ScoreEdit::add_parts(PartList* pl, bool all_in_one) { score_canvas->add_staves(pl, all_in_one); @@ -403,6 +457,46 @@ ScoreEdit::~ScoreEdit() } +void ScoreEdit::velo_box_changed() +{ + emit velo_changed(velo_spinbox->value()); +} + +void ScoreEdit::velo_off_box_changed() +{ + emit velo_off_changed(velo_off_spinbox->value()); +} + +void ScoreEdit::song_changed(int flags) +{ + if (flags & (SC_SELECTION | SC_EVENT_MODIFIED | SC_EVENT_REMOVED)) + { + map<Event*, Part*> selection=get_events(score_canvas->get_all_parts(),1); + if (selection.empty()) + { + apply_velo_to_label->setText(APPLY_TO_NEW_STRING); + } + else + { + apply_velo_to_label->setText(APPLY_TO_SELECTED_STRING); + + int velo=-1; + int velo_off=-1; + for (map<Event*, Part*>::iterator it=selection.begin(); it!=selection.end(); it++) + if (it->first->type()==Note) + { + if (velo==-1) velo=it->first->velo(); + else if ((velo>=0) && (velo!=it->first->velo())) velo=-2; + + if (velo_off==-1) velo_off=it->first->veloOff(); + else if ((velo_off>=0) && (velo_off!=it->first->veloOff())) velo_off=-2; + } + + if (velo>=0) velo_spinbox->setValue(velo); + if (velo_off>=0) velo_off_spinbox->setValue(velo_off); + } + } +} void ScoreEdit::canvas_width_changed(int width) { @@ -452,8 +546,21 @@ void ScoreEdit::resizeEvent(QResizeEvent* ev) { QWidget::resizeEvent(ev); - width_init=ev->size().width(); - height_init=ev->size().height(); + store_initial_state(); +} + +void ScoreEdit::focusOutEvent(QFocusEvent* ev) +{ + QMainWindow::focusOutEvent(ev); + + store_initial_state(); +} + +void ScoreEdit::store_initial_state() +{ + width_init=width(); + height_init=height(); + default_toolbar_state=saveState(); } void ScoreEdit::menu_command(int cmd) @@ -474,16 +581,26 @@ void ScoreEdit::menu_command(int cmd) } break; + case CMD_QUANTIZE: quantize_notes(score_canvas->get_all_parts()); break; + case CMD_VELOCITY: modify_velocity(score_canvas->get_all_parts()); break; + case CMD_CRESCENDO: crescendo(score_canvas->get_all_parts()); break; + case CMD_NOTELEN: modify_notelen(score_canvas->get_all_parts()); break; + case CMD_TRANSPOSE: transpose_notes(score_canvas->get_all_parts()); break; + case CMD_ERASE: erase_notes(score_canvas->get_all_parts()); break; + case CMD_MOVE: move_notes(score_canvas->get_all_parts()); break; + case CMD_FIXED_LEN: set_notelen(score_canvas->get_all_parts()); break; + case CMD_DELETE_OVERLAPS: delete_overlaps(score_canvas->get_all_parts()); break; + case CMD_LEGATO: legato(score_canvas->get_all_parts()); break; + default: score_canvas->menu_command(cmd); } } -//--------------------------------------------------------- -// readPart -//--------------------------------------------------------- -Part* readPart(Xml& xml, QString tag_name="part") //TODO FINDMICH: duplicated from songfile.cpp; only difference: "none" is supported +//duplicated from songfile.cpp's MusE::readPart(); the only differences: +//"none" is supported and tag_name is settable +Part* read_part(Xml& xml, QString tag_name="part") { Part* part = 0; @@ -514,7 +631,7 @@ Part* readPart(Xml& xml, QString tag_name="part") //TODO FINDMICH: duplicated fr break; case Xml::TagStart: - xml.unknown("readPart"); + xml.unknown("read_part"); break; case Xml::TagEnd: @@ -546,7 +663,7 @@ void staff_t::read_status(Xml& xml) clef = clef_t(xml.parseInt()); else if (tag == "part") { - Part* part=readPart(xml); + Part* part=read_part(xml); if (part) parts.insert(part); else @@ -672,6 +789,9 @@ void ScoreCanvas::write_staves(int level, Xml& xml) const void ScoreEdit::readStatus(Xml& xml) { + bool apply_velo_temp=apply_velo; + apply_velo=false; + for (;;) { Xml::Token token = xml.parse(); @@ -741,7 +861,7 @@ void ScoreEdit::readStatus(Xml& xml) else if (tag == "topwin") TopWin::readStatus(xml); else if (tag == "selectedPart") - score_canvas->set_selected_part(readPart(xml, "selectedPart")); + score_canvas->set_selected_part(read_part(xml, "selectedPart")); else if (tag == "staff") { staff_t staff(score_canvas); @@ -760,6 +880,7 @@ void ScoreEdit::readStatus(Xml& xml) break; } } + apply_velo=apply_velo_temp; } void ScoreEdit::read_configuration(Xml& xml) @@ -774,10 +895,12 @@ void ScoreEdit::read_configuration(Xml& xml) switch (token) { case Xml::TagStart: - if (tag == "width") + if (tag == "height") height_init = xml.parseInt(); - else if (tag == "height") + else if (tag == "width") width_init = xml.parseInt(); + else if (tag == "toolbars") + default_toolbar_state = QByteArray::fromHex(xml.parse1().toAscii()); else xml.unknown("ScoreEdit"); break; @@ -798,6 +921,7 @@ void ScoreEdit::write_configuration(int level, Xml& xml) xml.tag(level++, "scoreedit"); xml.intTag(level, "width", width_init); xml.intTag(level, "height", height_init); + xml.strTag(level, "toolbars", default_toolbar_state.toHex().data()); xml.etag(level, "scoreedit"); } @@ -806,60 +930,103 @@ void ScoreEdit::write_configuration(int level, Xml& xml) void ScoreCanvas::add_staves(PartList* pl, bool all_in_one) { - staff_t staff(this); - - if (all_in_one) + if (!pl->empty()) { - staff.parts.clear(); - for (ciPart part_it=pl->begin(); part_it!=pl->end(); part_it++) - staff.parts.insert(part_it->second); - staff.cleanup_parts(); + staff_t staff(this); - staff.type=GRAND_TOP; //FINDME_INITCLEF - staff.clef=VIOLIN; - staves.push_back(staff); + if (all_in_one) + { + ScoreEdit::clefTypes clef=((MidiTrack*)pl->begin()->second->track())->getClef(); + + staff.parts.clear(); + for (ciPart part_it=pl->begin(); part_it!=pl->end(); part_it++) + { + if (((MidiTrack*)part_it->second->track())->getClef() != clef) + clef=ScoreEdit::grandStaff; + + staff.parts.insert(part_it->second); + } + staff.cleanup_parts(); - staff.type=GRAND_BOTTOM; - staff.clef=BASS; - staves.push_back(staff); - } - else - { - set<Track*> tracks; - for (ciPart it=pl->begin(); it!=pl->end(); it++) - tracks.insert(it->second->track()); - - TrackList* tracklist = song->tracks(); - // this loop is used for inserting track-staves in the - // correct order. simply iterating through tracks's contents - // would sort after the pointer values, i.e. randomly - for (ciTrack track_it=tracklist->begin(); track_it!=tracklist->end(); track_it++) - if (tracks.find(*track_it)!=tracks.end()) + switch (clef) { - staff.parts.clear(); - for (ciPart part_it=pl->begin(); part_it!=pl->end(); part_it++) - if (part_it->second->track() == *track_it) - staff.parts.insert(part_it->second); - staff.cleanup_parts(); - - staff.type=GRAND_TOP; //FINDME_INITCLEF - staff.clef=VIOLIN; - staves.push_back(staff); - - staff.type=GRAND_BOTTOM; - staff.clef=BASS; - staves.push_back(staff); + case ScoreEdit::trebleClef: + staff.type=NORMAL; + staff.clef=VIOLIN; + staves.push_back(staff); + break; + + case ScoreEdit::bassClef: + staff.type=NORMAL; + staff.clef=BASS; + staves.push_back(staff); + break; + + case ScoreEdit::grandStaff: + staff.type=GRAND_TOP; + staff.clef=VIOLIN; + staves.push_back(staff); + + staff.type=GRAND_BOTTOM; + staff.clef=BASS; + staves.push_back(staff); + break; } + } + else + { + set<Track*> tracks; + for (ciPart it=pl->begin(); it!=pl->end(); it++) + tracks.insert(it->second->track()); + + TrackList* tracklist = song->tracks(); + // this loop is used for inserting track-staves in the + // correct order. simply iterating through tracks's contents + // would sort after the pointer values, i.e. randomly + for (ciTrack track_it=tracklist->begin(); track_it!=tracklist->end(); track_it++) + if (tracks.find(*track_it)!=tracks.end()) + { + staff.parts.clear(); + for (ciPart part_it=pl->begin(); part_it!=pl->end(); part_it++) + if (part_it->second->track() == *track_it) + staff.parts.insert(part_it->second); + staff.cleanup_parts(); + + switch (((MidiTrack*)(*track_it))->getClef()) + { + case ScoreEdit::trebleClef: + staff.type=NORMAL; + staff.clef=VIOLIN; + staves.push_back(staff); + break; + + case ScoreEdit::bassClef: + staff.type=NORMAL; + staff.clef=BASS; + staves.push_back(staff); + break; + + case ScoreEdit::grandStaff: + staff.type=GRAND_TOP; + staff.clef=VIOLIN; + staves.push_back(staff); + + staff.type=GRAND_BOTTOM; + staff.clef=BASS; + staves.push_back(staff); + break; + } + } + } + + cleanup_staves(); + fully_recalculate(); + recalc_staff_pos(); } - - cleanup_staves(); - recalc_staff_pos(); - song_changed(SC_EVENT_INSERTED); } -ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget, - int sx, int sy) : View(parent_widget, sx, sy) +ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_widget, 1, 1) { parent = pr; setFocusPolicy(Qt::StrongFocus); @@ -872,10 +1039,15 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget, x_pos=0; x_left=0; y_pos=0; + have_lasso=false; dragging=false; + drag_cursor_changed=false; mouse_erases_notes=false; mouse_inserts_notes=true; - + + undo_started=false; + undo_flags=0; + selected_part=NULL; last_len=384; @@ -886,8 +1058,8 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget, //called again. but for safety... set_pixels_per_whole(300); //same as above. but safety rocks - set_newnote_velo(64); - set_newnote_velo_off(64); + set_velo(64); + set_velo_off(64); dragging_staff=false; @@ -986,8 +1158,8 @@ void ScoreCanvas::set_staffmode(list<staff_t>::iterator it, staff_mode_t mode) cerr << "ERROR: ILLEGAL FUNCTION CALL: invalid mode in set_staffmode" << endl; } + fully_recalculate(); recalc_staff_pos(); - song_changed(SC_EVENT_INSERTED); } void ScoreCanvas::remove_staff(list<staff_t>::iterator it) @@ -1012,8 +1184,8 @@ void ScoreCanvas::remove_staff(list<staff_t>::iterator it) } maybe_close_if_empty(); + fully_recalculate(); recalc_staff_pos(); - song_changed(SC_EVENT_INSERTED); } void ScoreCanvas::merge_staves(list<staff_t>::iterator dest, list<staff_t>::iterator src) @@ -1048,8 +1220,8 @@ void ScoreCanvas::merge_staves(list<staff_t>::iterator dest, list<staff_t>::iter remove_staff(src); + fully_recalculate(); recalc_staff_pos(); - song_changed(SC_EVENT_INSERTED); } void ScoreCanvas::move_staff_above(list<staff_t>::iterator dest, list<staff_t>::iterator src) @@ -1079,8 +1251,8 @@ void ScoreCanvas::move_staff_above(list<staff_t>::iterator dest, list<staff_t>:: staves.splice(dest, staves, src, src_end); + fully_recalculate(); recalc_staff_pos(); - song_changed(SC_EVENT_INSERTED); } void ScoreCanvas::move_staff_below(list<staff_t>::iterator dest, list<staff_t>::iterator src) @@ -1097,6 +1269,20 @@ void ScoreCanvas::move_staff_below(list<staff_t>::iterator dest, list<staff_t>:: move_staff_above(dest, src); } +set<Part*> ScoreCanvas::get_all_parts() +{ + set<Part*> result; + + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + result.insert(it->parts.begin(), it->parts.end()); + + return result; +} + +void ScoreCanvas::fully_recalculate() +{ + song_changed(SC_EVENT_MODIFIED); +} void ScoreCanvas::song_changed(int flags) { @@ -1108,6 +1294,8 @@ void ScoreCanvas::song_changed(int flags) for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) it->recalculate(); + + recalc_staff_pos(); redraw(); emit canvas_width_changed(canvas_width()); @@ -1124,11 +1312,17 @@ void ScoreCanvas::song_changed(int flags) } cleanup_staves(); - recalc_staff_pos(); for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) it->recalculate(); + recalc_staff_pos(); + + redraw(); + } + + if (flags & SC_SELECTION) + { redraw(); } } @@ -1209,6 +1403,7 @@ void ScoreCanvas::init_pixmaps() mycolors[i]=config.partColors[i]; mycolors[BLACK_PIXMAP]=Qt::black; mycolors[HIGHLIGHTED_PIXMAP]=Qt::red; + mycolors[SELECTED_PIXMAP]=QColor(255,160,0); for (int i=0; i<64; i++) mycolors[i+VELO_PIXMAP_BEGIN]=QColor(i*4,0,0xff); @@ -1301,15 +1496,15 @@ bool operator< (const note_pos_t& a, const note_pos_t& b) } - + int flo_quantize(int tick, int quant_ticks) { - return int(nearbyint((float)tick / quant_ticks))*quant_ticks; + return AL::sigmap.raster(tick, quant_ticks); } int flo_quantize_floor(int tick, int quant_ticks) { - return int(tick / quant_ticks) * quant_ticks; + return AL::sigmap.raster1(tick, quant_ticks); } @@ -2419,6 +2614,9 @@ void staff_t::calc_item_pos() //key signature is properly drawn. int pos_add=0; + max_y_coord=0; + min_y_coord=0; + for (ScoreItemList::iterator it2=itemlist.begin(); it2!=itemlist.end(); it2++) { for (set<FloItem, floComp>::iterator it=it2->second.begin(); it!=it2->second.end();it++) @@ -2429,6 +2627,9 @@ void staff_t::calc_item_pos() if (it->type==FloItem::NOTE) { + if (it->y > max_y_coord) max_y_coord=it->y; + if (it->y < min_y_coord) min_y_coord=it->y; + it->x+=parent->note_x_indent() + it->shift*NOTE_SHIFT; switch (it->len) @@ -2502,6 +2703,9 @@ void staff_t::calc_item_pos() } } } + + max_y_coord+= (pix_quarter->height()/2 +NOTE_YDIST/2); + min_y_coord-= (pix_quarter->height()/2 +NOTE_YDIST/2); } void ScoreCanvas::calc_pos_add_list() @@ -2531,6 +2735,8 @@ void ScoreCanvas::calc_pos_add_list() curr_key=new_key; } + + emit pos_add_changed(); } void ScoreCanvas::draw_items(QPainter& p, int y, staff_t& staff, int x1, int x2) @@ -2684,9 +2890,14 @@ void ScoreCanvas::draw_items(QPainter& p, int y_offset, staff_t& staff, ScoreIte color_index=VELO_PIXMAP_BEGIN + it->source_event->velo(); break; } + + if (it->source_event->selected()) + color_index=SELECTED_PIXMAP; + if (audio->isPlaying() && it->is_active) color_index=HIGHLIGHTED_PIXMAP; + draw_pixmap(p,it->x -x_pos+x_left,y_offset + it->y,it->pix[color_index]); //draw dots @@ -2947,7 +3158,10 @@ void ScoreCanvas::draw_preamble(QPainter& p, int y_offset, clef_t clef) if (x_left_old!=x_left) + { emit viewport_width_changed(viewport_width()); + emit preamble_width_changed(x_left); + } } @@ -3007,7 +3221,14 @@ void ScoreCanvas::draw(QPainter& p, const QRect&) draw_items(p,it->y_draw - y_pos, *it); p.setClipping(false); } - + + if (have_lasso) + { + p.setPen(Qt::blue); + p.setBrush(Qt::NoBrush); + p.drawRect(lasso); + } + if (debugMsg) cout << "drawing done." << endl; } @@ -3058,6 +3279,11 @@ int ScoreCanvas::tick_to_x(int t) return x; } +int ScoreCanvas::delta_tick_to_delta_x(int t) +{ + return t*pixels_per_whole()/TICKS_PER_WHOLE; +} + int ScoreCanvas::calc_posadd(int t) { int result=0; @@ -3149,6 +3375,10 @@ int ScoreCanvas::y_to_pitch(int y, int t, clef_t clef) void ScoreCanvas::mousePressEvent (QMouseEvent* event) { + keystate=((QInputEvent*)event)->modifiers(); + + bool ctrl=keystate & Qt::ControlModifier; + // den errechneten tick immer ABrunden! // denn der "bereich" eines schlags geht von schlag_begin bis nächsterschlag_begin-1 // noten werden aber genau in die mitte dieses bereiches gezeichnet @@ -3158,6 +3388,10 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) int y=event->y() + y_pos - staff_it->y_draw; int x=event->x()+x_pos-x_left; int tick=flo_quantize_floor(x_to_tick(x), quant_ticks()); + + if (event->button()==Qt::LeftButton) + if (!ctrl) + deselect_all(); if (staff_it!=staves.end()) { @@ -3258,85 +3492,105 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) } else if (event->button()==Qt::LeftButton) //edit? { + set_it->source_event->setSelected(!set_it->source_event->selected()); + song_changed(SC_SELECTION); + setMouseTracking(true); dragging=true; - setCursor(Qt::SizeAllCursor); - song->startUndo(); + drag_cursor_changed=false; + undo_started=false; + undo_flags=SC_EVENT_MODIFIED; } } else //we found nothing? - { - if ((event->button()==Qt::LeftButton) && (mouse_inserts_notes)) + if (event->button()==Qt::LeftButton) { - Part* curr_part = NULL; - set<Part*> possible_dests=staff_it->parts_at_tick(tick); - - if (!possible_dests.empty()) + if (mouse_inserts_notes) { - if (possible_dests.size()==1) - curr_part=*possible_dests.begin(); - else + Part* curr_part = NULL; + set<Part*> possible_dests=staff_it->parts_at_tick(tick); + + if (!possible_dests.empty()) { - if (possible_dests.find(selected_part)!=possible_dests.end()) - curr_part=selected_part; + if (possible_dests.size()==1) + curr_part=*possible_dests.begin(); else - QMessageBox::information(this, tr("Ambiguous part"), tr("There are two or more possible parts you could add the note to, but none matches the selected part. Please select the destination part by clicking on any note belonging to it and try again, or add a new stave containing only the destination part.")); - } - } - else - QMessageBox::information(this, tr("No part"), tr("There are no parts you could add the note to.")); - - if (curr_part!=NULL) - { - signed int relative_tick=(signed) tick - curr_part->tick(); - if (relative_tick<0) - cerr << "ERROR: THIS SHOULD NEVER HAPPEN: relative_tick is negative!" << endl; - song->startUndo(); - //stopping undo at the end of this function is unneccessary - //because we'll begin a drag right after it. finishing - //this drag will stop undo as well (in mouseReleaseEvent) - - Event newevent(Note); - newevent.setPitch(y_to_pitch(y,tick, staff_it->clef)); - newevent.setVelo(newnote_velo); - newevent.setVeloOff(newnote_velo_off); - newevent.setTick(relative_tick); - newevent.setLenTick((new_len>0)?new_len:last_len); - - if (flo_quantize(newevent.lenTick(), quant_ticks()) <= 0) - { - newevent.setLenTick(quant_ticks()); - if (debugMsg) cout << "inserted note's length would be invisible after quantisation (too short)." << endl << - " setting it to " << newevent.lenTick() << endl; + { + if (possible_dests.find(selected_part)!=possible_dests.end()) + curr_part=selected_part; + else + QMessageBox::information(this, tr("Ambiguous part"), tr("There are two or more possible parts you could add the note to, but none matches the selected part. Please select the destination part by clicking on any note belonging to it and try again, or add a new stave containing only the destination part.")); + } } + else + QMessageBox::information(this, tr("No part"), tr("There are no parts you could add the note to.")); - if (newevent.endTick() > curr_part->lenTick()) + if (curr_part!=NULL) { - if (debugMsg) cout << "clipping inserted note from len="<<newevent.endTick()<<" to len="<<(curr_part->lenTick() - newevent.tick())<<endl; - newevent.setLenTick(curr_part->lenTick() - newevent.tick()); - } - - audio->msgAddEvent(newevent, curr_part, false, false, false); - - dragged_event_part=curr_part; - dragged_event=newevent; - dragged_event_original_pitch=newevent.pitch(); + signed int relative_tick=(signed) tick - curr_part->tick(); + if (relative_tick<0) + cerr << "ERROR: THIS SHOULD NEVER HAPPEN: relative_tick is negative!" << endl; + song->startUndo(); + undo_started=true; + undo_flags=SC_EVENT_INSERTED | SC_EVENT_MODIFIED; + //stopping undo at the end of this function is unneccessary + //because we'll begin a drag right after it. finishing + //this drag will stop undo as well (in mouseReleaseEvent) + + Event newevent(Note); + newevent.setPitch(y_to_pitch(y,tick, staff_it->clef)); + newevent.setVelo(note_velo); + newevent.setVeloOff(note_velo_off); + newevent.setTick(relative_tick); + newevent.setLenTick((new_len>0)?new_len:last_len); + newevent.setSelected(true); + + if (flo_quantize(newevent.lenTick(), quant_ticks()) <= 0) + { + newevent.setLenTick(quant_ticks()); + if (debugMsg) cout << "inserted note's length would be invisible after quantisation (too short)." << endl << + " setting it to " << newevent.lenTick() << endl; + } + + if (newevent.endTick() > curr_part->lenTick()) + { + if (debugMsg) cout << "clipping inserted note from len="<<newevent.endTick()<<" to len="<<(curr_part->lenTick() - newevent.tick())<<endl; + newevent.setLenTick(curr_part->lenTick() - newevent.tick()); + } + + audio->msgAddEvent(newevent, curr_part, false, false, false); + + dragged_event_part=curr_part; + dragged_event=newevent; + dragged_event_original_pitch=newevent.pitch(); - mouse_down_pos=event->pos(); - mouse_operation=NO_OP; - mouse_x_drag_operation=LENGTH; + mouse_down_pos=event->pos(); + mouse_operation=NO_OP; + mouse_x_drag_operation=LENGTH; - song_changed(SC_EVENT_INSERTED); + fully_recalculate(); - setMouseTracking(true); - dragging=true; - setCursor(Qt::SizeAllCursor); - //song->startUndo(); unneccessary because we have started it already above + setMouseTracking(true); + dragging=true; + drag_cursor_changed=true; + setCursor(Qt::SizeAllCursor); + //song->startUndo(); unneccessary because we have started it already above + } } - } - } + else // !mouse_inserts_notes. open a lasso + { + have_lasso=true; + lasso_start=event->pos(); + lasso=QRect(lasso_start, lasso_start); + + setMouseTracking(true); + } + } } } + + if (event->button()==Qt::LeftButton) + song->update(SC_SELECTION); } void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) @@ -3356,10 +3610,13 @@ void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) } } - song->endUndo(SC_EVENT_MODIFIED); + if (undo_started) + song->endUndo(undo_flags); + setMouseTracking(false); unsetCursor(); dragging=false; + drag_cursor_changed=false; x_scroll_speed=0; x_scroll_pos=0; } @@ -3386,6 +3643,19 @@ void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) y_scroll_speed=0; y_scroll_pos=0; } + + if (have_lasso && event->button()==Qt::LeftButton) + { + set<Event*> already_processed; + + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + it->apply_lasso(lasso.translated(x_pos-x_left, y_pos - it->y_draw), already_processed); + + song->update(SC_SELECTION); + + have_lasso=false; + redraw(); + } } #define PITCH_DELTA 5 @@ -3402,6 +3672,13 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) int tick=flo_quantize_floor(x_to_tick(x), quant_ticks()); + + if ((drag_cursor_changed==false) && ((dx!=0) || (dy!=0))) + { + setCursor(Qt::SizeAllCursor); + drag_cursor_changed=true; + } + if (mouse_operation==NO_OP) { if ((abs(dx)>DRAG_INIT_DISTANCE) && (mouse_x_drag_operation!=NO_OP)) @@ -3428,16 +3705,25 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) case PITCH: if (debugMsg) cout << "changing pitch, delta="<<nearbyint((float)dy/PITCH_DELTA)<<endl; new_pitch=dragged_event_original_pitch - nearbyint((float)dy/PITCH_DELTA); - + + if (new_pitch < 0) new_pitch=0; + if (new_pitch > 127) new_pitch=127; + if (dragged_event.pitch()!=new_pitch) { + if (!undo_started) + { + song->startUndo(); + undo_started=true; + } + Event tmp=dragged_event.clone(); tmp.setPitch(new_pitch); audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); dragged_event=tmp; - song_changed(SC_EVENT_INSERTED); + fully_recalculate(); } break; @@ -3445,6 +3731,12 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) case BEGIN: if (dragged_event.tick()+dragged_event_part->tick() != unsigned(tick)) { + if (!undo_started) + { + song->startUndo(); + undo_started=true; + } + Event tmp=dragged_event.clone(); signed relative_tick=tick-signed(dragged_event_part->tick()); @@ -3474,7 +3766,7 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); dragged_event=tmp; - song_changed(SC_EVENT_INSERTED); + fully_recalculate(); } break; @@ -3483,6 +3775,12 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) tick+=quant_ticks(); if (dragged_event.tick()+dragged_event.lenTick() + dragged_event_part->tick() != unsigned(tick)) { + if (!undo_started) + { + song->startUndo(); + undo_started=true; + } + Event tmp=dragged_event.clone(); signed relative_tick=tick-signed(dragged_event_part->tick()); signed new_len=relative_tick-dragged_event.tick(); @@ -3504,7 +3802,7 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); dragged_event=tmp; - song_changed(SC_EVENT_INSERTED); + fully_recalculate(); } break; @@ -3555,6 +3853,12 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) { y_scroll_speed=0; } + + if (have_lasso) + { + lasso=QRect(lasso_start, event->pos()).normalized(); + redraw(); + } } void ScoreCanvas::heartbeat_timer_event() @@ -3685,16 +3989,33 @@ void ScoreCanvas::recalc_staff_pos() { case NORMAL: it->y_draw = it->y_top + STAFF_DISTANCE/2; + if (it->min_y_coord < -STAFF_DISTANCE/2) + it->y_draw+= (-it->min_y_coord - STAFF_DISTANCE/2); + it->y_bottom = it->y_draw + STAFF_DISTANCE/2; + if (it->max_y_coord > STAFF_DISTANCE/2) + it->y_bottom+= (it->max_y_coord - STAFF_DISTANCE/2); + break; + case GRAND_TOP: it->y_draw = it->y_top + STAFF_DISTANCE/2; + if (it->min_y_coord < -STAFF_DISTANCE/2) + it->y_draw+= (-it->min_y_coord - STAFF_DISTANCE/2); + it->y_bottom = it->y_draw + GRANDSTAFF_DISTANCE/2; + break; + case GRAND_BOTTOM: it->y_draw = it->y_top + GRANDSTAFF_DISTANCE/2; + it->y_bottom = it->y_draw + STAFF_DISTANCE/2; + if (it->max_y_coord > STAFF_DISTANCE/2) + it->y_bottom+= (it->max_y_coord - STAFF_DISTANCE/2); + break; + default: cerr << "ERROR: THIS SHOULD NEVER HAPPEN: invalid staff type!" << endl; } @@ -3777,7 +4098,7 @@ void ScoreCanvas::set_quant(int val) set_pixels_per_whole(pixels_per_whole() * quant_len() / old_len ); - song_changed(SC_EVENT_INSERTED); + fully_recalculate(); } else { @@ -3785,7 +4106,7 @@ void ScoreCanvas::set_quant(int val) } } -void ScoreCanvas::set_pixels_per_whole(int val) //FINDMICH passt das? +void ScoreCanvas::set_pixels_per_whole(int val) { if (debugMsg) cout << "setting px per whole to " << val << endl; @@ -3838,14 +4159,39 @@ void ScoreCanvas::maybe_close_if_empty() } } -void ScoreCanvas::set_newnote_velo(int velo) +void ScoreCanvas::set_velo(int velo) +{ + note_velo=velo; + + if (parent->get_apply_velo()) + modify_velocity(get_all_parts(),1, 0,velo); +} + +void ScoreCanvas::set_velo_off(int velo) { - newnote_velo=velo; + note_velo_off=velo; + + if (parent->get_apply_velo()) + modify_off_velocity(get_all_parts(),1, 0,velo); } -void ScoreCanvas::set_newnote_velo_off(int velo) +void ScoreCanvas::deselect_all() { - newnote_velo_off=velo; + set<Part*> all_parts=get_all_parts(); + + for (set<Part*>::iterator part=all_parts.begin(); part!=all_parts.end(); part++) + for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++) + event->second.setSelected(false); + + song->update(SC_SELECTION); +} + +void ScoreCanvas::keyPressEvent(QKeyEvent* event) +{ + if (event->key()==Qt::Key_Delete) + { + erase_notes(get_all_parts(), 1); // 1 means "all selected" + } } bool staff_t::cleanup_parts() @@ -3893,6 +4239,22 @@ set<Part*> staff_t::parts_at_tick(unsigned tick) return result; } +void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed) +{ + for (ScoreItemList::iterator it=itemlist.begin(); it!=itemlist.end(); it++) + for (set<FloItem>::iterator it2=it->second.begin(); it2!=it->second.end(); it2++) + if (it2->type==FloItem::NOTE) + { + if (rect.contains(it2->x, it2->y)) + if (already_processed.find(it2->source_event)==already_processed.end()) + { + it2->source_event->setSelected(!it2->source_event->selected()); + already_processed.insert(it2->source_event); + } + } +} + + //the following assertions are made: // pix_quarter.width() == pix_half.width() @@ -3904,7 +4266,6 @@ set<Part*> staff_t::parts_at_tick(unsigned tick) - //hint: recalculating event- and itemlists "from zero" // could happen in realtime, as it is pretty fast. // however, this adds unneccessary cpu usage. @@ -3919,32 +4280,35 @@ set<Part*> staff_t::parts_at_tick(unsigned tick) * between, for example, when a cis is tied to a des * * CURRENT TODO - * o offer functions like in the pianoroll: quantize etc. - * o support selections - * o let the user select the distance between staves, or do this - * automatically? + * o add music-keyboard-bindings for "insert rest" and "increase note length" + * o maybe support step-recording in score editor as well? * * IMPORTANT TODO - * o add a select-clef-toolbox for tracks - * o respect the track's clef (has to be implemented first in muse) * o do partial recalculating; recalculating can take pretty long * (0,5 sec) when displaying a whole song in scores - * o save toolbar position also in the global window settings - * and provide sane defaults + * o transpose etc. must also transpose key-pressure events + * o transpose: support in-key-transpose + * o thin out: remove unneeded ctrl messages * * less important stuff + * o drum list: scroll while dragging + * o controller view in score editor + * o quantize-templates (everything is forced into a specified + * rhythm) + * o part-templates (you specify some notes and a control-chord; + * the notes are set according to the chord then) + * o add functions like set velo, mod/set velo-off * o deal with expanding parts - * o do all the song_changed(SC_EVENT_INSERTED) properly * o use bars instead of flags over groups of 8ths / 16ths etc * o support different keys in different tracks at the same time * calc_pos_add_list and calc_item_pos will be affected by this * calc_pos_add_list must be called before calc_item_pos then, * and calc_item_pos must respect the pos_add_list instead of * keeping its own pos_add variable (which is only an optimisation) - * o save more configuration stuff (quant, color, to_init) + * o support edge-scrolling when opening a lasso + * o save more configuration stuff (quant, color) * * really unimportant nice-to-haves - * o clean up code (find TODOs) * o support in-song clef-changes * o draw measure numbers * o use timesig_t in all timesig-stuff @@ -3954,48 +4318,17 @@ set<Part*> staff_t::parts_at_tick(unsigned tick) * * * stuff for the other muse developers + * o update translations + * o remove ambiguous translation: "offset"="zeitversatz" + * this is ambigous in mod. note len and WRONG in mod. velo dialogs + * * o process accurate timesignatures from muse's list (has to be implemented first in muse) * ( (2+2+3)/4 or (3+2+2)/4 instead of 7/4 ) * o maybe do expanding parts inside the msgChangeEvent or * msgNewEvent functions (see my e-mail) - * - * GUI stuff - * o velocity/release-velo for already existing notes - * - do this by right-click -> some dialog shows up? - * - or by selecting the note and changing the values in the same widget which also is used for new notes? - * - or by controller graphs, as used by the piano roll */ -/* how to use the score editor with multiple tracks - * ================================================ - * - * select parts, right-click, "display in new score window" or "display per-track in new score window" - * or "display in existing window -> 1,2,3,4" or "display per-track in existing..." - * - * ScoreCanvas has a list of note systems, consisting of the following: - * * all parts included in that view - * * eventlist, itemlist - * * used clef, transposing/octave settings - * * enum { NOT_GROUPED, I_AM_TOP, I_AM_BOTTOM } group_state - * NOT_GROUPED means "single note system" - * I_AM_TOP and I_AM_BOTTOM mean that the two systems belong - * together - * - * when redrawing, we iterate through all systems. - * we add a distance according to group_state - * then we draw the system. if group_state is I_AM_BOTTOM, we - * draw our beams longer/higher, and we draw a bracket - * - * when clicking around, we first determine which system has been clicked in - * (the systems have enough space in between, so there won't be notes - * from sys1 in sys2. if there are, they're ignored for simplicity) - * then we proceed as usual (adding, removing, changing notes) - * - * - * pos_add_list stays the same for each staff, so we only need one - */ - /* R O A D M A P * ============= * @@ -4043,4 +4376,3 @@ set<Part*> staff_t::parts_at_tick(unsigned tick) * REASON: this is only a nice-to-have, which can however be * easily implemented when 4) is done */ - diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 111a4f47..2ce8d645 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -20,17 +20,18 @@ #include <QSignalMapper> #include <QAction> #include <QActionGroup> +#include <QGridLayout> +#include <QByteArray> #include <values.h> #include "noteinfo.h" #include "cobject.h" -#include "midieditor.h" -#include "tools.h" #include "event.h" #include "view.h" #include "gconfig.h" #include "part.h" #include "keyevent.h" +#include "mtscale_flo.h" #include <set> #include <map> @@ -55,9 +56,14 @@ using std::string; enum {CMD_COLOR_BLACK, CMD_COLOR_VELO, CMD_COLOR_PART, CMD_SET_NAME, CMD_NOTELEN_1, CMD_NOTELEN_2, CMD_NOTELEN_4, CMD_NOTELEN_8, - CMD_NOTELEN_16, CMD_NOTELEN_32, CMD_NOTELEN_LAST }; + CMD_NOTELEN_16, CMD_NOTELEN_32, CMD_NOTELEN_LAST, + + CMD_QUANTIZE, CMD_VELOCITY, CMD_CRESCENDO, CMD_NOTELEN, CMD_TRANSPOSE, + CMD_ERASE, CMD_MOVE, CMD_FIXED_LEN, CMD_DELETE_OVERLAPS, CMD_LEGATO }; + class ScoreCanvas; +class EditToolBar; //--------------------------------------------------------- // ScoreEdit @@ -66,10 +72,15 @@ class ScoreCanvas; class ScoreEdit : public TopWin { Q_OBJECT + public: + enum clefTypes { trebleClef, bassClef, grandStaff }; private: virtual void closeEvent(QCloseEvent*); virtual void resizeEvent(QResizeEvent*); + virtual void focusOutEvent(QFocusEvent*); + + void store_initial_state(); void init_name(); @@ -103,9 +114,14 @@ class ScoreEdit : public TopWin QScrollBar* xscroll; QScrollBar* yscroll; ScoreCanvas* score_canvas; + MTScaleFlo* time_bar; + + QLabel* apply_velo_to_label; + bool apply_velo; static set<QString> names; static int width_init, height_init; + static QByteArray default_toolbar_state; QString name; @@ -115,16 +131,21 @@ class ScoreEdit : public TopWin private slots: void menu_command(int); + void velo_box_changed(); + void velo_off_box_changed(); signals: void deleted(unsigned long); void name_changed(); + void velo_changed(int); + void velo_off_changed(int); public slots: void canvas_width_changed(int); void viewport_width_changed(int); void canvas_height_changed(int); void viewport_height_changed(int); + void song_changed(int); public: ScoreEdit(QWidget* parent = 0, const char* name = 0, unsigned initPos = MAXINT); @@ -137,6 +158,7 @@ class ScoreEdit : public TopWin void add_parts(PartList* pl, bool all_in_one=false); QString get_name() { return name; } + bool get_apply_velo() { return apply_velo; } }; @@ -436,8 +458,9 @@ struct cumulative_t #define BLACK_PIXMAP (NUM_PARTCOLORS) #define HIGHLIGHTED_PIXMAP (NUM_PARTCOLORS+1) -#define NUM_MYCOLORS (NUM_PARTCOLORS+2 + 128) -#define VELO_PIXMAP_BEGIN (NUM_PARTCOLORS+2) +#define SELECTED_PIXMAP (NUM_PARTCOLORS+2) +#define NUM_MYCOLORS (NUM_PARTCOLORS+3 + 128) +#define VELO_PIXMAP_BEGIN (NUM_PARTCOLORS+3) struct timesig_t { @@ -469,6 +492,9 @@ struct staff_t int y_draw; int y_bottom; + int min_y_coord; + int max_y_coord; + staff_type_t type; clef_t clef; @@ -479,6 +505,8 @@ struct staff_t void process_itemlist(); void calc_item_pos(); + void apply_lasso(QRect rect, set<Event*>& already_processed); + void recalculate() { create_appropriate_eventlist(); @@ -561,13 +589,6 @@ class ScoreCanvas : public View void recalc_staff_pos(); list<staff_t>::iterator staff_at_y(int y); - - timesig_t timesig_at_tick(int t); - key_enum key_at_tick(int t); - int tick_to_x(int t); - int x_to_tick(int x); - int calc_posadd(int t); - bool need_redraw_for_hilighting(ScoreItemList::iterator from_it, ScoreItemList::iterator to_it); @@ -588,8 +609,8 @@ class ScoreCanvas : public View int _quant_power2; int _pixels_per_whole; - int newnote_velo; - int newnote_velo_off; + int note_velo; + int note_velo_off; std::map<int,int> pos_add_list; @@ -619,6 +640,7 @@ class ScoreCanvas : public View int last_len; int new_len; //when zero or negative, last_len is used + Qt::KeyboardModifiers keystate; QPoint mouse_down_pos; bool mouse_down; enum operation_t @@ -634,11 +656,19 @@ class ScoreCanvas : public View bool mouse_inserts_notes; bool dragging; + bool drag_cursor_changed; Part* dragged_event_part; Event dragged_event; int dragged_event_original_pitch; + + bool have_lasso; + QPoint lasso_start; + QRect lasso; - + bool undo_started; + int undo_flags; + + enum {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_VELO} coloring_mode; bool preamble_contains_keysig; @@ -664,11 +694,14 @@ class ScoreCanvas : public View void play_changed(bool); void config_changed(); + + void deselect_all(); public slots: void x_scroll_event(int); void y_scroll_event(int); void song_changed(int); + void fully_recalculate(); void goto_tick(int,bool); void pos_changed(int i, unsigned u, bool b); void heartbeat_timer_event(); @@ -680,17 +713,19 @@ class ScoreCanvas : public View void preamble_timesig_slot(bool); void set_pixels_per_whole(int); - void set_newnote_velo(int); - void set_newnote_velo_off(int); + void set_velo(int); + void set_velo_off(int); signals: void xscroll_changed(int); void yscroll_changed(int); void viewport_width_changed(int); void canvas_width_changed(int); + void preamble_width_changed(int); void viewport_height_changed(int); void canvas_height_changed(int); void pixels_per_whole_changed(int); + void pos_add_changed(); protected: virtual void draw(QPainter& p, const QRect& rect); @@ -700,9 +735,10 @@ class ScoreCanvas : public View virtual void mouseMoveEvent (QMouseEvent* event); virtual void mouseReleaseEvent (QMouseEvent* event); virtual void resizeEvent(QResizeEvent*); + virtual void keyPressEvent(QKeyEvent* event); public: - ScoreCanvas(ScoreEdit*, QWidget*, int, int); + ScoreCanvas(ScoreEdit*, QWidget*); ~ScoreCanvas(){}; void add_staves(PartList* pl, bool all_in_one); @@ -725,7 +761,16 @@ class ScoreCanvas : public View Part* get_selected_part() {return selected_part;} void set_selected_part(Part* p) {selected_part=p;} + set<Part*> get_all_parts(); + void write_staves(int level, Xml& xml) const; + + timesig_t timesig_at_tick(int t); + key_enum key_at_tick(int t); + int tick_to_x(int t); + int delta_tick_to_delta_x(int t); + int x_to_tick(int x); + int calc_posadd(int t); }; int calc_measure_len(const list<int>& nums, int denom); diff --git a/muse2/muse/midieditor.cpp b/muse2/muse/midieditor.cpp index 7e25972c..f4d21320 100644 --- a/muse2/muse/midieditor.cpp +++ b/muse2/muse/midieditor.cpp @@ -23,7 +23,7 @@ // MidiEditor //--------------------------------------------------------- -MidiEditor::MidiEditor(int q, int r, PartList* pl, +MidiEditor::MidiEditor(int r, PartList* pl, QWidget* parent, const char* name) : TopWin(parent, name) { setAttribute(Qt::WA_DeleteOnClose); @@ -31,7 +31,6 @@ MidiEditor::MidiEditor(int q, int r, PartList* pl, if (_pl) for (iPart i = _pl->begin(); i != _pl->end(); ++i) _parts.push_back(i->second->sn()); - _quant = q; _raster = r; canvas = 0; wview = 0; @@ -81,17 +80,6 @@ MidiEditor::~MidiEditor() delete _pl; } -//--------------------------------------------------------- -// quantVal -//--------------------------------------------------------- - -int MidiEditor::quantVal(int v) const - { - int val = ((v+_quant/2)/_quant)*_quant; - if (val == 0) - val = _quant; - return val; - } //--------------------------------------------------------- // readStatus @@ -110,9 +98,7 @@ void MidiEditor::readStatus(Xml& xml) case Xml::End: return; case Xml::TagStart: - if (tag == "quant") - _quant = xml.parseInt(); - else if (tag == "raster") + if (tag == "raster") _raster = xml.parseInt(); else if (tag == "topwin") TopWin::readStatus(xml); @@ -155,7 +141,6 @@ void MidiEditor::writeStatus(int level, Xml& xml) const { xml.tag(level++, "midieditor"); TopWin::writeStatus(level, xml); - xml.intTag(level, "quant", _quant); xml.intTag(level, "raster", _raster); xml.tag(level, "/midieditor"); } diff --git a/muse2/muse/midieditor.h b/muse2/muse/midieditor.h index c5668abf..78873a6a 100644 --- a/muse2/muse/midieditor.h +++ b/muse2/muse/midieditor.h @@ -44,7 +44,7 @@ class MidiEditor : public TopWin { WaveView* wview; std::list<CtrlEdit*> ctrlEditList; - int _quant, _raster; + int _raster; QGridLayout* mainGrid; QWidget* mainw; virtual void readStatus(Xml&); @@ -63,11 +63,10 @@ class MidiEditor : public TopWin { void curDrumInstrumentChanged(int); public: - MidiEditor(int, int, PartList*, + MidiEditor(int, PartList*, QWidget* parent = 0, const char* name = 0); ~MidiEditor(); - int quantVal(int v) const; ///int rasterStep(unsigned tick) const { return sigmap.rasterStep(tick, _raster); } ///unsigned rasterVal(unsigned v) const { return sigmap.raster(v, _raster); } ///unsigned rasterVal1(unsigned v) const { return sigmap.raster1(v, _raster); } @@ -76,8 +75,6 @@ class MidiEditor : public TopWin { unsigned rasterVal(unsigned v) const { return AL::sigmap.raster(v, _raster); } unsigned rasterVal1(unsigned v) const { return AL::sigmap.raster1(v, _raster); } unsigned rasterVal2(unsigned v) const { return AL::sigmap.raster2(v, _raster); } - int quant() const { return _quant; } - void setQuant(int val) { _quant = val; } int raster() const { return _raster; } void setRaster(int val) { _raster = val; } PartList* parts() { return _pl; } diff --git a/muse2/muse/midifile.cpp b/muse2/muse/midifile.cpp index 89cf30f6..65cb6d25 100644 --- a/muse2/muse/midifile.cpp +++ b/muse2/muse/midifile.cpp @@ -325,7 +325,7 @@ int MidiFile::readEvent(MidiPlayEvent* event, MidiFileTrack* t) } if (buffer[len-1] != 0xf7) { printf("SYSEX endet nicht mit 0xf7!\n"); - // Forstsetzung folgt? + // Fortsetzung folgt? } else --len; // don't count 0xf7 diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp index cd54b096..86ab0dcd 100644 --- a/muse2/muse/shortcuts.cpp +++ b/muse2/muse/shortcuts.cpp @@ -181,13 +181,9 @@ void initShortCuts() //Pianoroll: //----------------------------------------------------------- - defShrt(SHRT_OVER_QUANTIZE, 0, "Quantize: Over Quantize", PROLL_SHRT, "midi_over_quant"); - defShrt(SHRT_ON_QUANTIZE, 0, "Quantize: Note On Quantize", PROLL_SHRT, "midi_quant_noteon"); - defShrt(SHRT_ONOFF_QUANTIZE, 0, "Quantize: Note On/Off Quantize", PROLL_SHRT,"midi_quant_noteoff"); - defShrt(SHRT_ITERATIVE_QUANTIZE,0,"Quantize: Iterative Quantize", PROLL_SHRT,"midi_quant_iterative"); - defShrt(SHRT_CONFIG_QUANT, Qt::CTRL + Qt::ALT + Qt::Key_Q, "Quantize: Configure quant", PROLL_SHRT, "config_quant"); - defShrt(SHRT_MODIFY_GATE_TIME, 0, "Quantize: Modify Gate Time", PROLL_SHRT, "midi_mod_gate_time"); - defShrt(SHRT_MODIFY_VELOCITY, 0, "Quantize: Modify Velocity", PROLL_SHRT, "midi_mod_velo"); + defShrt(SHRT_QUANTIZE, 0, "Quantize", PROLL_SHRT, "midi_quant"); + defShrt(SHRT_MODIFY_GATE_TIME, 0, "Modify Note Length", PROLL_SHRT, "midi_mod_gate_time"); + defShrt(SHRT_MODIFY_VELOCITY, 0, "Modify Velocity", PROLL_SHRT, "midi_mod_velo"); defShrt(SHRT_CRESCENDO, 0, "Edit: Crescendo", PROLL_SHRT, "midi_crescendo"); defShrt(SHRT_THIN_OUT, 0, "Edit: Thin Out", PROLL_SHRT, "midi_thin_out"); defShrt(SHRT_ERASE_EVENT, 0, "Edit: Erase Event", PROLL_SHRT, "midi_erase_event"); diff --git a/muse2/muse/shortcuts.h b/muse2/muse/shortcuts.h index 1098be49..b72e0207 100644 --- a/muse2/muse/shortcuts.h +++ b/muse2/muse/shortcuts.h @@ -22,7 +22,7 @@ #define DEDIT_SHRT 2 // Drumedit shortcut #define LEDIT_SHRT 4 // Listedit shortcut #define SCORE_SHRT 8 // Score shortcut -#define ARRANG_SHRT 16 // Arrenger shortcut +#define ARRANG_SHRT 16 // Arranger shortcut #define TRANSP_SHRT 32 // Transport shortcut #define WAVE_SHRT 64 // Waveedit shortcut #define GLOBAL_SHRT 128 // Global shortcuts @@ -246,11 +246,6 @@ enum { SHRT_SCROLL_RIGHT, // l SHRT_FIXED_LEN, //Alt+L, currently only drumeditor SHRT_QUANTIZE, //q - SHRT_OVER_QUANTIZE, //Default: undefined - SHRT_ON_QUANTIZE, //Default: undefined - SHRT_ONOFF_QUANTIZE, //Default: undefined - SHRT_ITERATIVE_QUANTIZE, //Default: undefined - SHRT_CONFIG_QUANT, //Default: Ctrl+Alt+Q SHRT_MODIFY_GATE_TIME, //Default: undefined SHRT_MODIFY_VELOCITY, SHRT_CRESCENDO, diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 2900097e..28ea1210 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -3776,6 +3776,7 @@ void Song::executeScript(const char* scriptfile, PartList* parts, int quant, boo file.close(); } + remove(tmp); } diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 2a93968d..5dab4c09 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -369,6 +369,7 @@ MidiTrack::MidiTrack() init(); _events = new EventList; _mpevents = new MPEventList; + clefType=ScoreEdit::trebleClef; } //MidiTrack::MidiTrack(const MidiTrack& mt) @@ -388,6 +389,7 @@ MidiTrack::MidiTrack(const MidiTrack& mt, bool cloneParts) len = mt.len; compression = mt.compression; _recEcho = mt.recEcho(); + clefType=ScoreEdit::trebleClef; } MidiTrack::~MidiTrack() @@ -894,6 +896,7 @@ void MidiTrack::write(int level, Xml& xml) const xml.intTag(level, "len", len); xml.intTag(level, "compression", compression); xml.intTag(level, "automation", int(automationType())); + xml.intTag(level, "clef", int(clefType)); const PartList* pl = cparts(); for (ciPart p = pl->begin(); p != pl->end(); ++p) @@ -955,6 +958,8 @@ void MidiTrack::read(Xml& xml) _recEcho = xml.parseInt(); else if (tag == "automation") setAutomationType(AutomationType(xml.parseInt())); + else if (tag == "clef") + clefType = (ScoreEdit::clefTypes)xml.parseInt(); else if (Track::readProperties(xml, tag)) { // version 1.0 compatibility: if (tag == "track" && xml.majorVersion() == 1 && xml.minorVersion() == 0) diff --git a/muse2/muse/track.h b/muse2/muse/track.h index aec765da..d1dc3a6f 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -20,6 +20,7 @@ #include "route.h" #include "ctrl.h" #include "globaldefs.h" +#include "scoreedit.h" class Pipeline; class Xml; @@ -208,6 +209,7 @@ class MidiTrack : public Track { EventList* _events; // tmp Events during midi import MPEventList* _mpevents; // tmp Events druring recording static bool _isVisible; + ScoreEdit::clefTypes clefType; public: MidiTrack(); @@ -273,6 +275,9 @@ class MidiTrack : public Track { virtual bool canRecord() const { return true; } static void setVisible(bool t) { _isVisible = t; } static bool visible() { return _isVisible; } + + void setClef(ScoreEdit::clefTypes i) { clefType = i; } + ScoreEdit::clefTypes getClef() { return clefType; } }; //--------------------------------------------------------- diff --git a/muse2/muse/transpose.cpp b/muse2/muse/transpose.cpp deleted file mode 100644 index 9e99c471..00000000 --- a/muse2/muse/transpose.cpp +++ /dev/null @@ -1,100 +0,0 @@ - -#include <stdio.h> - -#include <QDialog> - -#include "transpose.h" -#include "track.h" -#include "song.h" -#include "event.h" -#include "audio.h" - -//--------------------------------------------------------- -// Transpose -//--------------------------------------------------------- - -Transpose::Transpose(QWidget* parent) - : QDialog(parent) - { - setupUi(this); - setAttribute(Qt::WA_DeleteOnClose); - buttonGroup1 = new QButtonGroup(this); - buttonGroup1->addButton(time_all); - buttonGroup1->addButton(time_selected); - buttonGroup2 = new QButtonGroup(this); - buttonGroup2->addButton(parts_all); - buttonGroup2->addButton(parts_selected); - - if (song->lpos() != song->rpos()) { - time_selected->setChecked(true); - } - else { -// time_all->setChecked(true); - ButtonBox1->setEnabled(false); - } -// parts_all->setSelected(true); - } - -//--------------------------------------------------------- -// accept -//--------------------------------------------------------- - -void Transpose::accept() - { - int left = 0, right = 0; - int dv = delta->value(); - - TrackList *tracks = song->tracks(); - - if (time_selected->isChecked()) { - left = song->lpos(); - right = song->rpos(); - } - else { - left = 0; - right = song->len(); - } - - std::vector< EventList* > doneList; - typedef std::vector< EventList* >::iterator iDoneList; - - song->startUndo(); - for (iTrack t = tracks->begin(); t != tracks->end(); ++t) { -// if (((*t)->type() == Track::MIDI || (*t)->type() == Track::DRUM) - if (((*t)->type() != Track::MIDI) - || !(parts_all->isChecked() || (*t)->selected())) - continue; - - PartList *pl = (*t)->parts(); - for (iPart p = pl->begin(); p != pl->end(); ++p) { - MidiPart *mp = (MidiPart *) p->second; - EventList* el = mp->events(); - - // Check if the event list has already been done. Skip repeated clones. - iDoneList idl; - for(idl = doneList.begin(); idl != doneList.end(); ++idl) - if(*idl == el) - break; - if(idl != doneList.end()) - break; - doneList.push_back(el); - - for (iEvent i = el->begin(); i != el->end(); ++i) { - Event oe = i->second; - int tick = oe.tick(); - if (tick > right) - break; - if (tick < left) - continue; - Event ne = oe.clone(); - ne.setA(oe.dataA() + dv ); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(oe, ne, mp, false); - audio->msgChangeEvent(oe, ne, mp, false, false, false); - } - } - } - song->endUndo(SC_EVENT_MODIFIED); - close(); - } - diff --git a/muse2/muse/transpose.h b/muse2/muse/transpose.h deleted file mode 100644 index a5d2a1bb..00000000 --- a/muse2/muse/transpose.h +++ /dev/null @@ -1,26 +0,0 @@ - -#ifndef __TRANSPOSE_H__ -#define __TRANSPOSE_H__ - -#include "ui_transposebase.h" - -class QButtonGroup; - -//--------------------------------------------------------- -// transpose widget -//--------------------------------------------------------- - -class Transpose : public QDialog, public Ui::TransposeDialogBase { - Q_OBJECT - - QButtonGroup* buttonGroup1; - QButtonGroup* buttonGroup2; - - private slots: - virtual void accept(); - - public: - Transpose(QWidget* parent=0); - }; - -#endif diff --git a/muse2/muse/waveedit/waveedit.cpp b/muse2/muse/waveedit/waveedit.cpp index ccfb2730..7a5ad815 100644 --- a/muse2/muse/waveedit/waveedit.cpp +++ b/muse2/muse/waveedit/waveedit.cpp @@ -42,6 +42,7 @@ extern QColor readColor(Xml& xml); int WaveEdit::_widthInit = 600; int WaveEdit::_heightInit = 400; +QByteArray WaveEdit::_toolbarInit; //--------------------------------------------------------- // closeEvent @@ -61,9 +62,10 @@ void WaveEdit::closeEvent(QCloseEvent* e) //--------------------------------------------------------- WaveEdit::WaveEdit(PartList* pl) - : MidiEditor(1, 1, pl) + : MidiEditor(1, pl) { resize(_widthInit, _heightInit); + setFocusPolicy(Qt::StrongFocus); QSignalMapper* mapper = new QSignalMapper(this); QAction* act; @@ -170,8 +172,8 @@ WaveEdit::WaveEdit(PartList* pl) // ToolBar: Solo Cursor1 Cursor2 addToolBarBreak(); - tb1 = addToolBar(tr("Pianoroll tools")); - tb1->setObjectName("Pianoroll tools"); + tb1 = addToolBar(tr("WaveEdit tools")); + tb1->setObjectName("WaveEdit tools"); //tb1->setLabel(tr("weTools")); solo = new QToolButton(); @@ -254,6 +256,8 @@ WaveEdit::WaveEdit(PartList* pl) connect(hscroll, SIGNAL(scaleChanged(int)), SLOT(updateHScrollRange())); connect(song, SIGNAL(songChanged(int)), SLOT(songChanged1(int))); + if (!_toolbarInit.isEmpty()) + restoreState(_toolbarInit); initShortcuts(); @@ -359,6 +363,8 @@ void WaveEdit::readConfiguration(Xml& xml) _widthInit = xml.parseInt(); else if (tag == "height") _heightInit = xml.parseInt(); + else if (tag == "toolbars") + _toolbarInit = QByteArray::fromHex(xml.parse1().toAscii()); else xml.unknown("WaveEdit"); break; @@ -384,6 +390,7 @@ void WaveEdit::writeConfiguration(int level, Xml& xml) xml.colorTag(level, "bgcolor", config.waveEditBackgroundColor); xml.intTag(level, "width", _widthInit); xml.intTag(level, "height", _heightInit); + xml.strTag(level, "toolbars", _toolbarInit.toHex().data()); xml.tag(level, "/waveedit"); } @@ -442,11 +449,33 @@ void WaveEdit::readStatus(Xml& xml) void WaveEdit::resizeEvent(QResizeEvent* ev) { QWidget::resizeEvent(ev); - _widthInit = ev->size().width(); - _heightInit = ev->size().height(); + storeInitialState(); } //--------------------------------------------------------- +// focusOutEvent +//--------------------------------------------------------- + +void WaveEdit::focusOutEvent(QFocusEvent* ev) + { + QWidget::focusOutEvent(ev); + storeInitialState(); + } + + +//--------------------------------------------------------- +// storeInitialState +//--------------------------------------------------------- + +void WaveEdit::storeInitialState() + { + _widthInit = width(); + _heightInit = height(); + _toolbarInit=saveState(); + } + + +//--------------------------------------------------------- // songChanged1 // signal from "song" //--------------------------------------------------------- diff --git a/muse2/muse/waveedit/waveedit.h b/muse2/muse/waveedit/waveedit.h index b4000794..e966a635 100644 --- a/muse2/muse/waveedit/waveedit.h +++ b/muse2/muse/waveedit/waveedit.h @@ -14,6 +14,8 @@ #include <QResizeEvent> #include <QKeyEvent> #include <QCloseEvent> +#include <QByteArray> + #include "midieditor.h" class QToolButton; @@ -45,11 +47,14 @@ class WaveEdit : public MidiEditor { QAction* pasteAction; static int _widthInit, _heightInit; + static QByteArray _toolbarInit; Q_OBJECT virtual void closeEvent(QCloseEvent*); - virtual void resizeEvent(QResizeEvent* ev); virtual void keyPressEvent(QKeyEvent*); + virtual void resizeEvent(QResizeEvent* ev); + virtual void focusOutEvent(QFocusEvent*); + void storeInitialState(); QMenu* menuFunctions, *select, *menuGain; diff --git a/muse2/muse/waveedit/waveview.cpp b/muse2/muse/waveedit/waveview.cpp index 0c387f72..1c7f74f2 100644 --- a/muse2/muse/waveedit/waveview.cpp +++ b/muse2/muse/waveedit/waveview.cpp @@ -392,7 +392,6 @@ void WaveView::wheelEvent(QWheelEvent* ev) int keyState = ev->modifiers(); bool shift = keyState & Qt::ShiftModifier; - bool alt = keyState & Qt::AltModifier; bool ctrl = keyState & Qt::ControlModifier; if (shift) { // scroll vertically diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt index 9a3f993a..7589ddf0 100644 --- a/muse2/muse/widgets/CMakeLists.txt +++ b/muse2/muse/widgets/CMakeLists.txt @@ -18,6 +18,12 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #============================================================================= +set (SubDirs + function_dialogs + ) + +subdirs (${SubDirs}) + ## ## Expand Qt macros in source files ## @@ -35,7 +41,6 @@ QT4_WRAP_CPP (widget_mocs didyouknow.h doublelabel.h filedialog.h - gatetime.h genset.h header.h hitscale.h @@ -48,6 +53,7 @@ QT4_WRAP_CPP (widget_mocs mixdowndialog.h mlabel.h mtscale.h + mtscale_flo.h mtrackinfo.h nentry.h noteinfo.h @@ -76,7 +82,6 @@ QT4_WRAP_CPP (widget_mocs # ttoolbar.h ttoolbutton.h unusedwavefiles.h - velocity.h verticalmeter.h view.h vscale.h @@ -96,7 +101,6 @@ file (GLOB widgets_ui_files editnotedialogbase.ui editsysexdialogbase.ui fdialogbuttons.ui - gatetimebase.ui gensetbase.ui itransformbase.ui metronomebase.ui @@ -110,9 +114,7 @@ file (GLOB widgets_ui_files songinfo.ui synthconfigbase.ui transformbase.ui - transposebase.ui unusedwavefiles.ui - velocitybase.ui ) QT4_WRAP_UI (widget_ui_headers ${widgets_ui_files}) @@ -134,7 +136,6 @@ file (GLOB widgets_source_files doublelabel.cpp drange.cpp filedialog.cpp - gatetime.cpp genset.cpp header.cpp hitscale.cpp @@ -149,6 +150,7 @@ file (GLOB widgets_source_files mmath.cpp mtrackinfo.cpp mtscale.cpp + mtscale_flo.cpp nentry.cpp noteinfo.cpp pitchedit.cpp diff --git a/muse2/muse/widgets/appearancebase.ui b/muse2/muse/widgets/appearancebase.ui index 8cb8c08c..a3a80a96 100644 --- a/muse2/muse/widgets/appearancebase.ui +++ b/muse2/muse/widgets/appearancebase.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>538</width> + <width>558</width> <height>531</height> </rect> </property> @@ -69,6 +69,39 @@ </property> </widget> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="partCakeStretch"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>y-stretch</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> </item> @@ -156,6 +189,9 @@ <attribute name="headerVisible"> <bool>false</bool> </attribute> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> <column> <property name="text"> <string notr="true">1</string> @@ -1936,5 +1972,21 @@ </hint> </hints> </connection> + <connection> + <sender>partShowCakes</sender> + <signal>toggled(bool)</signal> + <receiver>partCakeStretch</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>141</x> + <y>137</y> + </hint> + <hint type="destinationlabel"> + <x>159</x> + <y>164</y> + </hint> + </hints> + </connection> </connections> </ui> diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index 07ad1d1f..18de985b 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -574,11 +574,11 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) updateSelection(); redraw(); } - startDrag(curItem, shift); + startDrag(curItem, ctrl); } else if (event->button() == Qt::RightButton) { if (curItem) { - if (shift) { + if (ctrl) { drag = DRAG_RESIZE; setCursor(); int dx = start.x() - curItem->x(); @@ -622,15 +622,14 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) // Changed by T356. Alt is default reserved for moving the whole window in KDE. Changed to Shift-Alt. // Hmm, nope, shift-alt is also reserved sometimes. Must find a way to bypass, // why make user turn off setting? Left alone for now... - if (shift && !ctrl) + if (ctrl && !shift) drag = DRAG_COPY_START; else if (alt) { drag = DRAG_CLONE_START; } - else if (ctrl) { //Select all on the same pitch (e.g. same y-value) - if (!shift) + else if (shift) { //Select all on the same pitch (e.g. same y-value) + if (!ctrl) deselectAll(); - //printf("Yes, ctrl and press\n"); for (iCItem i = items.begin(); i != items.end(); ++i) { if (i->second->y() == curItem->y() ) selectItem(i->second, true); @@ -1082,32 +1081,26 @@ void Canvas::viewMouseMoveEvent(QMouseEvent* event) void Canvas::viewMouseReleaseEvent(QMouseEvent* event) { -// printf("release %x %x\n", event->state(), event->button()); - doScroll = false; canScrollLeft = true; canScrollRight = true; canScrollUp = true; canScrollDown = true; - ///if (event->state() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) { if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) { - ///printf("ignore %x %x\n", keyState, event->button()); - //printf("viewMouseReleaseEvent ignore buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button()); return; } QPoint pos = event->pos(); - ///bool shift = event->state() & Qt::ShiftModifier; - bool shift = ((QInputEvent*)event)->modifiers() & Qt::ShiftModifier; + bool ctrl = ((QInputEvent*)event)->modifiers() & Qt::ControlModifier; bool redrawFlag = false; switch (drag) { case DRAG_MOVE_START: case DRAG_COPY_START: case DRAG_CLONE_START: - if (!shift) + if (!ctrl) deselectAll(); - selectItem(curItem, !(shift && curItem->isSelected())); + selectItem(curItem, !(ctrl && curItem->isSelected())); updateSelection(); redrawFlag = true; itemReleased(curItem, curItem->pos()); @@ -1150,17 +1143,17 @@ void Canvas::viewMouseReleaseEvent(QMouseEvent* event) break; case DRAG_LASSO_START: lasso.setRect(-1, -1, -1, -1); - if (!shift) + if (!ctrl) deselectAll(); updateSelection(); redrawFlag = true; break; case DRAG_LASSO: - if (!shift) + if (!ctrl) deselectAll(); lasso = lasso.normalized(); - selectLasso(shift); + selectLasso(ctrl); updateSelection(); redrawFlag = true; break; diff --git a/muse2/muse/widgets/function_dialogs/CMakeLists.txt b/muse2/muse/widgets/function_dialogs/CMakeLists.txt new file mode 100644 index 00000000..db1f3229 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/CMakeLists.txt @@ -0,0 +1,114 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# 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., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +## +## Expand Qt macros in source files +## +QT4_WRAP_CPP (widgets_functiondialogs_mocs + crescendo.h + deloverlaps.h + gatetime.h + move.h + quantize.h + remove.h + setlen.h + transpose.h + legato.h + velocity.h + ) + +## +## UI files +## +file (GLOB widgets_functiondialogs_ui_files + crescendobase.ui + deloverlapsbase.ui + gatetimebase.ui + movebase.ui + quantbase.ui + removebase.ui + setlenbase.ui + transposebase.ui + legatobase.ui + velocitybase.ui + ) + +QT4_WRAP_UI (widgets_functiondialogs_ui_headers ${widgets_functiondialogs_ui_files}) + +## +## List of source files to compile +## +file (GLOB widgets_functiondialogs_source_files + crescendo.cpp + deloverlaps.cpp + gatetime.cpp + move.cpp + quantize.cpp + remove.cpp + setlen.cpp + transpose.cpp + legato.cpp + velocity.cpp + ) + +## +## Define target +## +add_library ( widgets_functiondialogs ${MODULES_BUILD} + ${widgets_functiondialogs_ui_headers} + ${widgets_functiondialogs_mocs} + ${widgets_functiondialogs_source_files} + ) + +## +## Append to the list of translations +## +set (FILES_TO_TRANSLATE + ${FILES_TO_TRANSLATE} + ${widgets_functiondialogs_source_files} + ${widgets_functiondialogs_ui_files} + CACHE INTERNAL "" + ) + +## +## Compilation flags and target name +## +set_target_properties( widgets_functiondialogs + # PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h ${MUSECXXFLAGS} -I../ -I${PROJECT_SOURCE_DIR}/synti " + PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h ${MUSECXXFLAGS} -I../ -I${PROJECT_SOURCE_DIR}/synti" + OUTPUT_NAME muse_widgets_functiondialogs + ) + +## +## Linkage +## +target_link_libraries ( widgets_functiondialogs + ${QT_LIBRARIES} + icons + ) + +## +## Install location +## +if ( ${MODULES_BUILD} STREQUAL SHARED ) + install(TARGETS widgets_functiondialogs + DESTINATION ${MusE_MODULES_DIR} + ) +endif ( ${MODULES_BUILD} STREQUAL SHARED ) diff --git a/muse2/muse/widgets/function_dialogs/crescendo.cpp b/muse2/muse/widgets/function_dialogs/crescendo.cpp new file mode 100644 index 00000000..ef31c5ef --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/crescendo.cpp @@ -0,0 +1,112 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: crescendo.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "crescendo.h" +#include "xml.h" + +Crescendo::Crescendo(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + connect(absolute_button, SIGNAL(toggled(bool)), SLOT(absolute_changed(bool))); + + pull_values(); +} + +void Crescendo::pull_values() +{ + range = range_group->checkedId(); + start_val = start_spinbox->value(); + end_val = end_spinbox->value(); + absolute = absolute_button->isChecked(); +} + +void Crescendo::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Crescendo::exec() +{ + if ((range < 2) || (range > 3)) range=3; + + range_group->button(range)->setChecked(true); + start_spinbox->setValue(start_val); + end_spinbox->setValue(end_val); + absolute_button->setChecked(absolute); + absolute_changed(absolute); + + return QDialog::exec(); +} + +void Crescendo::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "start") + start_val=xml.parseInt(); + else if (tag == "end") + end_val=xml.parseInt(); + else if (tag == "absolute") + absolute=xml.parseInt(); + else + xml.unknown("Crescendo"); + break; + + case Xml::TagEnd: + if (tag == "crescendo") + return; + + default: + break; + } + } +} + +void Crescendo::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "crescendo"); + xml.intTag(level, "range", range); + xml.intTag(level, "start", start_val); + xml.intTag(level, "end", end_val); + xml.intTag(level, "absolute", absolute); + xml.tag(level, "/crescendo"); +} + +void Crescendo::absolute_changed(bool val) +{ + if (val) + { + start_spinbox->setMaximum(127); + start_spinbox->setSuffix(""); + end_spinbox->setMaximum(127); + end_spinbox->setSuffix(""); + } + else + { + start_spinbox->setMaximum(12700); + start_spinbox->setSuffix(" %"); + end_spinbox->setMaximum(12700); + end_spinbox->setSuffix(" %"); + } +} diff --git a/muse2/muse/widgets/function_dialogs/crescendo.h b/muse2/muse/widgets/function_dialogs/crescendo.h new file mode 100644 index 00000000..eb00e94f --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/crescendo.h @@ -0,0 +1,46 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: crescendo.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __CRESCENDO_H__ +#define __CRESCENDO_H__ + +#include "ui_crescendobase.h" + +class QButtonGroup; +class Xml; + +class Crescendo : public QDialog, public Ui::CrescendoBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Crescendo(QWidget* parent = 0); + + int range; + int start_val; + int end_val; + bool absolute; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); + + private slots: + void absolute_changed(bool); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/crescendobase.ui b/muse2/muse/widgets/function_dialogs/crescendobase.ui new file mode 100644 index 00000000..5f4ec1f4 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/crescendobase.ui @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CrescendoBase</class> + <widget class="QDialog" name="CrescendoBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>293</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Crescendo/Decrescendo</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Values</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel3"> + <property name="text"> + <string>Start velocity</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="start_spinbox"> + <property name="suffix"> + <string> %</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>12700</number> + </property> + <property name="value"> + <number>80</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>End velocity</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QRadioButton" name="absolute_button"> + <property name="text"> + <string>Absolute</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QRadioButton" name="relative_button"> + <property name="text"> + <string>Relative</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="end_spinbox"> + <property name="suffix"> + <string> %</string> + </property> + <property name="maximum"> + <number>12700</number> + </property> + <property name="value"> + <number>130</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>CrescendoBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>CrescendoBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/deloverlaps.cpp b/muse2/muse/widgets/function_dialogs/deloverlaps.cpp new file mode 100644 index 00000000..76103d74 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/deloverlaps.cpp @@ -0,0 +1,79 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: deloverlaps.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "deloverlaps.h" +#include "xml.h" + + +DelOverlaps::DelOverlaps(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void DelOverlaps::pull_values() +{ + range = range_group->checkedId(); +} + +void DelOverlaps::accept() +{ + pull_values(); + QDialog::accept(); +} + +int DelOverlaps::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + + return QDialog::exec(); +} + +void DelOverlaps::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else + xml.unknown("DelOverlaps"); + break; + + case Xml::TagEnd: + if (tag == "del_overlaps") + return; + + default: + break; + } + } +} + +void DelOverlaps::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "del_overlaps"); + xml.intTag(level, "range", range); + xml.tag(level, "/del_overlaps"); +} diff --git a/muse2/muse/widgets/function_dialogs/deloverlaps.h b/muse2/muse/widgets/function_dialogs/deloverlaps.h new file mode 100644 index 00000000..813192a6 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/deloverlaps.h @@ -0,0 +1,39 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: deloverlaps.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __DELOVERLAPS_H__ +#define __DELOVERLAPS__H__ + +#include "ui_deloverlapsbase.h" + +class QButtonGroup; +class Xml; + +class DelOverlaps : public QDialog, public Ui::DelOverlapsBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + DelOverlaps(QWidget* parent = 0); + + int range; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/deloverlapsbase.ui b/muse2/muse/widgets/function_dialogs/deloverlapsbase.ui new file mode 100644 index 00000000..7484bf97 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/deloverlapsbase.ui @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DelOverlapsBase</class> + <widget class="QDialog" name="DelOverlapsBase"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>195</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Delete Overlaps</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_events_button"> + <property name="text"> + <string>Selected Events</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>DelOverlapsBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>DelOverlapsBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/gatetime.cpp b/muse2/muse/widgets/function_dialogs/gatetime.cpp new file mode 100644 index 00000000..9448ab1c --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/gatetime.cpp @@ -0,0 +1,108 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: gatetime.cpp,v 1.1.1.1 2003/10/27 18:54:37 wschweer Exp $ +// (C) Copyright 2001 Werner Schweer (ws@seh.de) +//========================================================= + +#include <QButtonGroup> +#include <QDialog> + +#include "gatetime.h" + +#include "xml.h" +#include "song.h" + +//--------------------------------------------------------- +// GateTime +//--------------------------------------------------------- + +GateTime::GateTime(QWidget* parent) + : QDialog(parent) + { + setupUi(this); + rangeGroup = new QButtonGroup(rangeBox); + rangeGroup->addButton(allButton, 0); + rangeGroup->addButton(selButton, 1); + rangeGroup->addButton(loopButton, 2); + rangeGroup->addButton(sloopButton, 3); + rangeGroup->setExclusive(true); + + pullValues(); + } + +//--------------------------------------------------------- +// accept +//--------------------------------------------------------- + +void GateTime::accept() + { + pullValues(); + QDialog::accept(); + } + +//--------------------------------------------------------- +// pullValues +//--------------------------------------------------------- + +void GateTime::pullValues() + { + range = rangeGroup->checkedId(); + rateVal = rate->value(); + offsetVal = offset->value(); + } + +//--------------------------------------------------------- +// exec +//--------------------------------------------------------- + +int GateTime::exec() + { + rangeGroup->button(range)->setChecked(true); + rate->setValue(rateVal); + offset->setValue(offsetVal); + + return QDialog::exec(); + } + + +void GateTime::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "rate") + rateVal=xml.parseInt(); + else if (tag == "offset") + offsetVal=xml.parseInt(); + else + xml.unknown("ModLen"); + break; + + case Xml::TagEnd: + if (tag == "mod_len") + return; + + default: + break; + } + } +} + +void GateTime::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "mod_len"); + xml.intTag(level, "range", range); + xml.intTag(level, "offset", offsetVal); + xml.intTag(level, "rate", rateVal); + xml.tag(level, "/mod_len"); +} diff --git a/muse2/muse/widgets/gatetime.h b/muse2/muse/widgets/function_dialogs/gatetime.h index dcb1827c..d2555872 100644 --- a/muse2/muse/widgets/gatetime.h +++ b/muse2/muse/widgets/function_dialogs/gatetime.h @@ -12,28 +12,35 @@ class QButtonGroup; class QDialog; +class Xml; //--------------------------------------------------------- // GateTime //--------------------------------------------------------- class GateTime : public QDialog, public Ui::GateTimeBase { + private: Q_OBJECT - int _range; - int _rateVal; - int _offsetVal; QButtonGroup *rangeGroup; protected slots: void accept(); + void pullValues(); public: GateTime(QWidget* parent=0); - void setRange(int id); - int range() const { return _range; } - int rateVal() const { return _rateVal; } - int offsetVal() const { return _offsetVal; } + + int range; + int rateVal; + int offsetVal; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); }; #endif diff --git a/muse2/muse/widgets/gatetimebase.ui b/muse2/muse/widgets/function_dialogs/gatetimebase.ui index babf5f02..e804de17 100644 --- a/muse2/muse/widgets/gatetimebase.ui +++ b/muse2/muse/widgets/function_dialogs/gatetimebase.ui @@ -11,7 +11,7 @@ </rect> </property> <property name="windowTitle"> - <string>MusE: Modify Gate Time</string> + <string>MusE: Modify Note Length</string> </property> <layout class="QVBoxLayout"> <property name="spacing"> @@ -59,7 +59,7 @@ <item> <widget class="QRadioButton" name="sloopButton"> <property name="text"> - <string>Selected & Looped</string> + <string>Selected Looped</string> </property> </widget> </item> @@ -104,7 +104,7 @@ <string>%</string> </property> <property name="maximum"> - <number>200</number> + <number>1000</number> </property> <property name="value"> <number>100</number> @@ -124,6 +124,13 @@ </property> </widget> </item> + <item row="2" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>lenNew = (lenOld * rate) + offset</string> + </property> + </widget> + </item> </layout> </widget> </item> diff --git a/muse2/muse/widgets/function_dialogs/legato.cpp b/muse2/muse/widgets/function_dialogs/legato.cpp new file mode 100644 index 00000000..0a181106 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/legato.cpp @@ -0,0 +1,88 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: legato.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "legato.h" +#include "xml.h" + +Legato::Legato(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void Legato::pull_values() +{ + range = range_group->checkedId(); + min_len = len_spinbox->value(); + allow_shortening = allow_shorten_checkbox->isChecked(); +} + +void Legato::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Legato::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + len_spinbox->setValue(min_len); + allow_shorten_checkbox->setChecked(allow_shortening); + + return QDialog::exec(); +} + +void Legato::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "min_len") + min_len=xml.parseInt(); + else if (tag == "allow_shortening") + allow_shortening=xml.parseInt(); + else + xml.unknown("Legato"); + break; + + case Xml::TagEnd: + if (tag == "legato") + return; + + default: + break; + } + } +} + +void Legato::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "legato"); + xml.intTag(level, "range", range); + xml.intTag(level, "min_len", min_len); + xml.intTag(level, "allow_shortening", allow_shortening); + xml.tag(level, "/legato"); +} diff --git a/muse2/muse/widgets/function_dialogs/legato.h b/muse2/muse/widgets/function_dialogs/legato.h new file mode 100644 index 00000000..80b371ca --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/legato.h @@ -0,0 +1,42 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: legato.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __LEGATO_H__ +#define __LEGATO_H__ + +#include "ui_legatobase.h" + +class QButtonGroup; +class Xml; + +class Legato : public QDialog, public Ui::LegatoBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Legato(QWidget* parent = 0); + + int range; + int min_len; + bool allow_shortening; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/transposebase.ui b/muse2/muse/widgets/function_dialogs/legatobase.ui index 63ac74a6..7bc406df 100644 --- a/muse2/muse/widgets/transposebase.ui +++ b/muse2/muse/widgets/function_dialogs/legatobase.ui @@ -1,19 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>TransposeDialogBase</class> - <widget class="QDialog" name="TransposeDialogBase"> + <class>LegatoBase</class> + <widget class="QDialog" name="LegatoBase"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>289</width> - <height>340</height> + <width>275</width> + <height>289</height> </rect> </property> <property name="windowTitle"> - <string>MusE: Midi Transpose</string> + <string>MusE: Legato</string> </property> - <layout class="QVBoxLayout"> + <layout class="QVBoxLayout" name="verticalLayout_2"> <property name="spacing"> <number>6</number> </property> @@ -21,11 +24,11 @@ <number>11</number> </property> <item> - <widget class="QGroupBox" name="GroupBox1"> + <widget class="QGroupBox" name="rangeBox"> <property name="title"> - <string>Value</string> + <string>Range</string> </property> - <layout class="QVBoxLayout"> + <layout class="QVBoxLayout" name="verticalLayout"> <property name="spacing"> <number>6</number> </property> @@ -33,63 +36,16 @@ <number>11</number> </property> <item> - <layout class="QHBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>0</number> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> </property> - <item> - <widget class="QSpinBox" name="delta"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <number>-99</number> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="TextLabel1"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>halftones</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - </layout> + </widget> </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="ButtonBox1"> - <property name="title"> - <string>Time</string> - </property> - <layout class="QVBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>11</number> - </property> <item> - <widget class="QRadioButton" name="time_all"> + <widget class="QRadioButton" name="selected_events_button"> <property name="text"> - <string>all</string> + <string>Selected Events</string> </property> <property name="checked"> <bool>true</bool> @@ -97,9 +53,16 @@ </widget> </item> <item> - <widget class="QRadioButton" name="time_selected"> + <widget class="QRadioButton" name="looped_events_button"> <property name="text"> - <string>between markers</string> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> </property> </widget> </item> @@ -107,48 +70,90 @@ </widget> </item> <item> - <widget class="QGroupBox" name="ButtonBox2"> + <widget class="QGroupBox" name="groupBox_2"> <property name="title"> - <string>Parts</string> + <string>Settings</string> </property> - <layout class="QVBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> <property name="margin"> <number>11</number> </property> - <item> - <widget class="QRadioButton" name="parts_all"> - <property name="text"> - <string>all</string> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="1"> + <widget class="QSpinBox" name="len_spinbox"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="checked"> + <property name="accelerated"> <bool>true</bool> </property> + <property name="suffix"> + <string> ticks</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + <property name="value"> + <number>0</number> + </property> </widget> </item> - <item> - <widget class="QRadioButton" name="parts_selected"> - <property name="windowTitle"> - <string/> - </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> <property name="text"> - <string>all in selected tracks</string> + <string>Minimum Length</string> </property> </widget> </item> + <item row="1" column="0" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Allow shortening notes</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="allow_shorten_checkbox"> + <property name="layoutDirection"> + <enum>Qt::RightToLeft</enum> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> </item> <item> - <layout class="QHBoxLayout"> + <layout class="QHBoxLayout" name="horizontalLayout"> <property name="spacing"> <number>6</number> </property> - <property name="margin"> - <number>0</number> - </property> <item> <spacer name="Spacer1"> <property name="orientation"> @@ -195,7 +200,7 @@ <connection> <sender>okButton</sender> <signal>clicked()</signal> - <receiver>TransposeDialogBase</receiver> + <receiver>LegatoBase</receiver> <slot>accept()</slot> <hints> <hint type="sourcelabel"> @@ -211,7 +216,7 @@ <connection> <sender>cancelButton</sender> <signal>clicked()</signal> - <receiver>TransposeDialogBase</receiver> + <receiver>LegatoBase</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel"> diff --git a/muse2/muse/widgets/function_dialogs/move.cpp b/muse2/muse/widgets/function_dialogs/move.cpp new file mode 100644 index 00000000..2ce6cb05 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/move.cpp @@ -0,0 +1,84 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: move.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "move.h" +#include "xml.h" + +Move::Move(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void Move::pull_values() +{ + range = range_group->checkedId(); + amount = amount_spinbox->value(); +} + +void Move::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Move::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + amount_spinbox->setValue(amount); + + return QDialog::exec(); +} + + +void Move::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "amount") + amount=xml.parseInt(); + else + xml.unknown("Move"); + break; + + case Xml::TagEnd: + if (tag == "move") + return; + + default: + break; + } + } +} + +void Move::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "move"); + xml.intTag(level, "range", range); + xml.intTag(level, "amount", amount); + xml.tag(level, "/move"); +} diff --git a/muse2/muse/widgets/function_dialogs/move.h b/muse2/muse/widgets/function_dialogs/move.h new file mode 100644 index 00000000..4c90a922 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/move.h @@ -0,0 +1,41 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: move.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __MOVE_H__ +#define __MOVE_H__ + +#include "ui_movebase.h" + +class QButtonGroup; +class Xml; + +class Move : public QDialog, public Ui::MoveBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Move(QWidget* parent = 0); + + int range; + int amount; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/movebase.ui b/muse2/muse/widgets/function_dialogs/movebase.ui new file mode 100644 index 00000000..a8825dd5 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/movebase.ui @@ -0,0 +1,203 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MoveBase</class> + <widget class="QDialog" name="MoveBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>264</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Move Notes</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_events_button"> + <property name="text"> + <string>Selected Events</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Value</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel3"> + <property name="text"> + <string>Move by</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="amount_spinbox"> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="suffix"> + <string> ticks</string> + </property> + <property name="minimum"> + <number>-9999999</number> + </property> + <property name="maximum"> + <number>9999999</number> + </property> + <property name="singleStep"> + <number>386</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>MoveBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>MoveBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/quantbase.ui b/muse2/muse/widgets/function_dialogs/quantbase.ui new file mode 100644 index 00000000..6a88c86f --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/quantbase.ui @@ -0,0 +1,308 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QuantBase</class> + <widget class="QDialog" name="QuantBase"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>279</width> + <height>486</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Quantize</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_events_button"> + <property name="text"> + <string>Selected Events</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Values</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel3"> + <property name="text"> + <string>Strength:</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="strength_spinbox"> + <property name="suffix"> + <string>%</string> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>80</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="TextLabel4"> + <property name="text"> + <string>Threshold (ticks):</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="threshold_spinbox"> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Quantize Len</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QCheckBox" name="len_checkbox"> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Raster</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="raster_combobox"> + <property name="editable"> + <bool>false</bool> + </property> + <property name="currentIndex"> + <number>3</number> + </property> + <property name="frame"> + <bool>true</bool> + </property> + <item> + <property name="text"> + <string>Whole</string> + </property> + </item> + <item> + <property name="text"> + <string>Half</string> + </property> + </item> + <item> + <property name="text"> + <string>Quarter</string> + </property> + </item> + <item> + <property name="text"> + <string>8th</string> + </property> + </item> + <item> + <property name="text"> + <string>16th</string> + </property> + </item> + <item> + <property name="text"> + <string>32th</string> + </property> + </item> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Swing:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QSpinBox" name="swing_spinbox"> + <property name="minimum"> + <number>-99</number> + </property> + </widget> + </item> + <item row="5" column="0" colspan="2"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>If the proposed change in tick or length is smaller than threshold, nothing is done. +If swing=0, this is normal +If swing is 33, you get a 2:1-rhythm. +If swing is -33, you get a 1:2-rhythm.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="ok_button"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancel_button"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>ok_button</sender> + <signal>clicked()</signal> + <receiver>QuantBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancel_button</sender> + <signal>clicked()</signal> + <receiver>QuantBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/quantize.cpp b/muse2/muse/widgets/function_dialogs/quantize.cpp new file mode 100644 index 00000000..111087c2 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/quantize.cpp @@ -0,0 +1,103 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: quantize.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "quantize.h" +#include "xml.h" + +Quantize::Quantize(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void Quantize::pull_values() +{ + range = range_group->checkedId(); + strength = strength_spinbox->value(); + threshold = threshold_spinbox->value(); + raster_power2 = raster_combobox->currentIndex(); + quant_len = len_checkbox->isChecked(); + swing = swing_spinbox->value(); +} + +void Quantize::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Quantize::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + strength_spinbox->setValue(strength); + threshold_spinbox->setValue(threshold); + raster_combobox->setCurrentIndex(raster_power2); + len_checkbox->setChecked(quant_len); + swing_spinbox->setValue(swing); + + return QDialog::exec(); +} + +void Quantize::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "strength") + strength=xml.parseInt(); + else if (tag == "threshold") + threshold=xml.parseInt(); + else if (tag == "raster") + raster_power2=xml.parseInt(); + else if (tag == "swing") + swing=xml.parseInt(); + else if (tag == "quant_len") + quant_len=xml.parseInt(); + else + xml.unknown("Quantize"); + break; + + case Xml::TagEnd: + if (tag == "quantize") + return; + + default: + break; + } + } +} + +void Quantize::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "quantize"); + xml.intTag(level, "range", range); + xml.intTag(level, "strength", strength); + xml.intTag(level, "threshold", threshold); + xml.intTag(level, "raster", raster_power2); + xml.intTag(level, "swing", swing); + xml.intTag(level, "quant_len", quant_len); + xml.tag(level, "/quantize"); +} diff --git a/muse2/muse/widgets/function_dialogs/quantize.h b/muse2/muse/widgets/function_dialogs/quantize.h new file mode 100644 index 00000000..399e2545 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/quantize.h @@ -0,0 +1,45 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: quantize.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __QUANTIZE_H__ +#define __QUANTIZE_H__ + +#include "ui_quantbase.h" + +class QButtonGroup; +class Xml; + +class Quantize : public QDialog, public Ui::QuantBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Quantize(QWidget* parent = 0); + + int range; + int strength; + int threshold; + int raster_power2; + int swing; + bool quant_len; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/remove.cpp b/muse2/muse/widgets/function_dialogs/remove.cpp new file mode 100644 index 00000000..4a875135 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/remove.cpp @@ -0,0 +1,98 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: remove.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "remove.h" +#include "xml.h" + +Remove::Remove(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void Remove::pull_values() +{ + range = range_group->checkedId(); + len_thres_used=len_checkbox->isChecked(); + len_threshold=len_spinbox->value(); + velo_thres_used=velo_checkbox->isChecked(); + velo_threshold=velo_spinbox->value(); +} + +void Remove::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Remove::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + len_checkbox->setChecked(len_thres_used); + len_spinbox->setValue(len_threshold); + velo_checkbox->setChecked(velo_thres_used); + velo_spinbox->setValue(velo_threshold); + + return QDialog::exec(); +} + +void Remove::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "velo_threshold") + velo_threshold=xml.parseInt(); + else if (tag == "velo_thres_used") + velo_thres_used=xml.parseInt(); + else if (tag == "len_threshold") + len_threshold=xml.parseInt(); + else if (tag == "len_thres_used") + len_thres_used=xml.parseInt(); + else + xml.unknown("Erase"); + break; + + case Xml::TagEnd: + if (tag == "erase") + return; + + default: + break; + } + } +} + +void Remove::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "erase"); + xml.intTag(level, "range", range); + xml.intTag(level, "velo_threshold", velo_threshold); + xml.intTag(level, "velo_thres_used", velo_thres_used); + xml.intTag(level, "len_threshold", len_threshold); + xml.intTag(level, "len_thres_used", len_thres_used); + xml.tag(level, "/erase"); +} diff --git a/muse2/muse/widgets/function_dialogs/remove.h b/muse2/muse/widgets/function_dialogs/remove.h new file mode 100644 index 00000000..4c1a91e9 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/remove.h @@ -0,0 +1,44 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: remove.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __REMOVE_H__ +#define __REMOVE_H__ + +#include "ui_removebase.h" + +class QButtonGroup; +class Xml; + +class Remove : public QDialog, public Ui::RemoveBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Remove(QWidget* parent = 0); + + int range; + int velo_threshold; + bool velo_thres_used; + int len_threshold; + bool len_thres_used; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/removebase.ui b/muse2/muse/widgets/function_dialogs/removebase.ui new file mode 100644 index 00000000..79d541cc --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/removebase.ui @@ -0,0 +1,280 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>RemoveBase</class> + <widget class="QDialog" name="RemoveBase"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>443</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Erase Notes</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_events_button"> + <property name="text"> + <string>Selected Events</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Thresholds</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="1"> + <widget class="QSpinBox" name="velo_spinbox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="suffix"> + <string/> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>127</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + <property name="value"> + <number>16</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="len_spinbox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> ticks</string> + </property> + <property name="maximum"> + <number>10000</number> + </property> + <property name="value"> + <number>12</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QCheckBox" name="velo_checkbox"> + <property name="text"> + <string>Velocity</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="len_checkbox"> + <property name="text"> + <string>Length</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:7px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If nothing is checked, everything is removed.</p> +<p style=" margin-top:0px; margin-bottom:7px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If velocity is checked, only notes with velo &lt; threshold are removed.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If both are checked, notes with velo &lt; threshold OR with length &lt; threshold are removed.</p></body></html></string> + </property> + <property name="textFormat"> + <enum>Qt::AutoText</enum> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>RemoveBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>RemoveBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>velo_checkbox</sender> + <signal>toggled(bool)</signal> + <receiver>velo_spinbox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>83</x> + <y>192</y> + </hint> + <hint type="destinationlabel"> + <x>198</x> + <y>193</y> + </hint> + </hints> + </connection> + <connection> + <sender>len_checkbox</sender> + <signal>toggled(bool)</signal> + <receiver>len_spinbox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>83</x> + <y>221</y> + </hint> + <hint type="destinationlabel"> + <x>198</x> + <y>222</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/setlen.cpp b/muse2/muse/widgets/function_dialogs/setlen.cpp new file mode 100644 index 00000000..024cdd35 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/setlen.cpp @@ -0,0 +1,83 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: setlen.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "setlen.h" +#include "xml.h" + +Setlen::Setlen(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void Setlen::pull_values() +{ + range = range_group->checkedId(); + len = len_spinbox->value(); +} + +void Setlen::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Setlen::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + len_spinbox->setValue(len); + + return QDialog::exec(); +} + +void Setlen::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "len") + len=xml.parseInt(); + else + xml.unknown("SetLen"); + break; + + case Xml::TagEnd: + if (tag == "setlen") + return; + + default: + break; + } + } +} + +void Setlen::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "setlen"); + xml.intTag(level, "range", range); + xml.intTag(level, "len", len); + xml.tag(level, "/setlen"); +} diff --git a/muse2/muse/widgets/function_dialogs/setlen.h b/muse2/muse/widgets/function_dialogs/setlen.h new file mode 100644 index 00000000..ad66a38b --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/setlen.h @@ -0,0 +1,41 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: setlen.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __SETLEN_H__ +#define __SETLEN_H__ + +#include "ui_setlenbase.h" + +class QButtonGroup; +class Xml; + +class Setlen : public QDialog, public Ui::SetlenBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Setlen(QWidget* parent = 0); + + int range; + int len; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/setlenbase.ui b/muse2/muse/widgets/function_dialogs/setlenbase.ui new file mode 100644 index 00000000..7d929716 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/setlenbase.ui @@ -0,0 +1,197 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SetlenBase</class> + <widget class="QDialog" name="SetlenBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>264</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Set Note Length</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_events_button"> + <property name="text"> + <string>Selected Events</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Value</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel3"> + <property name="text"> + <string>New length</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="len_spinbox"> + <property name="suffix"> + <string> ticks</string> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>SetlenBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>SetlenBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/transpose.cpp b/muse2/muse/widgets/function_dialogs/transpose.cpp new file mode 100644 index 00000000..b10c1249 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/transpose.cpp @@ -0,0 +1,83 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: transpose.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#include <QButtonGroup> +#include "transpose.h" +#include "xml.h" + +Transpose::Transpose(QWidget* parent) + : QDialog(parent) +{ + setupUi(this); + range_group = new QButtonGroup; + range_group->addButton(all_events_button,0); + range_group->addButton(selected_events_button,1); + range_group->addButton(looped_events_button,2); + range_group->addButton(selected_looped_button,3); + + pull_values(); +} + +void Transpose::pull_values() +{ + range = range_group->checkedId(); + amount = amount_spinbox->value(); +} + +void Transpose::accept() +{ + pull_values(); + QDialog::accept(); +} + +int Transpose::exec() +{ + if ((range < 0) || (range > 3)) range=0; + + range_group->button(range)->setChecked(true); + amount_spinbox->setValue(amount); + + return QDialog::exec(); +} + +void Transpose::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "amount") + amount=xml.parseInt(); + else + xml.unknown("Transpose"); + break; + + case Xml::TagEnd: + if (tag == "transpose") + return; + + default: + break; + } + } +} + +void Transpose::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "transpose"); + xml.intTag(level, "range", range); + xml.intTag(level, "amount", amount); + xml.tag(level, "/transpose"); +} diff --git a/muse2/muse/widgets/function_dialogs/transpose.h b/muse2/muse/widgets/function_dialogs/transpose.h new file mode 100644 index 00000000..97dd443e --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/transpose.h @@ -0,0 +1,41 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: transpose.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $ +// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//========================================================= + +#ifndef __TRANSPOSE_H__ +#define __TRANSPOSE_H__ + +#include "ui_transposebase.h" + +class QButtonGroup; +class Xml; + +class Transpose : public QDialog, public Ui::TransposeBase +{ + private: + Q_OBJECT + QButtonGroup* range_group; + + protected slots: + void accept(); + void pull_values(); + + public: + Transpose(QWidget* parent = 0); + + int range; + int amount; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); +}; + +#endif + diff --git a/muse2/muse/widgets/function_dialogs/transposebase.ui b/muse2/muse/widgets/function_dialogs/transposebase.ui new file mode 100644 index 00000000..c26f2ef9 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/transposebase.ui @@ -0,0 +1,203 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>TransposeBase</class> + <widget class="QDialog" name="TransposeBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>264</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Transpose</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QGroupBox" name="rangeBox"> + <property name="title"> + <string>Range</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QRadioButton" name="all_events_button"> + <property name="text"> + <string>All Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_events_button"> + <property name="text"> + <string>Selected Events</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="looped_events_button"> + <property name="text"> + <string>Looped Events</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selected_looped_button"> + <property name="text"> + <string>Selected Looped</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Value</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel3"> + <property name="text"> + <string>Halftone-steps</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="amount_spinbox"> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="suffix"> + <string/> + </property> + <property name="minimum"> + <number>-127</number> + </property> + <property name="maximum"> + <number>127</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <spacer name="Spacer1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>TransposeBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>TransposeBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/muse2/muse/widgets/function_dialogs/velocity.cpp b/muse2/muse/widgets/function_dialogs/velocity.cpp new file mode 100644 index 00000000..ec625489 --- /dev/null +++ b/muse2/muse/widgets/function_dialogs/velocity.cpp @@ -0,0 +1,102 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: velocity.cpp,v 1.1.1.1 2003/10/27 18:55:04 wschweer Exp $ +// (C) Copyright 2001 Werner Schweer (ws@seh.de) +//========================================================= + +#include <QButtonGroup> +#include "velocity.h" +#include "xml.h" + +//--------------------------------------------------------- +// Velocity +//--------------------------------------------------------- + +Velocity::Velocity(QWidget* parent) + : QDialog(parent) + { + setupUi(this); + rangeGroup = new QButtonGroup; + rangeGroup->addButton(allEvents,0); + rangeGroup->addButton(selectedEvents,1); + rangeGroup->addButton(loopedEvents,2); + rangeGroup->addButton(selectedLooped,3); + + pullValues(); + } + +//--------------------------------------------------------- +// accept +//--------------------------------------------------------- + +void Velocity::accept() + { + pullValues(); + QDialog::accept(); + } + +//--------------------------------------------------------- +// pullValues +//--------------------------------------------------------- + +void Velocity::pullValues() + { + range = rangeGroup->checkedId(); + rateVal = rate->value(); + offsetVal = offset->value(); + } + +//--------------------------------------------------------- +// exec +//--------------------------------------------------------- + +int Velocity::exec() + { + rangeGroup->button(range)->setChecked(true); + rate->setValue(rateVal); + offset->setValue(offsetVal); + + return QDialog::exec(); + } + +void Velocity::read_configuration(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "range") + range=xml.parseInt(); + else if (tag == "rate") + rateVal=xml.parseInt(); + else if (tag == "offset") + offsetVal=xml.parseInt(); + else + xml.unknown("ModVelo"); + break; + + case Xml::TagEnd: + if (tag == "mod_velo") + return; + + default: + break; + } + } +} + +void Velocity::write_configuration(int level, Xml& xml) +{ + xml.tag(level++, "mod_velo"); + xml.intTag(level, "range", range); + xml.intTag(level, "offset", offsetVal); + xml.intTag(level, "rate", rateVal); + xml.tag(level, "/mod_velo"); +} diff --git a/muse2/muse/widgets/velocity.h b/muse2/muse/widgets/function_dialogs/velocity.h index cf5b2779..cbea4e22 100644 --- a/muse2/muse/widgets/velocity.h +++ b/muse2/muse/widgets/function_dialogs/velocity.h @@ -11,28 +11,34 @@ #include "ui_velocitybase.h" class QButtonGroup; +class Xml; //--------------------------------------------------------- // Velocity //--------------------------------------------------------- class Velocity : public QDialog, public Ui::VelocityBase { - int _range; - int _rateVal; - int _offsetVal; - + private: Q_OBJECT QButtonGroup* rangeGroup; protected slots: void accept(); + void pullValues(); public: - Velocity(QDialog* parent = 0); - void setRange(int id); - int range() const { return _range; } - int rateVal() const { return _rateVal; } - int offsetVal() const { return _offsetVal; } + Velocity(QWidget* parent = 0); + + int range; + int rateVal; + int offsetVal; + + void read_configuration(Xml& xml); + void write_configuration(int level, Xml& xml); + + + public slots: + int exec(); }; #endif diff --git a/muse2/muse/widgets/velocitybase.ui b/muse2/muse/widgets/function_dialogs/velocitybase.ui index 1e386e11..40fe625f 100644 --- a/muse2/muse/widgets/velocitybase.ui +++ b/muse2/muse/widgets/function_dialogs/velocitybase.ui @@ -59,7 +59,7 @@ <item> <widget class="QRadioButton" name="selectedLooped"> <property name="text"> - <string>Selected & Looped</string> + <string>Selected Looped</string> </property> </widget> </item> @@ -114,7 +114,7 @@ <item row="1" column="1"> <widget class="QSpinBox" name="offset"> <property name="minimum"> - <number>1</number> + <number>-127</number> </property> <property name="maximum"> <number>127</number> @@ -122,6 +122,16 @@ <property name="singleStep"> <number>1</number> </property> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>veloNew = (veloOld * rate) + offset</string> + </property> </widget> </item> </layout> diff --git a/muse2/muse/widgets/gatetime.cpp b/muse2/muse/widgets/gatetime.cpp deleted file mode 100644 index f1804c35..00000000 --- a/muse2/muse/widgets/gatetime.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: gatetime.cpp,v 1.1.1.1 2003/10/27 18:54:37 wschweer Exp $ -// (C) Copyright 2001 Werner Schweer (ws@seh.de) -//========================================================= - -#include <QButtonGroup> -#include <QDialog> - -#include "gatetime.h" - -#include "song.h" - -//--------------------------------------------------------- -// GateTime -//--------------------------------------------------------- - -GateTime::GateTime(QWidget* parent) - : QDialog(parent) - { - setupUi(this); - rangeGroup = new QButtonGroup(rangeBox); - rangeGroup->addButton(allButton, 0); - rangeGroup->addButton(selButton, 1); - rangeGroup->addButton(loopButton, 2); - rangeGroup->addButton(sloopButton, 3); - rangeGroup->setExclusive(true); - } - -//--------------------------------------------------------- -// accept -//--------------------------------------------------------- - -void GateTime::accept() - { - _range = rangeGroup->checkedId(); - _rateVal = rate->value(); - _offsetVal = offset->value(); - QDialog::accept(); - } - -//--------------------------------------------------------- -// setRange -//--------------------------------------------------------- - -void GateTime::setRange(int id) - { - rangeGroup->button(id)->setChecked(true); - } - diff --git a/muse2/muse/widgets/header.cpp b/muse2/muse/widgets/header.cpp index 16cc374b..00cbd29c 100644 --- a/muse2/muse/widgets/header.cpp +++ b/muse2/muse/widgets/header.cpp @@ -7,46 +7,56 @@ #include "header.h" #include "xml.h" +#include "popupmenu.h" #include <QStringList> #include <QStandardItemModel> +#include <QMouseEvent> //--------------------------------------------------------- // readStatus //--------------------------------------------------------- void Header::readStatus(Xml& xml) - { - for (;;) { - Xml::Token token = xml.parse(); - const QString& tag = xml.s1(); - switch (token) { - case Xml::Error: - case Xml::End: - return; - case Xml::Text: - { - //QStringList l = QStringList::split(QString(" "), tag); - QStringList l = tag.split(QString(" "), QString::SkipEmptyParts); - int index = count() -1; - for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - int section = visualIndex((*it).toInt()); - moveSection(section, index); - --index; - } - } - break; - case Xml::TagStart: - xml.unknown("Header"); - break; - case Xml::TagEnd: - if (tag ==objectName()) - return; - default: - break; - } - } - } +{ + + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::Text: + { + //QStringList l = QStringList::split(QString(" "), tag); + QStringList l = tag.split(QString(" "), QString::SkipEmptyParts); + int index = count() -1; + for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + int logialIdx=abs((*it).toInt()); + bool isHidden = (*it).toInt() < 0 ? true:false; + int section = visualIndex(logialIdx); + setMovable(true); + moveSection(section, index); + if (isHidden) + hideSection(logialIdx); + else + showSection(logialIdx); + --index; + } + } + break; + case Xml::TagStart: + xml.unknown("Header"); + break; + case Xml::TagEnd: + if (tag ==objectName()) + return; + default: + break; + } + } +} //--------------------------------------------------------- // writeStatus @@ -57,8 +67,12 @@ void Header::writeStatus(int level, Xml& xml) const //xml.nput(level, "<%s> ", name()); xml.nput(level, "<%s> ", Xml::xmlString(objectName()).toLatin1().constData()); int n = count() - 1; - for (int i = n; i >= 0; --i) - xml.nput("%d ", logicalIndex(i)); + for (int i = n; i >= 0; --i) { + if (isSectionHidden(logicalIndex(i))) + xml.nput("%d ", -logicalIndex(i)); // hidden is stored as negative value + else + xml.nput("%d ", logicalIndex(i)); + } //xml.put("</%s>", name()); xml.put("</%s>", Xml::xmlString(objectName()).toLatin1().constData()); } @@ -73,8 +87,9 @@ Header::Header(QWidget* parent, const char* name) setObjectName(name); itemModel = new QStandardItemModel; setModel(itemModel); - //setResizeMode(QHeaderView::ResizeToContents); setDefaultSectionSize(30); + setStretchLastSection(true); + } //--------------------------------------------------------- @@ -86,7 +101,7 @@ void Header::setColumnLabel(const QString & text, int col, int width ) QStandardItem *sitem = new QStandardItem(text ); itemModel->setHorizontalHeaderItem(col, sitem); if (width > -1) - resizeSection(col, width); + resizeSection(col, width); } //--------------------------------------------------------- @@ -109,3 +124,37 @@ void Header::setWhatsThis(int col, const QString &text) item->setWhatsThis(text); } +void Header::mousePressEvent ( QMouseEvent * e ) +{ + if (e->button() == Qt::RightButton) { + + PopupMenu* p = new PopupMenu(); + p->disconnect(); + p->clear(); + p->setTitle(tr("Track Info Columns")); + QAction* act = 0; + + for(int i=1; i < count(); i++) { + act = p->addAction(itemModel->horizontalHeaderItem(logicalIndex(i))->text() + + "\t - "+ itemModel->horizontalHeaderItem(logicalIndex(i))->toolTip()); + + act->setCheckable(true); + act->setChecked(!isSectionHidden(logicalIndex(i))); + int data = logicalIndex(i); + act->setData(data); + } + connect(p, SIGNAL(triggered(QAction*)), SLOT(changeColumns(QAction*))); + p->exec(QCursor::pos()); + + delete p; + + } +} +void Header::changeColumns(QAction *a) +{ + int section = a->data().toInt(); + if (isSectionHidden(section)) + showSection(section); + else + hideSection(section); +} diff --git a/muse2/muse/widgets/header.h b/muse2/muse/widgets/header.h index 83680f8a..3e7b73a4 100644 --- a/muse2/muse/widgets/header.h +++ b/muse2/muse/widgets/header.h @@ -9,6 +9,7 @@ #define __HEADER_H__ #include <QHeaderView> +#include <QAction> class QStandardItemModel; @@ -26,6 +27,9 @@ class Header : public QHeaderView { void setColumnLabel( const QString & s, int col, int width = -1 ); void setToolTip(int col, const QString &text); void setWhatsThis(int col, const QString &text); + void mousePressEvent ( QMouseEvent * e ); + private slots: + void changeColumns(QAction* a); }; #endif diff --git a/muse2/muse/widgets/mtscale_flo.cpp b/muse2/muse/widgets/mtscale_flo.cpp new file mode 100644 index 00000000..e18a7d11 --- /dev/null +++ b/muse2/muse/widgets/mtscale_flo.cpp @@ -0,0 +1,325 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: mtscale_flo.cpp,v 1.8.2.7 2011/05/19 04:14:01 flo Exp $ +// (C) Copyright 1999 Werner Schweer (ws@seh.de) +//========================================================= + +#include <values.h> + +#include <QMouseEvent> +#include <QPainter> + +#include "mtscale_flo.h" +#include "song.h" +#include "icons.h" +#include "gconfig.h" +#include "scoreedit.h" + +//--------------------------------------------------------- +// MTScale +// Midi Time Scale +//--------------------------------------------------------- + +MTScaleFlo::MTScaleFlo(ScoreCanvas* parent_editor, QWidget* parent_widget) + : View(parent_widget, 1, 1) + { + setToolTip(tr("bar scale")); + pos[0] = song->cpos(); + pos[1] = song->lpos(); + pos[2] = song->rpos(); + button = Qt::NoButton; + setMouseTracking(true); + connect(song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(setPos(int, unsigned, bool))); + connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); + connect(song, SIGNAL(markerChanged(int)), SLOT(redraw())); + + parent=parent_editor; + + setFixedHeight(28); + setBg(QColor(0xe0, 0xe0, 0xe0)); + } + +//--------------------------------------------------------- +// songChanged +//--------------------------------------------------------- + +void MTScaleFlo::songChanged(int type) + { + if (type & (SC_SIG|SC_TEMPO)) + redraw(); + } + +//--------------------------------------------------------- +// setPos +//--------------------------------------------------------- + +void MTScaleFlo::setPos(int idx, unsigned val, bool) + { + if ((val == MAXINT) || (val == pos[idx])) + return; + + int opos = parent->tick_to_x(pos[idx] == MAXINT ? val : pos[idx]) + xoffset - xpos; + + pos[idx] = val; + +// if (isVisible()) +// redraw(); + if (isVisible()) { + + int tval = parent->tick_to_x(val) + xoffset - xpos; + int x = -9; + int w = 18; + + if (tval < 0) { // tval<0 occurs whenever the window is scrolled left, so I switched to signed int (ml) + redraw(); + } + else if (opos > tval) { + w += opos - tval; + x += tval; + } + else { + w += tval - opos; + x += opos; + } + redraw(QRect(x, 0, w, height())); + } + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void MTScaleFlo::mousePressEvent(QMouseEvent* event) + { + button = event->button(); + mouseMoveEvent(event); + } + +//--------------------------------------------------------- +// mouseReleaseEvent +//--------------------------------------------------------- + +void MTScaleFlo::mouseReleaseEvent(QMouseEvent*) + { + button = Qt::NoButton; + } + +//--------------------------------------------------------- +// mouseMoveEvent +//--------------------------------------------------------- + +void MTScaleFlo::mouseMoveEvent(QMouseEvent* event) + { + if (event->modifiers() & Qt::ShiftModifier ) + setCursor(QCursor(Qt::PointingHandCursor)); + else + setCursor(QCursor(Qt::ArrowCursor)); + + int tick = AL::sigmap.raster(parent->x_to_tick(event->x()-xoffset+xpos), parent->quant_ticks()); + if (tick<0) tick=0; + + int i; + switch (button) { + case Qt::LeftButton: + i = 0; + break; + case Qt::MidButton: + i = 1; + break; + case Qt::RightButton: + i = 2; + break; + default: + return; // if no button is pressed the function returns here + } + Pos p(tick, true); + + if(i== 0 && (event->modifiers() & Qt::ShiftModifier )) { // If shift +LMB we add a marker + Marker *alreadyExists = song->getMarkerAt(tick); + if (!alreadyExists) + song->addMarker(QString(""), tick, false); + } + else if (i== 2 && (event->modifiers() & Qt::ShiftModifier )) { // If shift +RMB we remove a marker + Marker *toRemove = song->getMarkerAt(tick); + if (toRemove) + song->removeMarker(toRemove); + else + printf("No marker to remove\n"); + } + else + song->setPos(i, p); // all other cases: relocating one of the locators + } + + + +//--------------------------------------------------------- +// draw +//--------------------------------------------------------- + +void MTScaleFlo::draw(QPainter& p, const QRect& r) + { + int x = r.x(); + int w = r.width(); + + x -= 20; + w += 40; // wg. Text + + //--------------------------------------------------- + // draw Marker + //--------------------------------------------------- + + int y = 12; + p.setPen(Qt::black); + p.setFont(config.fonts[4]); + p.drawLine(r.x(), y+1, r.x() + r.width(), y+1); + QRect tr(r); + tr.setHeight(12); + MarkerList* marker = song->marker(); + for (iMarker m = marker->begin(); m != marker->end(); ++m) { + + int xp = parent->tick_to_x(m->second.tick()) + xoffset - xpos; + if (xp > x+w) + break; + int xe = r.x() + r.width(); + iMarker mm = m; + ++mm; + if (mm != marker->end()) + xe = parent->tick_to_x(mm->first) + xoffset - xpos; + + QRect tr(xp, 0, xe-xp, 13); + + QRect wr = r.intersect(tr); + if(!wr.isEmpty()) + { + if (m->second.current()) + p.fillRect(wr, Qt::white); + + int x2; + if (mm != marker->end()) + x2 = parent->tick_to_x(mm->first) + xoffset - xpos; + else + x2 = xp+200; + + if(xp >= -32) + p.drawPixmap(xp, 0, *flagIconS); + + if(xp >= -1023) + { + QRect r = QRect(xp+10, 0, x2-xp, 12); + p.setPen(Qt::black); + p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter, m->second.name()); + } + + if(xp >= 0) + { + p.setPen(Qt::green); + p.drawLine(xp, y, xp, height()); + } + } + } + + //--------------------------------------------------- + // draw location marker + //--------------------------------------------------- + + int h = height()-12; + + for (int i = 0; i < 3; ++i) { + int xp = parent->tick_to_x(pos[i]) + xoffset - xpos; + if (xp >= x && xp < x+w) { + QPixmap* pm = markIcon[i]; + p.drawPixmap(xp - pm->width()/2, y-1, *pm); + } + } + + + //--------------------------------------------------- + // draw beats + //--------------------------------------------------- + + + p.setPen(Qt::black); + + unsigned ctick; + int bar1, bar2, beat; + unsigned tick; + + ctick = parent->x_to_tick(x - xoffset + xpos); + AL::sigmap.tickValues(ctick, &bar1, &beat, &tick); + AL::sigmap.tickValues(parent->x_to_tick(x+w - xoffset + xpos), &bar2, &beat, &tick); + + + int stick = AL::sigmap.bar2tick(bar1, 0, 0); + int ntick; + for (int bar = bar1; bar <= bar2; bar++, stick = ntick) { + ntick = AL::sigmap.bar2tick(bar+1, 0, 0); + int tpix = parent->delta_tick_to_delta_x(ntick - stick); + if (tpix < 64) { + // don�t show beats if measure is this small + int n = 1; + if (tpix < 32) + n = 2; + if (tpix <= 16) + n = 4; + if (tpix < 8) + n = 8; + if (tpix <= 4) + n = 16; + if (tpix <= 2) + n = 32; + if (bar % n) + continue; + p.setFont(config.fonts[3]); + int x = parent->tick_to_x(stick) + xoffset - xpos; + QString s; + s.setNum(bar + 1); + p.drawLine(x, y+1, x, y+1+h); +// QRect r = QRect(x+2, y, 0, h); + QRect r = QRect(x+2, y, 1000, h); + p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip, s); + } + else { + int z, n; + AL::sigmap.timesig(stick, z, n); + for (int beat = 0; beat < z; beat++) { + int xp = parent->tick_to_x(AL::sigmap.bar2tick(bar, beat, 0)) + xoffset - xpos; + QString s; + QRect r(xp+2, y, 1000, h); + int y1; + int num; + if (beat == 0) { + num = bar + 1; + y1 = y + 1; + p.setFont(config.fonts[3]); + } + else { + num = beat + 1; + y1 = y + 7; + p.setFont(config.fonts[1]); + r.setY(y+3); + } + s.setNum(num); + p.drawLine(xp, y1, xp, y+1+h); + p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip, s); + } + } + } + } + +void MTScaleFlo::set_xpos(int pos) +{ + xpos=pos; + redraw(); +} + +void MTScaleFlo::set_xoffset(int o) +{ + xoffset=o; + redraw(); +} + +void MTScaleFlo::pos_add_changed() +{ + redraw(); +} diff --git a/muse2/muse/widgets/mtscale_flo.h b/muse2/muse/widgets/mtscale_flo.h new file mode 100644 index 00000000..b7856207 --- /dev/null +++ b/muse2/muse/widgets/mtscale_flo.h @@ -0,0 +1,51 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: mtscale_flo.h,v 1.3 2011/05/19 22:27:06 flo Exp $ +// (C) Copyright 1999 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __MTSCALE_FLO_H__ +#define __MTSCALE_FLO_H__ + +#include "view.h" + + +class ScoreCanvas; + +//--------------------------------------------------------- +// MTScaleFlo +// scale for midi track +//--------------------------------------------------------- + +class MTScaleFlo : public View { + Q_OBJECT + unsigned pos[3]; + int button; + ScoreCanvas* parent; + int xpos; + int xoffset; + + private slots: + void songChanged(int); + + protected: + virtual void draw(QPainter&, const QRect&); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + + signals: + void timeChanged(unsigned); + + public slots: + void setPos(int, unsigned, bool); + void set_xpos(int); + void pos_add_changed(); + void set_xoffset(int); + + public: + MTScaleFlo(ScoreCanvas* parent_editor, QWidget* parent_widget); + }; +#endif + diff --git a/muse2/muse/widgets/tb1.cpp b/muse2/muse/widgets/tb1.cpp index 917e6ae2..bd8e94a2 100644 --- a/muse2/muse/widgets/tb1.cpp +++ b/muse2/muse/widgets/tb1.cpp @@ -33,27 +33,16 @@ static const char* rasterStrings[] = { QT_TRANSLATE_NOOP("@default", "Off"), "4pp", "7pp", "64.", "32.", "16.", "8.", "4.", "2.", "1." }; -static int quantTable[] = { - 1, 16, 32, 64, 128, 256, 512, 1024, - 1, 24, 48, 96, 192, 384, 768, 1536, - 1, 36, 72, 144, 288, 576, 1152, 2304 - }; - -static const char* quantStrings[] = { - QT_TRANSLATE_NOOP("@default", "Off"), "64T", "32T", "16T", "8T", "4T", "2T", "1T", - QT_TRANSLATE_NOOP("@default", "Off"), "64", "32", "16", "8", "4", "2", "1", - QT_TRANSLATE_NOOP("@default", "Off"), "64.", "32.", "16.", "8.", "4.", "2.", "1." - }; //--------------------------------------------------------- // genToolbar -// solo time pitch raster quant +// solo time pitch raster //--------------------------------------------------------- -Toolbar1::Toolbar1(QWidget* parent, int r, int q, bool sp) - : QToolBar(QString("Quant'n'Snap-tools"), parent) +Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) + : QToolBar(QString("Pos/Snap/Solo-tools"), parent) { - setObjectName("Quant'n'Snap-tools"); + setObjectName("Pos/Snap/Solo-tools"); pitch = 0; showPitch = sp; // ORCAN - FIXME: Check this: @@ -85,66 +74,34 @@ Toolbar1::Toolbar1(QWidget* parent, int r, int q, bool sp) } //--------------------------------------------------- - // Raster, Quant. + // Raster //--------------------------------------------------- raster = new LabelCombo(tr("Snap"), 0); - quant = new LabelCombo(tr("Quantize"), 0); rlist = new QTableWidget(10, 3); - qlist = new QTableWidget(8, 3); rlist->verticalHeader()->setDefaultSectionSize(22); rlist->horizontalHeader()->setDefaultSectionSize(32); rlist->setSelectionMode(QAbstractItemView::SingleSelection); rlist->verticalHeader()->hide(); rlist->horizontalHeader()->hide(); - qlist->verticalHeader()->setDefaultSectionSize(22); - qlist->horizontalHeader()->setDefaultSectionSize(32); - qlist->setSelectionMode(QAbstractItemView::SingleSelection); - qlist->verticalHeader()->hide(); - qlist->horizontalHeader()->hide(); rlist->setMinimumWidth(96); - qlist->setMinimumWidth(96); raster->setView(rlist); - quant->setView(qlist); for (int j = 0; j < 3; j++) for (int i = 0; i < 10; i++) rlist->setItem(i, j, new QTableWidgetItem(tr(rasterStrings[i + j * 10]))); - for (int j = 0; j < 3; j++) - for (int i = 0; i < 8; i++) - qlist->setItem(i, j, new QTableWidgetItem(tr(quantStrings[i + j * 8]))); setRaster(r); - setQuant(q); addWidget(raster); - addWidget(quant); // FIXME: Not working right. raster->setFixedHeight(38); - quant->setFixedHeight(38); - //--------------------------------------------------- - // To Menu - //--------------------------------------------------- - - addWidget(new QLabel(tr("To"))); - QComboBox* toList = new QComboBox; - toList->setFixedHeight(22); - toList->insertItem(0, tr("All Events")); - toList->insertItem(CMD_RANGE_LOOP, tr("Looped Ev.")); - toList->insertItem(CMD_RANGE_SELECTED, tr("Selected Ev.")); - toList->insertItem(CMD_RANGE_LOOP | CMD_RANGE_SELECTED, tr("Looped+Sel.")); - addWidget(toList); - connect(raster, SIGNAL(activated(int)), SLOT(_rasterChanged(int))); - connect(quant, SIGNAL(activated(int)), SLOT(_quantChanged(int))); - //connect(rlist, SIGNAL(cellClicked(int,int)), SLOT(_rasterChanged(int, int))); - //connect(qlist, SIGNAL(cellClicked(int,int)), SLOT(_quantChanged(int,int))); - connect(toList, SIGNAL(activated(int)), SIGNAL(toChanged(int))); connect(solo, SIGNAL(toggled(bool)), SIGNAL(soloChanged(bool))); pos->setEnabled(false); } @@ -160,16 +117,6 @@ void Toolbar1::_rasterChanged(int /*i*/) //emit rasterChanged(rasterTable[r + c * 10]); } -//--------------------------------------------------------- -// quantChanged -//--------------------------------------------------------- - -void Toolbar1::_quantChanged(int /*i*/) -//void Toolbar1::_quantChanged(int r, int c) - { - emit quantChanged(quantTable[qlist->currentRow() + qlist->currentColumn() * 8]); - //emit quantChanged(quantTable[r + c * 8]); - } //--------------------------------------------------------- // setPitch @@ -226,22 +173,6 @@ void Toolbar1::setRaster(int val) } //--------------------------------------------------------- -// setQuant -//--------------------------------------------------------- - -void Toolbar1::setQuant(int val) - { - for (unsigned i = 0; i < sizeof(quantTable)/sizeof(*quantTable); i++) { - if (val == quantTable[i]) { - quant->setCurrentIndex(i); - return; - } - } - printf("setQuant(%d) not defined\n", val); - quant->setCurrentIndex(0); - } - -//--------------------------------------------------------- // setSolo //--------------------------------------------------------- diff --git a/muse2/muse/widgets/tb1.h b/muse2/muse/widgets/tb1.h index fbed13b1..ff31593f 100644 --- a/muse2/muse/widgets/tb1.h +++ b/muse2/muse/widgets/tb1.h @@ -26,8 +26,6 @@ class Toolbar1 : public QToolBar { QToolButton* solo; PosLabel* pos; PitchLabel* pitch; - LabelCombo* quant; - QTableWidget* qlist; LabelCombo* raster; QTableWidget* rlist; bool showPitch; @@ -35,25 +33,21 @@ class Toolbar1 : public QToolBar { private slots: void _rasterChanged(int); - void _quantChanged(int); public slots: void setTime(unsigned); void setPitch(int); void setInt(int); void setRaster(int); - void setQuant(int); signals: void rasterChanged(int); - void quantChanged(int); void soloChanged(bool); - void toChanged(int); public: //Toolbar1(QMainWindow* parent = 0, int r=96, Toolbar1(QWidget* parent, int r=96, - int q=96, bool showPitch=true); + bool showPitch=true); void setSolo(bool val); void setPitchMode(bool flag); }; diff --git a/muse2/muse/widgets/velocity.cpp b/muse2/muse/widgets/velocity.cpp deleted file mode 100644 index 309beb4d..00000000 --- a/muse2/muse/widgets/velocity.cpp +++ /dev/null @@ -1,46 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: velocity.cpp,v 1.1.1.1 2003/10/27 18:55:04 wschweer Exp $ -// (C) Copyright 2001 Werner Schweer (ws@seh.de) -//========================================================= - -#include <QButtonGroup> -#include "velocity.h" - -//--------------------------------------------------------- -// Velocity -//--------------------------------------------------------- - -Velocity::Velocity(QDialog* parent) - : QDialog(parent) - { - setupUi(this); - rangeGroup = new QButtonGroup; - rangeGroup->addButton(allEvents,0); - rangeGroup->addButton(selectedEvents,1); - rangeGroup->addButton(loopedEvents,2); - rangeGroup->addButton(selectedLooped,3); - } - -//--------------------------------------------------------- -// accept -//--------------------------------------------------------- - -void Velocity::accept() - { - _range = rangeGroup->checkedId(); - _rateVal = rate->value(); - _offsetVal = offset->value(); - QDialog::accept(); - } - -//--------------------------------------------------------- -// setRange -//--------------------------------------------------------- - -void Velocity::setRange(int id) - { - rangeGroup->button(id)->setChecked(true); - } - |