changeset 756:9cfcb2924ee3 tony_integration

Merge from branch tonioni
author Chris Cannam
date Wed, 02 Apr 2014 08:51:33 +0100
parents ad01e7d4a956 (current diff) 09e2677e34e7 (diff)
children 2cd6d2d17437
files view/Pane.cpp
diffstat 7 files changed, 277 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp	Wed Apr 02 08:50:18 2014 +0100
+++ b/layer/FlexiNoteLayer.cpp	Wed Apr 02 08:51:33 2014 +0100
@@ -1043,7 +1043,7 @@
     m_originalPoint = FlexiNote(m_editingPoint);
     
     if (m_editMode == RightBoundary) {
-        m_dragPointX =   v->getXForFrame(m_editingPoint.frame + m_editingPoint.duration);
+        m_dragPointX = v->getXForFrame(m_editingPoint.frame + m_editingPoint.duration);
     } else {
         m_dragPointX = v->getXForFrame(m_editingPoint.frame);
     }
@@ -1079,7 +1079,7 @@
             break;
         }
     }
-    std::cerr << "note frame: " << onset << ", left boundary: " << m_greatestLeftNeighbourFrame << ", right boundary: " << m_smallestRightNeighbourFrame << std::endl;
+    std::cerr << "editStart: mode is " << m_editMode << ", note frame: " << onset << ", left boundary: " << m_greatestLeftNeighbourFrame << ", right boundary: " << m_smallestRightNeighbourFrame << std::endl;
 }
 
 void
@@ -1214,39 +1214,55 @@
         return; 
     }
 
-    // MM: simpler declaration 
-    FlexiNote note(0);
-    if (!getPointToDrag(v, e->x(), e->y(), note)) return;
-
     long frame = v->getFrameForX(e->x());
 
-    int gap = 0; // MM: I prefer a gap of 0, but we can decide later
+    splitNotesAt(v, frame, e);
+}
+
+void
+FlexiNoteLayer::splitNotesAt(View *v, int frame)
+{
+    splitNotesAt(v, frame, 0);
+}
+
+void
+FlexiNoteLayer::splitNotesAt(View *v, int frame, QMouseEvent *e)
+{
+    FlexiNoteModel::PointList onPoints = m_model->getPoints(frame);
+    if (onPoints.empty()) return;
     
-    // MM: changed this a bit, to make it slightly clearer (// GF: nice changes!)
-    FlexiNote newNote1(note.frame, note.value, 
-                       frame - note.frame - gap, 
-                       note.level, note.label);
-    
-    FlexiNote newNote2(frame, note.value, 
-                       note.duration - newNote1.duration, 
-                       note.level, note.label);
-                       
-    if (m_intelligentActions) {
-        updateNoteValue(v,newNote1);
-        updateNoteValue(v,newNote2);
-    }
+    FlexiNote note(*onPoints.begin());
 
     FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
         (m_model, tr("Edit Point"));
     command->deletePoint(note);
-    if ((e->modifiers() & Qt::ShiftModifier)) {
-        finish(command);
-        return;
+
+    if (!e || !(e->modifiers() & Qt::ShiftModifier)) {
+
+        int gap = 0; // MM: I prefer a gap of 0, but we can decide later
+    
+        FlexiNote newNote1(note.frame, note.value, 
+                           frame - note.frame - gap, 
+                           note.level, note.label);
+    
+        FlexiNote newNote2(frame, note.value, 
+                           note.duration - newNote1.duration, 
+                           note.level, note.label);
+                       
+        if (m_intelligentActions) {
+            if (updateNoteValue(v, newNote1)) {
+                command->addPoint(newNote1);
+            }
+            if (updateNoteValue(v, newNote2)) {
+                command->addPoint(newNote2);
+            }
+        } else {
+            command->addPoint(newNote1);
+            command->addPoint(newNote2);
+        }
     }
-    command->addPoint(newNote1);
-    command->addPoint(newNote2);
+
     finish(command);
-    
 }
 
 void
@@ -1276,8 +1292,7 @@
     }
 
     if (!m_intelligentActions || 
-        m_model->getPoints(frame).empty() && duration > 0)
-    {
+        (m_model->getPoints(frame).empty() && duration > 0)) {
         FlexiNote newNote(frame, value, duration, 100, "new note");
         FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
             (m_model, tr("Add Point"));
@@ -1286,31 +1301,137 @@
     }
 }
 
