From e9c43888de8601c940b428c3bc6012f2ffe9f68c Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Wed, 11 May 2011 12:38:56 +0000 Subject: implemented erasing notes with [delete] functions only indicate undo when something has really changed --- muse2/muse/functions.cpp | 199 +++++++++++++++++++++----------------- muse2/muse/functions.h | 1 + muse2/muse/midiedit/scoreedit.cpp | 21 +++- muse2/muse/midiedit/scoreedit.h | 1 + 4 files changed, 130 insertions(+), 92 deletions(-) diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 980a5103..6a3af374 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -54,6 +54,20 @@ bool is_relevant(const Event& event, const Part* part, int range) } } + +map get_events(const set& parts, int range) +{ + map events; + + for (set::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->second, *part)); + + return events; +} + + bool modify_notelen(const set& parts) { if (!gatetime_dialog->exec()) @@ -89,78 +103,72 @@ bool quantize_notes(const set& parts) void modify_velocity(const set& parts, int range, int rate, int offset) { - map events; - - for (set::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->second, *part)); - - - song->startUndo(); + map events = get_events(parts, range); - for (map::iterator it=events.begin(); it!=events.end(); it++) + if (!events.empty()) { - Event& event=*(it->first); - Part* part=it->second; + song->startUndo(); - int velo = event.velo(); + for (map::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; + 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); + 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); } - - song->endUndo(SC_EVENT_MODIFIED); } void modify_notelen(const set& parts, int range, int rate, int offset) { - map events; - - for (set::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->second, *part)); + map events = get_events(parts, range); - - song->startUndo(); - - for (map::iterator it=events.begin(); it!=events.end(); it++) + if (!events.empty()) { - Event& event=*(it->first); - Part* part=it->second; + song->startUndo(); + + for (map::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 + unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned - len = (len * rate) / 100; - len += offset; + 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); + 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); } - - song->endUndo(SC_EVENT_MODIFIED); } unsigned quantize_tick(unsigned tick, unsigned raster, int swing) @@ -187,51 +195,68 @@ unsigned quantize_tick(unsigned tick, unsigned raster, int swing) void quantize_notes(const set& parts, int range, int raster, int strength, int swing, int threshold) { - map events; - - for (set::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->second, *part)); - - - song->startUndo(); + map events = get_events(parts, range); - for (map::iterator it=events.begin(); it!=events.end(); it++) + if (!events.empty()) { - Event& event=*(it->first); - Part* part=it->second; + song->startUndo(); + + for (map::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; + 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; + 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; + unsigned len=event.lenTick(); - if (abs(len_diff) > threshold) - len = len + len_diff*strength/100; + unsigned end_tick = begin_tick + len; + int len_diff = quantize_tick(end_tick, raster, swing) - end_tick; + + if (abs(len_diff) > threshold) + len = len + len_diff*strength/100; - if (len <= 0) - len = 1; + if (len <= 0) + len = 1; - - if ( (event.lenTick() != len) || (event.tick() + part->tick() != begin_tick) ) - { - 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 ( (event.lenTick() != len) || (event.tick() + part->tick() != begin_tick) ) + { + 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); + } } + + song->endUndo(SC_EVENT_MODIFIED); } +} + +void erase_notes(const set& parts, int range) +{ + map events = get_events(parts, range); - song->endUndo(SC_EVENT_MODIFIED); + if (!events.empty()) + { + song->startUndo(); + + for (map::iterator it=events.begin(); it!=events.end(); it++) + { + Event& event=*(it->first); + Part* part=it->second; + + audio->msgDeleteEvent(event, part, false, false, false); + } + + song->endUndo(SC_EVENT_REMOVED); + } } diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h index a71230a4..03d0ba88 100644 --- a/muse2/muse/functions.h +++ b/muse2/muse/functions.h @@ -29,6 +29,7 @@ std::set partlist_to_set(PartList* pl); void modify_velocity(const std::set& parts, int range, int rate, int offset=0); void modify_notelen(const std::set& parts, int range, int rate, int offset=0); void quantize_notes(const std::set& parts, int range, int raster, int strength=100, int swing=0, int threshold=0); +void erase_notes(const std::set& parts, int range); //the below functions automatically open the dialog //they return true if you click "ok" and false if "abort" diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 4471f48e..02151227 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -3451,6 +3451,8 @@ void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) for (list::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(); } @@ -3937,7 +3939,15 @@ void ScoreCanvas::deselect_all() for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++) event->second.setSelected(false); - song_changed(SC_SELECTION); + 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() @@ -4027,12 +4037,9 @@ void staff_t::apply_lasso(QRect rect, set& already_processed) * between, for example, when a cis is tied to a des * * CURRENT TODO - * o use "DEL" for deleting all selected items * o let the user select the distance between staves, or do this * automatically? - * o update translations - * o remove ambiguous translation: "offset"="zeitversatz" - * this is ambigous in mod. note len and WRONG in mod. velo dialogs + * o don't indicate undo when only clicking on an item * * IMPORTANT TODO * o add a select-clef-toolbox for tracks @@ -4065,6 +4072,10 @@ void staff_t::apply_lasso(QRect rect, set& already_processed) * * * 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 diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 74bc0283..e46f408a 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -715,6 +715,7 @@ 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); -- cgit v1.2.3