implement deleting of sysex events

git-svn-id: svn://localhost/ardour2/branches/3.0@13238 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Hans Baier 2012-10-11 03:22:17 +00:00
parent 9707a0e827
commit 97c23848d7
9 changed files with 134 additions and 16 deletions

View File

@ -19,27 +19,27 @@ class CanvasFlag : public Group
{
public:
CanvasFlag (MidiRegionView& region,
Group& parent,
double height,
guint outline_color_rgba = 0xc0c0c0ff,
guint fill_color_rgba = 0x07070707,
double x = 0.0,
double y = 0.0);
Group& parent,
double height,
guint outline_color_rgba = 0xc0c0c0ff,
guint fill_color_rgba = 0x07070707,
double x = 0.0,
double y = 0.0);
virtual ~CanvasFlag();
virtual void set_text(const std::string& a_text);
virtual void set_height (double);
int width () const { return name_pixbuf_width + 10.0; }
int width () const { return name_pixbuf_width + 10.0; }
protected:
ArdourCanvas::Pixbuf* _name_pixbuf;
double _height;
guint _outline_color_rgba;
guint _fill_color_rgba;
MidiRegionView& _region;
int name_pixbuf_width;
int name_pixbuf_width;
private:
void delete_allocated_objects();

View File

@ -21,6 +21,7 @@
#include "ardour_ui.h"
#include "midi_region_view.h"
#include "canvas-sysex.h"
using namespace Gnome::Canvas;
@ -32,7 +33,8 @@ CanvasSysEx::CanvasSysEx(
string& text,
double height,
double x,
double y)
double y,
const ARDOUR::MidiModel::SysExPtr sysex)
: CanvasFlag(
region,
parent,
@ -40,7 +42,8 @@ CanvasSysEx::CanvasSysEx(
ARDOUR_UI::config()->canvasvar_MidiSysExOutline.get(),
ARDOUR_UI::config()->canvasvar_MidiSysExFill.get(),
x,
y)
y),
_sysex(sysex)
{
set_text(text);
}
@ -67,6 +70,29 @@ CanvasSysEx::on_event(GdkEvent* ev)
}
break;
case GDK_KEY_PRESS:
switch (ev->key.keyval) {
case GDK_Delete:
case GDK_BackSpace:
_region.delete_sysex (this);
break;
default:
break;
}
break;
case GDK_ENTER_NOTIFY:
grab_focus();
return true;
break;
case GDK_LEAVE_NOTIFY:
/* focus will transfer back via the enter-notify
* event sent to the midi region view.
*/
break;
default:
break;
}

View File

@ -23,6 +23,7 @@
#include <string>
#include "canvas-flag.h"
#include "ardour/midi_model.h"
class MidiRegionView;
@ -38,11 +39,17 @@ public:
std::string& text,
double height,
double x,
double y);
double y,
ARDOUR::MidiModel::SysExPtr sysex);
virtual ~CanvasSysEx();
const ARDOUR::MidiModel::SysExPtr sysex() const { return _sysex; }
virtual bool on_event(GdkEvent* ev);
private:
const ARDOUR::MidiModel::SysExPtr _sysex;
};
} // namespace Canvas

View File

@ -48,6 +48,7 @@
#include "canvas-hit.h"
#include "canvas-note.h"
#include "canvas_patch_change.h"
#include "canvas-sysex.h"
#include "debug.h"
#include "editor.h"
#include "editor_drag.h"
@ -1296,7 +1297,7 @@ MidiRegionView::display_sysexes()
double height = midi_stream_view()->contents_height();
boost::shared_ptr<CanvasSysEx> sysex = boost::shared_ptr<CanvasSysEx>(
new CanvasSysEx(*this, *_note_group, text, height, x, 1.0));
new CanvasSysEx(*this, *_note_group, text, height, x, 1.0, (*i)));
// Show unless message is beyond the region bounds
if (time - _region->start() >= _region->length() || time < _region->start()) {
@ -3752,6 +3753,18 @@ MidiRegionView::edit_patch_change (ArdourCanvas::CanvasPatchChange* pc)
change_patch_change (pc->patch(), d.patch ());
}
void
MidiRegionView::delete_sysex (CanvasSysEx* sysex)
{
cerr << "about to delete sysex " << sysex->sysex() << endl;
MidiModel::SysExDiffCommand* c = _model->new_sysex_diff_command (_("delete sysex"));
c->remove (sysex->sysex());
_model->apply_command (*trackview.session(), c);
_sys_exes.clear ();
display_sysexes();
}
void
MidiRegionView::show_verbose_cursor (boost::shared_ptr<NoteType> n) const

View File

@ -145,6 +145,8 @@ public:
void delete_patch_change (ArdourCanvas::CanvasPatchChange *);
void edit_patch_change (ArdourCanvas::CanvasPatchChange *);
void delete_sysex (ArdourCanvas::CanvasSysEx*);
/** Alter a given patch to be its predecessor in the MIDNAM file.
*/
void previous_patch (ArdourCanvas::CanvasPatchChange &);

View File

@ -152,6 +152,7 @@ public:
int set_state (const XMLNode&, int version);
XMLNode & get_state ();
void remove (SysExPtr sysex);
void operator() ();
void undo ();
@ -168,6 +169,8 @@ public:
typedef std::list<Change> ChangeList;
ChangeList _changes;
std::list<SysExPtr> _removed;
XMLNode & marshal_change (const Change &);
Change unmarshal_change (XMLNode *);
};