+SparseTimeValueModel *
+FlexiNoteLayer::getAssociatedPitchModel(View *v) const
+{
+    // Better than we used to do, but still not very satisfactory
+
+    cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl;
+
+    for (int i = 0; i < v->getLayerCount(); ++i) {
+        Layer *layer = v->getLayer(i);
+        if (layer && !layer->isLayerDormant(v) && 
+            layer->getLayerPresentationName() != "candidate") {
+            cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
+            SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
+                (layer->getModel());
+            cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
+            if (model && model->getScaleUnits() == "Hz") {
+                cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl;
+                return model;
+            }
+        }
+    }
+    return 0;
+}
 
 void
+FlexiNoteLayer::snapSelectedNotesToPitchTrack(View *v, Selection s)
+{
+    if (!m_model) return;
+
+    FlexiNoteModel::PointList points =
+        m_model->getPoints(s.getStartFrame(), s.getEndFrame());
+
+    FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
+        (m_model, tr("Snap Notes"));
+
+    cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl;
+
+    for (FlexiNoteModel::PointList::iterator i = points.begin();
+         i != points.end(); ++i) {
+
+        FlexiNote note(*i);
+
+        cerr << "snapSelectedNotesToPitchTrack: looking at note from " << note.frame << " to " << note.frame + note.duration << endl;
+
+        if (!s.contains(note.frame) &&
+            !s.contains(note.frame + note.duration - 1)) {
+            continue;
+        }
+
+        FlexiNote newNote(note);
+
+        command->deletePoint(note);
+
+        if (updateNoteValue(v, newNote)) {
+            command->addPoint(newNote);
+        }
+    }
+    
+    finish(command);
+}
+
+void
+FlexiNoteLayer::mergeNotes(View *v, Selection s, bool inclusive)
+{
+    FlexiNoteModel::PointList points =
+        m_model->getPoints(s.getStartFrame(), s.getEndFrame());
+
+    FlexiNoteModel::PointList::iterator i = points.begin();
+    if (inclusive) {
+        while (i != points.end() && i->frame + i->duration < s.getStartFrame()) {
+            ++i;
+        }
+    } else {
+        while (i != points.end() && i->frame < s.getStartFrame()) {
+            ++i;
+        }
+    }
+        
+    if (i == points.end()) return;
+
+    FlexiNoteModel::EditCommand *command = 
+        new FlexiNoteModel::EditCommand(m_model, tr("Merge Notes"));
+
+    FlexiNote newNote(*i);
+
+    while (i != points.end()) {
+
+        if (inclusive) {
+            if (i->frame >= s.getEndFrame()) break;
+        } else {
+            if (i->frame + i->duration > s.getEndFrame()) break;
+        }
+
+        newNote.duration = i->frame + i->duration - newNote.frame;
+        command->deletePoint(*i);
+
+        ++i;
+    }
+
+    updateNoteValue(v, newNote);
+    command->addPoint(newNote);
+    finish(command);
+}
+
+bool
 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
 {
-    //GF: update the note value conforming the median of pitch values in the underlying note layer
-    Layer *layer = v->getLayer(1); // GF: !!! gross assumption about correct layer order
-    SparseTimeValueModel *model = 0;
-    if (layer && layer->getModel()) 
-        model = dynamic_cast<SparseTimeValueModel *>(layer->getModel());
-        
-    if (!model) return;
+    SparseTimeValueModel *model = getAssociatedPitchModel(v);
+    if (!model) return false;
         
     std::cerr << model->getTypeName() << std::endl;
 
-    SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration);
-    if (dataPoints.empty()) return;
+    SparseModel<TimeValuePoint>::PointList dataPoints =
+        model->getPoints(note.frame, note.frame + note.duration);
    
-    // std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
+    std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
    
+    if (dataPoints.empty()) return false;
+
     std::vector<float> pitchValues;
    
-    for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin(); 
-         i != dataPoints.end(); ++i) {
-        pitchValues.push_back((*i).value);
+    for (SparseModel<TimeValuePoint>::PointList::const_iterator i =
+             dataPoints.begin(); i != dataPoints.end(); ++i) {
+        if (i->frame >= note.frame &&
+            i->frame < note.frame + note.duration) {
+            pitchValues.push_back(i->value);
+        }
     }
+        
+    if (pitchValues.empty()) return false;
+
     sort(pitchValues.begin(), pitchValues.end());
     size_t size = pitchValues.size();
     double median;
@@ -1322,6 +1443,8 @@
     }
     
     note.value = median;
+
+    return true;
 }
 
 void 
--- a/layer/FlexiNoteLayer.h	Wed Apr 02 08:50:18 2014 +0100
+++ b/layer/FlexiNoteLayer.h	Wed Apr 02 08:51:33 2014 +0100
@@ -28,7 +28,7 @@
 
 class View;
 class QPainter;
-
+class SparseTimeValueModel;
 
 class FlexiNoteLayer : public SingleColourLayer,
                        public VerticalScaleLayer
@@ -78,6 +78,10 @@
     virtual bool paste(View *v, const Clipboard &from, int frameOffset,
                        bool interactive);
 
+    void splitNotesAt(View *v, int frame);
+    void snapSelectedNotesToPitchTrack(View *v, Selection s);
+    void mergeNotes(View *v, Selection s, bool inclusive);
+
     virtual const Model *getModel() const { return m_model; }
     void setModel(FlexiNoteModel *model);
 
@@ -169,7 +173,9 @@
     bool getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &) const;
     bool getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &) const;
     void getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const;
-    void updateNoteValue(View *v, FlexiNoteModel::Point &note) const;
+    SparseTimeValueModel *getAssociatedPitchModel(View *v) const;
+    bool updateNoteValue(View *v, FlexiNoteModel::Point &note) const;
+    void splitNotesAt(View *v, int frame, QMouseEvent *e);
 
     FlexiNoteModel *m_model;
     bool m_editing;
--- a/view/Pane.cpp	Wed Apr 02 08:50:18 2014 +0100
+++ b/view/Pane.cpp	Wed Apr 02 08:51:33 2014 +0100
@@ -344,10 +344,10 @@
     }
 
     if (layer == getSelectedLayer() &&
-    !shouldIlluminateLocalSelection(discard, b0, b1)) {
-
-    pos = m_identifyPoint;
-    return m_identifyFeatures;
+        !shouldIlluminateLocalSelection(discard, b0, b1)) {
+
+        pos = m_identifyPoint;
+        return m_identifyFeatures;
     }
 
     return false;
@@ -364,17 +364,17 @@
         !m_manager->getSelections().empty() &&
         !selectionIsBeingEdited()) {
 
-    Selection s(getSelectionAt(m_identifyPoint.x(),
-                   closeToLeft, closeToRight));
-
-    if (!s.isEmpty()) {
-        if (getSelectedLayer() && getSelectedLayer()->isLayerEditable()) {
-        
-        pos = m_identifyPoint;
-        return true;
+        Selection s(getSelectionAt(m_identifyPoint.x(),
+                                   closeToLeft, closeToRight));
+
+        if (!s.isEmpty()) {
+            if (getSelectedLayer() && getSelectedLayer()->isLayerEditable()) {
+            
+                pos = m_identifyPoint;
+                return true;
+            }
         }
     }
-    }
 
     return false;
 }
@@ -1235,6 +1235,18 @@
                         tr("Show pane context menu"));
 }
 