View File

@ -786,6 +786,10 @@ MidiModel::SysExDiffCommand::operator() ()
{
MidiModel::WriteLock lock (_model->edit_lock ());
for (list<SysExPtr>::iterator i = _removed.begin(); i != _removed.end(); ++i) {
_model->remove_sysex_unlocked (*i);
}
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
switch (i->property) {
case Time:
@ -803,6 +807,10 @@ MidiModel::SysExDiffCommand::undo ()
{
MidiModel::WriteLock lock (_model->edit_lock ());
for (list<SysExPtr>::iterator i = _removed.begin(); i != _removed.end(); ++i) {
_model->add_sysex_unlocked (*i);
}
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
switch (i->property) {
case Time:
@ -816,6 +824,12 @@ MidiModel::SysExDiffCommand::undo ()
_model->ContentsChanged(); /* EMIT SIGNAL */
}
void
MidiModel::SysExDiffCommand::remove (SysExPtr sysex)
{
_removed.push_back(sysex);
}
XMLNode&
MidiModel::SysExDiffCommand::marshal_change (const Change& change)
{

View File

@ -181,7 +181,16 @@ public:
void set_notes (const Sequence<Time>::Notes& n);
typedef std::vector< boost::shared_ptr< Event<Time> > > SysExes;
typedef boost::shared_ptr< Event<Time> > SysExPtr;
typedef boost::shared_ptr<const Event<Time> > constSysExPtr;
struct EarlierSysExComparator {
inline bool operator() (constSysExPtr a, constSysExPtr b) const {
return a->time() < b->time();
}
};
typedef std::multiset<SysExPtr, EarlierSysExComparator> SysExes;
inline SysExes& sysexes() { return _sysexes; }
inline const SysExes& sysexes() const { return _sysexes; }
@ -262,6 +271,7 @@ public:
typename Notes::const_iterator note_lower_bound (Time t) const;
typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const;
typename SysExes::const_iterator sysex_lower_bound (Time t) const;
bool control_to_midi_event(boost::shared_ptr< Event<Time> >& ev,
const ControlIterator& iter) const;
@ -279,6 +289,9 @@ public:
void add_patch_change_unlocked (const PatchChangePtr);
void remove_patch_change_unlocked (const constPatchChangePtr);
void add_sysex_unlocked (const SysExPtr);
void remove_sysex_unlocked (const SysExPtr);
uint8_t lowest_note() const { return _lowest_note; }
uint8_t highest_note() const { return _highest_note; }

View File

@ -494,7 +494,7 @@ Sequence<Time>::Sequence(const Sequence<Time>& other)
for (typename SysExes::const_iterator i = other._sysexes.begin(); i != other._sysexes.end(); ++i) {
boost::shared_ptr<Event<Time> > n (new Event<Time> (**i, true));
_sysexes.push_back (n);
_sysexes.insert (n);
}
for (typename PatchChanges::const_iterator i = other._patch_changes.begin(); i != other._patch_changes.end(); ++i) {
@ -788,6 +788,24 @@ Sequence<Time>::remove_patch_change_unlocked (const constPatchChangePtr p)
}
}
template<typename Time>
void
Sequence<Time>::remove_sysex_unlocked (const SysExPtr sysex)
{
typename Sequence<Time>::SysExes::iterator i = sysex_lower_bound (sysex->time ());
while (i != _sysexes.end() && (*i)->time() == sysex->time()) {
typename Sequence<Time>::SysExes::iterator tmp = i;
++tmp;
if (*i == sysex) {
_sysexes.erase (i);
}
i = tmp;
}
}
/** Append \a ev to model. NOT realtime safe.
*
* The timestamp of event is expected to be relative to
@ -984,7 +1002,7 @@ Sequence<Time>::append_sysex_unlocked(const MIDIEvent<Time>& ev, event_id_t /* e
boost::shared_ptr<MIDIEvent<Time> > event(new MIDIEvent<Time>(ev, true));
/* XXX sysex events should use IDs */
_sysexes.push_back(event);
_sysexes.insert(event);
}
template<typename Time>
@ -1011,6 +1029,17 @@ Sequence<Time>::add_patch_change_unlocked (PatchChangePtr p)
_patch_changes.insert (p);
}
template<typename Time>
void
Sequence<Time>::add_sysex_unlocked (SysExPtr s)
{
if (s->id () < 0) {
s->set_id (Evoral::next_event_id ());
}
_sysexes.insert (s);
}
template<typename Time>
bool
Sequence<Time>::contains (const NotePtr& note) const
@ -1105,6 +1134,17 @@ Sequence<Time>::patch_change_lower_bound (Time t) const
return i;
}
/** Return the earliest sysex with time >= t */
template<typename Time>
typename Sequence<Time>::SysExes::const_iterator
Sequence<Time>::sysex_lower_bound (Time t) const
{
SysExPtr search (new Event<Time> (0, t));
typename Sequence<Time>::SysExes::const_iterator i = _sysexes.lower_bound (search);
assert (i == _sysexes.end() || (*i)->time() >= t);
return i;
}
template<typename Time>
void
Sequence<Time>::get_notes (Notes& n, NoteOperator op, uint8_t val, int chan_mask) const