+Layer *
+Pane::getTopFlexiNoteLayer()
+{
+    for (int i = int(m_layers.size()) - 1; i >= 0; --i) {
+        if (LayerFactory::getInstance()->getLayerType(m_layers[i]) ==
+            LayerFactory::FlexiNotes) {
+            return m_layers[i];
+        }
+    }
+    return 0;
+}
+
 void
 Pane::mousePressEvent(QMouseEvent *e)
 {
@@ -1346,8 +1358,8 @@
     } else if (mode == ViewManager::NoteEditMode) {
 
         std::cerr << "mouse pressed in note edit mode" << std::endl;
-        Layer *layer = getSelectedLayer();
-        if (layer && layer->isLayerEditable()) {
+        Layer *layer = getTopFlexiNoteLayer();
+        if (layer) {
             layer->splitStart(this, e); 
         }
 
@@ -1461,11 +1473,22 @@
     } else if (mode == ViewManager::NoteEditMode) {
     
         //GF: handle mouse release for NoteEditMode (note: works but will need to re-think this a bit later)
-        Layer *layer = getSelectedLayer();
-        if (layer && layer->isLayerEditable()) {
+        Layer *layer = getTopFlexiNoteLayer();
+
+        if (layer) {
             layer->splitEnd(this, e);
-            update(); }
-
+            update();
+
+            if (m_editing) {
+                if (!editSelectionEnd(e)) {
+                    layer->editEnd(this, e);
+                    update();
+                }
+            }
+        } 
+
+    } else if (mode == ViewManager::EditMode) {
+        
         if (m_editing) {
             if (!editSelectionEnd(e)) {
                 Layer *layer = getSelectedLayer();
@@ -1476,19 +1499,6 @@
             }
         } 
 
-    } else if (mode == ViewManager::EditMode) {
-        
-        // GF: edited this previously, but restored to original state
-        if (m_editing) {
-            if (!editSelectionEnd(e)) {
-                Layer *layer = getSelectedLayer();
-                if (layer && layer->isLayerEditable()) {
-                    layer->editEnd(this, e);
-                    update();
-                }
-            }
-        } 
-
     } else if (mode == ViewManager::MeasureMode) {
 
         Layer *layer = getTopLayer();
@@ -1539,10 +1549,12 @@
     
         // GF: handle mouse move for context sensitive cursor switching in NoteEditMode.
         // GF: Propagate the event to FlexiNoteLayer. I somehow feel it's best handeled there rather than here, but perhaps not if this will be needed elsewhere too.
-        if (mode == ViewManager::NoteEditMode && LayerFactory::getInstance()->getLayerType(getTopLayer()) == LayerFactory::FlexiNotes) {
-        
-            dynamic_cast<FlexiNoteLayer *>(getTopLayer())->mouseMoveEvent(this, e);
-
+        if (mode == ViewManager::NoteEditMode) {
+            FlexiNoteLayer *layer = qobject_cast<FlexiNoteLayer *>(getTopFlexiNoteLayer());
+            if (layer) {
+                layer->mouseMoveEvent(this, e); //!!! ew
+                return;
+            }
         }   
     
         if (mode == ViewManager::SelectMode && hasTopLayerTimeXAxis()) {
@@ -1651,8 +1663,8 @@
                                        e->modifiers());
 
                 if (!editSelectionStart(&clickEvent)) {
-                    Layer *layer = getSelectedLayer();
-                    if (layer && layer->isLayerEditable()) {
+                    Layer *layer = getTopFlexiNoteLayer();
+                    if (layer) {
                         std::cerr << "calling edit start" << std::endl;
                         layer->editStart(this, &clickEvent);
                     }
--- a/view/Pane.h	Wed Apr 02 08:50:18 2014 +0100
+++ b/view/Pane.h	Wed Apr 02 08:51:33 2014 +0100
@@ -136,6 +136,8 @@
     void updateContextHelp(const QPoint *pos);
     void edgeScrollMaybe(int x);
 
+    Layer *getTopFlexiNoteLayer();
+
     bool m_identifyFeatures;
     QPoint m_identifyPoint;
     QPoint m_clickPos;
--- a/widgets/ActivityLog.cpp	Wed Apr 02 08:50:18 2014 +0100
+++ b/widgets/ActivityLog.cpp	Wed Apr 02 08:51:33 2014 +0100
@@ -25,6 +25,13 @@
 
 #include <iostream>
 
+#include "base/Debug.h"
+
+using std::cerr;
+using std::endl;
+
+#define PRINT_ACTIVITY 1
+
 ActivityLog::ActivityLog() : QDialog()
 {
     setWindowTitle(tr("Activity Log"));
@@ -53,9 +60,16 @@
 ActivityLog::activityHappened(QString name)
 {
     name = name.replace("&", "");
-//    SVDEBUG << "ActivityLog::activityHappened(" << name << ")" << endl;
+
+#ifdef PRINT_ACTIVITY
+    cerr << "ActivityLog: " << name;
     if (name == m_prevName) {
-//        cerr << "(ignoring duplicate)" << endl;
+        cerr << " (duplicate)";
+    }
+    cerr << endl;
+#endif
+
+    if (name == m_prevName) {
         return;
     }
     m_prevName = name;
--- a/widgets/CommandHistory.cpp	Wed Apr 02 08:50:18 2014 +0100
+++ b/widgets/CommandHistory.cpp	Wed Apr 02 08:51:33 2014 +0100
@@ -37,7 +37,7 @@
 
 #include <typeinfo>
 
-//#define DEBUG_COMMAND_HISTORY 1
+#define DEBUG_COMMAND_HISTORY 1
 
 CommandHistory *CommandHistory::m_instance = 0;
 
@@ -101,7 +101,7 @@
 CommandHistory::clear()
 {
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::clear()" << endl;
+    cerr << "CommandHistory::clear()" << endl;
 #endif
     closeBundle();
     m_savedAt = -1;
@@ -143,7 +143,7 @@
     if (!command) return;
 
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::addCommand: " << command->getName() << " of type " << typeid(*command).name() << " at " << command << ": execute = " << execute << ", bundle = " << bundle << " (m_currentCompound = " << m_currentCompound << ", m_currentBundle = " << m_currentBundle << ")" << endl;
+    cerr << "CommandHistory::addCommand: " << command->getName() << " of type " << typeid(*command).name() << " at " << command << ": execute = " << execute << ", bundle = " << bundle << " (m_currentCompound = " << m_currentCompound << ", m_currentBundle = " << m_currentBundle << ")" << endl;
 #endif
 
     if (m_currentCompound) {
@@ -160,7 +160,7 @@
 
 #ifdef DEBUG_COMMAND_HISTORY
     if (!m_redoStack.empty()) {
-        SVDEBUG << "CommandHistory::clearing redo stack" << endl;
+        cerr << "CommandHistory::clearing redo stack" << endl;
     }
 #endif
 
@@ -192,8 +192,8 @@
     if (m_currentBundle) {
 	if (!command || (command->getName() != m_currentBundleName)) {
 #ifdef DEBUG_COMMAND_HISTORY
-            SVDEBUG << "CommandHistory::addToBundle: "
-                      << command->getName()                      << ": closing current bundle" << endl;
+            cerr << "CommandHistory::addToBundle: " << command->getName()
+                 << ": closing current bundle" << endl;
 #endif
 	    closeBundle();
 	}
@@ -204,8 +204,8 @@
     if (!m_currentBundle) {
 
 #ifdef DEBUG_COMMAND_HISTORY
-        SVDEBUG << "CommandHistory::addToBundle: "
-                  << command->getName()                  << ": creating new bundle" << endl;
+        cerr << "CommandHistory::addToBundle: " << command->getName()
+             << ": creating new bundle" << endl;
 #endif
 
 	// need to addCommand before setting m_currentBundle, as addCommand
@@ -219,8 +219,8 @@
     }
 
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::addToBundle: "
-              << command->getName()              << ": adding to bundle" << endl;
+    cerr << "CommandHistory::addToBundle: " << command->getName()
+         << ": adding to bundle" << endl;
 #endif
 
     if (execute) command->execute();
@@ -242,11 +242,12 @@
 void
 CommandHistory::closeBundle()
 {
+    if (m_currentBundle) {
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::closeBundle" << endl;
+        cerr << "CommandHistory::closeBundle" << endl;
 #endif
-
-    if (m_currentBundle) emit activity(m_currentBundle->getName());
+        emit activity(m_currentBundle->getName());
+    }
     m_currentBundle = 0;
     m_currentBundleName = "";
 }
@@ -255,7 +256,7 @@
 CommandHistory::bundleTimerTimeout()
 {
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::bundleTimerTimeout: bundle is " << m_currentBundle << endl;
+    cerr << "CommandHistory::bundleTimerTimeout: bundle is " << m_currentBundle << endl;
 #endif
 
     closeBundle();
@@ -264,14 +265,15 @@
 void
 CommandHistory::addToCompound(Command *command, bool execute)
 {
-#ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::addToCompound: " << command->getName() << endl;
-#endif
     if (!m_currentCompound) {
-	SVDEBUG << "CommandHistory::addToCompound: ERROR: no compound operation in progress!" << endl;
+	cerr << "CommandHistory::addToCompound: ERROR: no compound operation in progress!" << endl;
         return;
     }
 
+#ifdef DEBUG_COMMAND_HISTORY
+    cerr << "CommandHistory::addToCompound[" << m_currentCompound->getName() << "]: " << command->getName() << " (exec: " << execute << ")" << endl;
+#endif
+
     if (execute) command->execute();
     m_currentCompound->addCommand(command);
 }
@@ -280,13 +282,17 @@
 CommandHistory::startCompoundOperation(QString name, bool execute)
 {
     if (m_currentCompound) {
-	SVDEBUG << "CommandHistory::startCompoundOperation: ERROR: compound operation already in progress!" << endl;
+	cerr << "CommandHistory::startCompoundOperation: ERROR: compound operation already in progress!" << endl;
 	cerr << "(name is " << m_currentCompound->getName() << ")" << endl;
         return;
     }
  
+#ifdef DEBUG_COMMAND_HISTORY
+    cerr << "CommandHistory::startCompoundOperation: " << name << " (exec: " << execute << ")" << endl;
+#endif
+   
     closeBundle();
-   
+
     m_currentCompound = new MacroCommand(name);
     m_executeCompound = execute;
 }
@@ -295,9 +301,13 @@
 CommandHistory::endCompoundOperation()
 {
     if (!m_currentCompound) {
-	SVDEBUG << "CommandHistory::endCompoundOperation: ERROR: no compound operation in progress!" << endl;
+	cerr << "CommandHistory::endCompoundOperation: ERROR: no compound operation in progress!" << endl;
         return;
     }
+ 
+#ifdef DEBUG_COMMAND_HISTORY
+    cerr << "CommandHistory::endCompoundOperation: " << m_currentCompound->getName() << endl;
+#endif
 
     MacroCommand *toAdd = m_currentCompound;
     m_currentCompound = 0;
@@ -329,7 +339,7 @@
     if (m_undoStack.empty()) return;
 
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::undo()" << endl;
+    cerr << "CommandHistory::undo()" << endl;
 #endif
 
     closeBundle();
@@ -355,7 +365,7 @@
     if (m_redoStack.empty()) return;
 
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::redo()" << endl;
+    cerr << "CommandHistory::redo()" << endl;
 #endif
 
     closeBundle();
@@ -436,7 +446,7 @@
 	for (i = 0; i < limit; ++i) {
 #ifdef DEBUG_COMMAND_HISTORY
 	    Command *command = stack.top();
-	    SVDEBUG << "CommandHistory::clipStack: Saving recent command: " << command->getName() << " at " << command << endl;
+	    cerr << "CommandHistory::clipStack: Saving recent command: " << command->getName() << " at " << command << endl;
 #endif
 	    tempStack.push(stack.top());
 	    stack.pop();
@@ -458,7 +468,7 @@
 	Command *command = stack.top();
 	// Not safe to call getName() on a command about to be deleted
 #ifdef DEBUG_COMMAND_HISTORY
-	SVDEBUG << "CommandHistory::clearStack: About to delete command " << command << endl;
+	cerr << "CommandHistory::clearStack: About to delete command " << command << endl;
 #endif
 	delete command;
 	stack.pop();
--- a/widgets/KeyReference.cpp	Wed Apr 02 08:50:18 2014 +0100
+++ b/widgets/KeyReference.cpp	Wed Apr 02 08:51:33 2014 +0100
@@ -172,7 +172,8 @@
     m_text->setReadOnly(true);
 
     m_dialog = new QDialog;
-    m_dialog->setWindowTitle(tr("Sonic Visualiser: Key and Mouse Reference"));
+    m_dialog->setWindowTitle(tr("%1: Key and Mouse Reference")
+                             .arg(QApplication::applicationName()));
 
     QVBoxLayout *layout = new QVBoxLayout;
     m_dialog->setLayout(layout);