diff view/Pane.cpp @ 771:a964151832a7

Merge from branch tony_integration
author Chris Cannam
date Wed, 14 May 2014 09:54:34 +0100
parents 410816717c2c
children 488add397d34 4c8ca536b54f
line wrap: on
line diff
--- a/view/Pane.cpp	Sat Apr 12 01:07:05 2014 -0700
+++ b/view/Pane.cpp	Wed May 14 09:54:34 2014 +0100
@@ -25,6 +25,11 @@
 #include "base/Preferences.h"
 #include "layer/WaveformLayer.h"
 
+// GF: added so we can propagate the mouse move event to the note layer for context handling.
+#include "layer/LayerFactory.h"
+#include "layer/FlexiNoteLayer.h"
+
+
 //!!! ugh
 #include "data/model/WaveFileModel.h"
 
@@ -85,6 +90,9 @@
     
     updateHeadsUpDisplay();
 
+    connect(this, SIGNAL(regionOutlined(QRect)), 
+            this, SLOT(zoomToRegion(QRect)));
+
     cerr << "Pane::Pane(" << this << ") returning" << endl;
 }
 
@@ -167,7 +175,7 @@
         }
 
         m_reset = new NotifyingPushButton;
-	m_reset->setFlat(true);
+        m_reset->setFlat(true);
         m_reset->setCursor(Qt::ArrowCursor);
         m_reset->setFixedHeight(16);
         m_reset->setFixedWidth(16);
@@ -327,19 +335,19 @@
     QPoint discard;
     bool b0, b1;
 
-    if (m_manager && m_manager->getToolMode() == ViewManager::MeasureMode) {
+    if (m_manager && m_manager->getToolModeFor(this) == ViewManager::MeasureMode) {
         return false;
     }
-
+    
     if (m_manager && !m_manager->shouldIlluminateLocalFeatures()) {
         return false;
     }
 
     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;
@@ -347,25 +355,25 @@
 
 bool
 Pane::shouldIlluminateLocalSelection(QPoint &pos,
-				     bool &closeToLeft,
-				     bool &closeToRight) const
+                     bool &closeToLeft,
+                     bool &closeToRight) const
 {
     if (m_identifyFeatures &&
-	m_manager &&
-	m_manager->getToolMode() == ViewManager::EditMode &&
-	!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;
-	    }
-	}
+        m_manager &&
+        m_manager->getToolModeFor(this) == ViewManager::EditMode &&
+        !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;
+            }
+        }
     }
 
     return false;
@@ -375,10 +383,10 @@
 Pane::selectionIsBeingEdited() const
 {
     if (!m_editingSelection.isEmpty()) {
-	if (m_mousePos != m_clickPos &&
-	    getFrameForX(m_mousePos.x()) != getFrameForX(m_clickPos.x())) {
-	    return true;
-	}
+    if (m_mousePos != m_clickPos &&
+        getFrameForX(m_mousePos.x()) != getFrameForX(m_clickPos.x())) {
+        return true;
+    }
     }
     return false;
 }
@@ -407,7 +415,7 @@
 
     if (e) paint.setClipRect(r);
 
-    ViewManager::ToolMode toolMode = m_manager->getToolMode();
+    ViewManager::ToolMode toolMode = m_manager->getToolModeFor(this);
 
     if (m_manager &&
 //        !m_manager->isPlaying() &&
@@ -457,6 +465,10 @@
 
     m_scaleWidth = 0;
 
+    if (workModel) {
+        drawModelTimeExtents(r, paint, workModel);
+    }
+
     if (m_manager && m_manager->shouldShowVerticalScale() && topLayer) {
         drawVerticalScale(r, topLayer, paint);
     }
@@ -625,9 +637,9 @@
         
     if (m_scaleWidth > 0 && r.left() < m_scaleWidth) {
 
-//	    Profiler profiler("Pane::paintEvent - painting vertical scale", true);
-
-//	    SVDEBUG << "Pane::paintEvent: calling paint.save() in vertical scale block" << endl;
+//      Profiler profiler("Pane::paintEvent - painting vertical scale", true);
+
+//      SVDEBUG << "Pane::paintEvent: calling paint.save() in vertical scale block" << endl;
         paint.save();
             
         paint.setPen(getForeground());
@@ -648,7 +660,7 @@
 {
     QPoint pos = m_identifyPoint;
     QString desc = topLayer->getFeatureDescription(this, pos);
-	    
+        
     if (desc != "") {
         
         paint.save();
@@ -725,7 +737,7 @@
     LayerList::iterator vi = m_layers.end();
     
     if (vi != m_layers.begin()) {
-	    
+        
         switch ((*--vi)->getPreferredFrameCountPosition()) {
             
         case Layer::PositionTop:
@@ -767,6 +779,39 @@
 }
 
 void
+Pane::drawModelTimeExtents(QRect r, QPainter &paint, const Model *model)
+{
+    int x0 = getXForFrame(model->getStartFrame());
+    int x1 = getXForFrame(model->getEndFrame());
+
+    int lw = 10;
+
+    paint.save();
+
+    QBrush brush;
+
+    if (hasLightBackground()) {
+        brush = QBrush(QColor("#f8f8f8"));
+        paint.setPen(Qt::black);
+    } else {
+        brush = QBrush(QColor("#101010"));
+        paint.setPen(Qt::white);
+    }
+
+    if (x0 > r.x()) {
+        paint.fillRect(0, 0, x0, height(), brush);
+        paint.drawLine(x0, 0, x0, height());
+    }
+
+    if (x1 < r.x() + r.width()) {
+        paint.fillRect(x1, 0, width() - x1, height(), brush);
+        paint.drawLine(x1, 0, x1, height());
+    }
+
+    paint.restore();
+}
+
+void
 Pane::drawAlignmentStatus(QRect r, QPainter &paint, const Model *model,
                           bool down)
 {
@@ -892,7 +937,7 @@
     }
     
     if (r.x() + r.width() >= llx - fontAscent - 3) {
-	
+    
         for (size_t i = 0; i < texts.size(); ++i) {
 
 //            cerr << "Pane "<< this << ": text " << i << ": " << texts[i] << endl;
@@ -1146,8 +1191,8 @@
 
     long testFrame = getFrameForX(x - 5);
     if (testFrame < 0) {
-	testFrame = getFrameForX(x);
-	if (testFrame < 0) return Selection();
+    testFrame = getFrameForX(x);
+    if (testFrame < 0) return Selection();
     }
 
     Selection selection = m_manager->getContainingSelection(testFrame, true);
@@ -1225,47 +1270,18 @@
                         tr("Double-click middle button to relocate with any tool"));
     kr.registerShortcut(tr("Menu"), tr("Right"),
                         tr("Show pane context menu"));
-    
-    kr.setCategory(tr("Navigate Tool Mouse Actions"));
-    
-    kr.registerShortcut(tr("Navigate"), tr("Left"), 
-                        tr("Click left button and drag to move around"));
-    kr.registerShortcut(tr("Zoom to Area"), tr("Shift+Left"), 
-                        tr("Shift-click left button and drag to zoom to a rectangular area"));
-    kr.registerShortcut(tr("Relocate"), tr("Double-Click Left"), 
-                        tr("Double-click left button to jump to clicked location"));
-    kr.registerShortcut(tr("Edit"), tr("Double-Click Left"), 
-                        tr("Double-click left button on an item to edit it"));
-        
-    kr.setCategory(tr("Select Tool Mouse Actions"));
-    kr.registerShortcut(tr("Select"), tr("Left"), 
-                        tr("Click left button and drag to select region; drag region edge to resize"));
-    kr.registerShortcut(tr("Multi Select"), tr("Ctrl+Left"), 
-#ifdef Q_OS_MAC
-                        tr("Cmd-click left button and drag to select an additional region"));
-#else
-                        tr("Ctrl-click left button and drag to select an additional region"));
-#endif
-    kr.registerShortcut(tr("Fine Select"), tr("Shift+Left"), 
-                        tr("Shift-click left button and drag to select without snapping to items or grid"));
-    
-    kr.setCategory(tr("Edit Tool Mouse Actions"));
-    kr.registerShortcut(tr("Move"), tr("Left"), 
-                        tr("Click left button on an item or selected region and drag to move"));
-    kr.registerShortcut(tr("Edit"), tr("Double-Click Left"), 
-                        tr("Double-click left button on an item to edit it"));
-    
-    kr.setCategory(tr("Draw Tool Mouse Actions"));
-    kr.registerShortcut(tr("Draw"), tr("Left"), 
-                        tr("Click left button and drag to create new item"));
-
-    kr.setCategory(tr("Measure Tool Mouse Actions"));
-    kr.registerShortcut(tr("Measure Area"), tr("Left"), 
-                        tr("Click left button and drag to measure a rectangular area"));
-    kr.registerShortcut(tr("Measure Item"), tr("Double-Click Left"), 
-                        tr("Click left button and drag to measure extents of an item or shape"));
-    kr.registerShortcut(tr("Zoom to Area"), tr("Shift+Left"), 
-                        tr("Shift-click left button and drag to zoom to a rectangular area"));
+}
+
+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
@@ -1290,7 +1306,7 @@
     m_dragMode = UnresolvedDrag;
 
     ViewManager::ToolMode mode = ViewManager::NavigateMode;
-    if (m_manager) mode = m_manager->getToolMode();
+    if (m_manager) mode = m_manager->getToolModeFor(this);
 
     m_navigating = false;
     m_resizing = false;
@@ -1302,12 +1318,12 @@
         (mode == ViewManager::MeasureMode &&
          (e->buttons() & Qt::LeftButton) && m_shiftPressed)) {
 
-	if (mode != ViewManager::NavigateMode) {
-	    setCursor(Qt::PointingHandCursor);
-	}
-
-	m_navigating = true;
-	m_dragCentreFrame = m_centreFrame;
+        if (mode != ViewManager::NavigateMode) {
+            setCursor(Qt::PointingHandCursor);
+        }
+
+        m_navigating = true;
+        m_dragCentreFrame = m_centreFrame;
         m_dragStartMinValue = 0;
         
         float vmin, vmax, dmin, dmax;
@@ -1319,61 +1335,70 @@
 
         if (!hasTopLayerTimeXAxis()) return;
 
-	bool closeToLeft = false, closeToRight = false;
-	Selection selection = getSelectionAt(e->x(), closeToLeft, closeToRight);
-
-	if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
-
-	    m_manager->removeSelection(selection);
-
-	    if (closeToLeft) {
-		m_selectionStartFrame = selection.getEndFrame();
-	    } else {
-		m_selectionStartFrame = selection.getStartFrame();
-	    }
-
-	    m_manager->setInProgressSelection(selection, false);
-	    m_resizing = true;
-	
-	} else {
-
-	    int mouseFrame = getFrameForX(e->x());
-	    size_t resolution = 1;
-	    int snapFrame = mouseFrame;
-	
-	    Layer *layer = getSelectedLayer();
-	    if (layer && !m_shiftPressed) {
-		layer->snapToFeatureFrame(this, snapFrame,
-					  resolution, Layer::SnapLeft);
-	    }
-	    
-	    if (snapFrame < 0) snapFrame = 0;
-	    m_selectionStartFrame = snapFrame;
-	    if (m_manager) {
-		m_manager->setInProgressSelection
+        bool closeToLeft = false, closeToRight = false;
+        Selection selection = getSelectionAt(e->x(), closeToLeft, closeToRight);
+
+        if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
+
+            m_manager->removeSelection(selection);
+
+            if (closeToLeft) {
+                m_selectionStartFrame = selection.getEndFrame();
+            } else {
+                m_selectionStartFrame = selection.getStartFrame();
+            }
+            
+            m_manager->setInProgressSelection(selection, false);
+            m_resizing = true;
+            
+        } else {
+            
+            int mouseFrame = getFrameForX(e->x());
+            size_t resolution = 1;
+            int snapFrame = mouseFrame;
+    
+            Layer *layer = getSelectedLayer();
+            if (layer && !m_shiftPressed) {
+                layer->snapToFeatureFrame(this, snapFrame,
+                                          resolution, Layer::SnapLeft);
+            }
+        
+            if (snapFrame < 0) snapFrame = 0;
+            m_selectionStartFrame = snapFrame;
+            if (m_manager) {
+                m_manager->setInProgressSelection
                     (Selection(alignToReference(snapFrame),
                                alignToReference(snapFrame + resolution)),
                      !m_ctrlPressed);
-	    }
-
-	    m_resizing = false;
-	}
-
-	update();
+            }
+
+            m_resizing = false;
+        }
+
+        update();
 
     } else if (mode == ViewManager::DrawMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    layer->drawStart(this, e);
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->drawStart(this, e);
+        }
 
     } else if (mode == ViewManager::EraseMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    layer->eraseStart(this, e);
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->eraseStart(this, e);
+        }
+
+        // GF: handle mouse press for NoteEditMode 
+    } else if (mode == ViewManager::NoteEditMode) {
+
+        std::cerr << "mouse pressed in note edit mode" << std::endl;
+        Layer *layer = getTopFlexiNoteLayer();
+        if (layer) {
+            layer->splitStart(this, e); 
+        }
 
     } else if (mode == ViewManager::EditMode) {
 
@@ -1400,33 +1425,33 @@
 //    cerr << "mouseReleaseEvent" << endl;
 
     ViewManager::ToolMode mode = ViewManager::NavigateMode;
-    if (m_manager) mode = m_manager->getToolMode();
+    if (m_manager) mode = m_manager->getToolModeFor(this);
 
     m_releasing = true;
 
     if (m_clickedInRange) {
-	mouseMoveEvent(e);
+        mouseMoveEvent(e);
     }
 
     if (m_navigating || mode == ViewManager::NavigateMode) {
 
-	m_navigating = false;
-
-	if (mode != ViewManager::NavigateMode) {
-	    // restore cursor
-	    toolModeChanged();
-	}
-
-	if (m_shiftPressed) {
-
-	    int x0 = std::min(m_clickPos.x(), m_mousePos.x());
-	    int x1 = std::max(m_clickPos.x(), m_mousePos.x());
-
-	    int y0 = std::min(m_clickPos.y(), m_mousePos.y());
-	    int y1 = std::max(m_clickPos.y(), m_mousePos.y());
-
-            zoomToRegion(x0, y0, x1, y1);
-	}
+        m_navigating = false;
+
+        if (mode != ViewManager::NavigateMode) {
+            // restore cursor
+            toolModeChanged();
+        }
+
+        if (m_shiftPressed) {
+
+            int x0 = std::min(m_clickPos.x(), m_mousePos.x());
+            int x1 = std::max(m_clickPos.x(), m_mousePos.x());
+
+            int y0 = std::min(m_clickPos.y(), m_mousePos.y());
+            int y1 = std::max(m_clickPos.y(), m_mousePos.y());
+
+            emit regionOutlined(QRect(x0, y0, x1 - x0, y1 - y0));
+        }
 
     } else if (mode == ViewManager::SelectMode) {
 
@@ -1435,44 +1460,72 @@
             return;
         }
 
-	if (m_manager && m_manager->haveInProgressSelection()) {
-
-	    bool exclusive;
-	    Selection selection = m_manager->getInProgressSelection(exclusive);
-	    
-	    if (selection.getEndFrame() < selection.getStartFrame() + 2) {
-		selection = Selection();
-	    }
-	    
-	    m_manager->clearInProgressSelection();
-	    
-	    if (exclusive) {
-		m_manager->setSelection(selection);
-	    } else {
-		m_manager->addSelection(selection);
-	    }
-	}
-	
-	update();
+        if (m_manager && m_manager->haveInProgressSelection()) {
+
+            //cerr << "JTEST: release with selection" << endl;
+            bool exclusive;
+            Selection selection = m_manager->getInProgressSelection(exclusive);
+        
+            if (selection.getEndFrame() < selection.getStartFrame() + 2) {
+                selection = Selection();
+            }
+        
+            m_manager->clearInProgressSelection();
+        
+            if (exclusive) {
+                m_manager->setSelection(selection);
+            } else {
+                m_manager->addSelection(selection);
+            }
+        }
+        else if (m_manager && !m_manager->haveInProgressSelection()) {
+            
+            //cerr << "JTEST: release without selection" << endl;
+            // Get frame location of mouse
+            int mouseFrame = getFrameForX(e->x());
+            //cerr << "JTEST: frame location of click is " << mouseFrame << endl;
+            // Move play head to that frame location
+            int playbackFrame = fmax(0,mouseFrame);
+            m_manager->setPlaybackFrame(playbackFrame);
+        }
+    
+        update();
 
     } else if (mode == ViewManager::DrawMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    layer->drawEnd(this, e);
-	    update();
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->drawEnd(this, e);
+            update();
+        }
 
     } else if (mode == ViewManager::EraseMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    layer->eraseEnd(this, e);
-	    update();
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->eraseEnd(this, e);
+            update();
+        }
+
+    } 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 = getTopFlexiNoteLayer();
+
+        if (layer) {
+            layer->splitEnd(this, e);
+            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();
@@ -1481,7 +1534,7 @@
                     update();
                 }
             }
-        }
+        } 
 
     } else if (mode == ViewManager::MeasureMode) {
 
@@ -1524,22 +1577,32 @@
     }
 
     ViewManager::ToolMode mode = ViewManager::NavigateMode;
-    if (m_manager) mode = m_manager->getToolMode();
+    if (m_manager) mode = m_manager->getToolModeFor(this);
 
     QPoint prevPoint = m_identifyPoint;
     m_identifyPoint = e->pos();
 
     if (!m_clickedInRange) {
-	
-	if (mode == ViewManager::SelectMode && hasTopLayerTimeXAxis()) {
-	    bool closeToLeft = false, closeToRight = false;
-	    getSelectionAt(e->x(), closeToLeft, closeToRight);
-	    if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
-		setCursor(Qt::SizeHorCursor);
-	    } else {
-		setCursor(Qt::ArrowCursor);
-	    }
-	}
+    
+        // 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) {
+            FlexiNoteLayer *layer = qobject_cast<FlexiNoteLayer *>(getTopFlexiNoteLayer());
+            if (layer) {
+                layer->mouseMoveEvent(this, e); //!!! ew
+                return;
+            }
+        }   
+    
+        if (mode == ViewManager::SelectMode && hasTopLayerTimeXAxis()) {
+            bool closeToLeft = false, closeToRight = false;
+            getSelectionAt(e->x(), closeToLeft, closeToRight);
+            if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
+                setCursor(Qt::SizeHorCursor);
+            } else {
+                setCursor(Qt::ArrowCursor);
+            }
+        }
 
         if (!m_manager->isPlaying()) {
 
@@ -1569,17 +1632,17 @@
             }
         }
 
-	return;
+        return;
     }
 
     if (m_navigating || mode == ViewManager::NavigateMode) {
 
-	if (m_shiftPressed) {
-
-	    m_mousePos = e->pos();
-	    update();
-
-	} else {
+        if (m_shiftPressed) {
+
+            m_mousePos = e->pos();
+            update();
+
+        } else {
 
             dragTopLayer(e);
         }
@@ -1592,17 +1655,82 @@
 
     } else if (mode == ViewManager::DrawMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    layer->drawDrag(this, e);
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->drawDrag(this, e);
+        }
 
     } else if (mode == ViewManager::EraseMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    layer->eraseDrag(this, e);
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->eraseDrag(this, e);
+        }
+
+        // GF: handling NoteEditMode dragging and boundary actions for mouseMoveEvent
+    } else if (mode == ViewManager::NoteEditMode) {
+
+        bool resist = true;
+
+        if ((e->modifiers() & Qt::ShiftModifier)) {
+            m_shiftPressed = true;
+        }
+
+        if (m_shiftPressed) resist = false;
+
+        m_dragMode = updateDragMode
+            (m_dragMode,
+             m_clickPos,
+             e->pos(),
+             true,    // can move horiz
+             true,    // can move vert
+             resist,  // resist horiz
+             resist); // resist vert
+
+        if (!m_editing) {
+
+            if (m_dragMode != UnresolvedDrag) {
+
+                m_editing = true;
+
+                QMouseEvent clickEvent(QEvent::MouseButtonPress,
+                                       m_clickPos,
+                                       Qt::NoButton,
+                                       e->buttons(),
+                                       e->modifiers());
+
+                if (!editSelectionStart(&clickEvent)) {
+                    Layer *layer = getTopFlexiNoteLayer();
+                    if (layer) {
+                        std::cerr << "calling edit start" << std::endl;
+                        layer->editStart(this, &clickEvent);
+                    }
+                }
+            }
+
+        } else {
+
+            if (!editSelectionDrag(e)) {
+
+                Layer *layer = getSelectedLayer();
+
+                if (layer && layer->isLayerEditable()) {
+
+                    int x = e->x();
+                    int y = e->y();
+                    if (m_dragMode == VerticalDrag) x = m_clickPos.x();
+                    else if (m_dragMode == HorizontalDrag) y = m_clickPos.y();
+
+                    QMouseEvent moveEvent(QEvent::MouseMove,
+                                          QPoint(x, y),
+                                          Qt::NoButton,
+                                          e->buttons(),
+                                          e->modifiers());
+                    std::cerr << "calling editDrag" << std::endl;
+                    layer->editDrag(this, &moveEvent);
+                }
+            }
+        }
 
     } else if (mode == ViewManager::EditMode) {
 
@@ -1685,21 +1813,26 @@
 }
 
 void
-Pane::zoomToRegion(int x0, int y0, int x1, int y1)
+Pane::zoomToRegion(QRect r)
 {
+    int x0 = r.x();
+    int y0 = r.y();
+    int x1 = r.x() + r.width();
+    int y1 = r.y() + r.height();
+
     int w = x1 - x0;
-	    
+        
     long newStartFrame = getFrameForX(x0);
-	    
+        
     long visibleFrames = getEndFrame() - getStartFrame();
     if (newStartFrame <= -visibleFrames) {
         newStartFrame  = -visibleFrames + 1;
     }
-	    
+        
     if (newStartFrame >= long(getModelsEndFrame())) {
         newStartFrame  = getModelsEndFrame() - 1;
     }
-	    
+        
     float ratio = float(w) / float(width());
 //	cerr << "ratio: " << ratio << endl;
     size_t newZoomLevel = (size_t)nearbyint(m_zoomLevel * ratio);
@@ -1784,7 +1917,7 @@
         long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x());
 
         size_t newCentreFrame = m_dragCentreFrame;
-	    
+        
         if (frameOff < 0) {
             newCentreFrame -= frameOff;
         } else if (newCentreFrame >= size_t(frameOff)) {
@@ -1793,7 +1926,7 @@
             newCentreFrame = 0;
         }
 
-#ifdef DEBUG_PANE	    
+#ifdef DEBUG_PANE       
         SVDEBUG << "Pane::dragTopLayer: newCentreFrame = " << newCentreFrame <<
             ", models end frame = " << getModelsEndFrame() << endl;
 #endif
@@ -1912,7 +2045,7 @@
     size_t resolution = 1;
     int snapFrameLeft = mouseFrame;
     int snapFrameRight = mouseFrame;
-	
+    
     Layer *layer = getSelectedLayer();
     if (layer && !m_shiftPressed) {
         layer->snapToFeatureFrame(this, snapFrameLeft,
@@ -1925,9 +2058,9 @@
 
     if (snapFrameLeft < 0) snapFrameLeft = 0;
     if (snapFrameRight < 0) snapFrameRight = 0;
-	
+    
     size_t min, max;
-	
+    
     if (m_selectionStartFrame > size_t(snapFrameLeft)) {
         min = snapFrameLeft;
         max = m_selectionStartFrame;
@@ -1993,18 +2126,25 @@
     m_altPressed = (e->modifiers() & Qt::AltModifier);
 
     ViewManager::ToolMode mode = ViewManager::NavigateMode;
-    if (m_manager) mode = m_manager->getToolMode();
+    if (m_manager) mode = m_manager->getToolModeFor(this);
 
     bool relocate = (mode == ViewManager::NavigateMode ||
                      (e->buttons() & Qt::MidButton));
 
+    if (mode == ViewManager::SelectMode) {
+        m_clickedInRange = false;
+        m_manager->clearInProgressSelection();
+        emit doubleClickSelectInvoked(getFrameForX(e->x()));
+        return;
+    }
+
     if (mode == ViewManager::NavigateMode ||
         mode == ViewManager::EditMode) {
 
-	Layer *layer = getSelectedLayer();
-	if (layer && layer->isLayerEditable()) {
-	    if (layer->editOpen(this, e)) relocate = false;
-	}
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            if (layer->editOpen(this, e)) relocate = false;
+        }
 
     } else if (mode == ViewManager::MeasureMode) {
 
@@ -2028,6 +2168,14 @@
             m_dragStartMinValue = dmin;
         }
     }
+    
+    if (mode == ViewManager::NoteEditMode) {
+        std::cerr << "double click in note edit mode" << std::endl;
+        Layer *layer = getSelectedLayer();
+        if (layer && layer->isLayerEditable()) {
+            layer->addNote(this, e); 
+        }
+    }
 
     m_clickedInRange = false; // in case mouseReleaseEvent is not properly called
 }
@@ -2062,31 +2210,31 @@
     int count = e->delta();
 
     if (count > 0) {
-	if (count >= 120) count /= 120;
-	else count = 1;
+    if (count >= 120) count /= 120;
+    else count = 1;
     } 
 
     if (count < 0) {
-	if (count <= -120) count /= 120;
-	else count = -1;
+    if (count <= -120) count /= 120;
+    else count = -1;
     }
 
     if (e->modifiers() & Qt::ControlModifier) {
 
-	// Scroll left or right, rapidly
-
-	if (getStartFrame() < 0 && 
-	    getEndFrame() >= getModelsEndFrame()) return;
-
-	long delta = ((width() / 2) * count * m_zoomLevel);
-
-	if (int(m_centreFrame) < delta) {
-	    setCentreFrame(0);
-	} else if (int(m_centreFrame) - delta >= int(getModelsEndFrame())) {
-	    setCentreFrame(getModelsEndFrame());
-	} else {
-	    setCentreFrame(m_centreFrame - delta);
-	}
+    // Scroll left or right, rapidly
+
+    if (getStartFrame() < 0 && 
+        getEndFrame() >= getModelsEndFrame()) return;
+
+    long delta = ((width() / 2) * count * m_zoomLevel);
+
+    if (int(m_centreFrame) < delta) {
+        setCentreFrame(0);
+    } else if (int(m_centreFrame) - delta >= int(getModelsEndFrame())) {
+        setCentreFrame(getModelsEndFrame());
+    } else {
+        setCentreFrame(m_centreFrame - delta);
+    }
 
     } else if (e->modifiers() & Qt::ShiftModifier) {
 
@@ -2106,29 +2254,29 @@
 
     } else {
 
-	// Zoom in or out
-
-	int newZoomLevel = m_zoomLevel;
+    // Zoom in or out
+
+    int newZoomLevel = m_zoomLevel;
   
-	while (count > 0) {
-	    if (newZoomLevel <= 2) {
-		newZoomLevel = 1;
-		break;
-	    }
-	    newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1, 
-						      ZoomConstraint::RoundDown);
-	    --count;
-	}
-	
-	while (count < 0) {
-	    newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1,
-						      ZoomConstraint::RoundUp);
-	    ++count;
-	}
-	
-	if (newZoomLevel != m_zoomLevel) {
-	    setZoomLevel(newZoomLevel);
-	}
+    while (count > 0) {
+        if (newZoomLevel <= 2) {
+        newZoomLevel = 1;
+        break;
+        }
+        newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1, 
+                              ZoomConstraint::RoundDown);
+        --count;
+    }
+    
+    while (count < 0) {
+        newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1,
+                              ZoomConstraint::RoundUp);
+        ++count;
+    }
+    
+    if (newZoomLevel != m_zoomLevel) {
+        setZoomLevel(newZoomLevel);
+    }
     }
 
     emit paneInteractedWith();
@@ -2306,9 +2454,9 @@
 Pane::editSelectionStart(QMouseEvent *e)
 {
     if (!m_identifyFeatures ||
-	!m_manager ||
-	m_manager->getToolMode() != ViewManager::EditMode) {
-	return false;
+        !m_manager ||
+        m_manager->getToolModeFor(this) != ViewManager::EditMode) {
+        return false;
     }
 
     bool closeToLeft, closeToRight;
@@ -2338,8 +2486,8 @@
     Layer *layer = getSelectedLayer();
 
     if (offset == 0 || !layer) {
-	m_editingSelection = Selection();
-	return true;
+        m_editingSelection = Selection();
+        return true;
     }
 
     int p0 = getXForFrame(m_editingSelection.getStartFrame()) + offset;
@@ -2351,25 +2499,25 @@
     Selection newSelection(f0, f1);
     
     if (m_editingSelectionEdge == 0) {
-	
+    
         CommandHistory::getInstance()->startCompoundOperation
             (tr("Drag Selection"), true);
 
-	layer->moveSelection(m_editingSelection, f0);
-	
+        layer->moveSelection(m_editingSelection, f0);
+    
     } else {
-	
+    
         CommandHistory::getInstance()->startCompoundOperation
             (tr("Resize Selection"), true);
 
-	if (m_editingSelectionEdge < 0) {
-	    f1 = m_editingSelection.getEndFrame();
-	} else {
-	    f0 = m_editingSelection.getStartFrame();
-	}
-
-	newSelection = Selection(f0, f1);
-	layer->resizeSelection(m_editingSelection, newSelection);
+        if (m_editingSelectionEdge < 0) {
+            f1 = m_editingSelection.getEndFrame();
+        } else {
+            f0 = m_editingSelection.getStartFrame();
+        }
+
+        newSelection = Selection(f0, f1);
+        layer->resizeSelection(m_editingSelection, newSelection);
     }
     
     m_manager->removeSelection(m_editingSelection);
@@ -2384,7 +2532,7 @@
 void
 Pane::toolModeChanged()
 {
-    ViewManager::ToolMode mode = m_manager->getToolMode();
+    ViewManager::ToolMode mode = m_manager->getToolModeFor(this);
 //    SVDEBUG << "Pane::toolModeChanged(" << mode << ")" << endl;
 
     if (mode == ViewManager::MeasureMode && !m_measureCursor1) {
@@ -2399,33 +2547,38 @@
     switch (mode) {
 
     case ViewManager::NavigateMode:
-	setCursor(Qt::PointingHandCursor);
-	break;
-	
+        setCursor(Qt::PointingHandCursor);
+        break;
+    
     case ViewManager::SelectMode:
-	setCursor(Qt::ArrowCursor);
-	break;
-	
+        setCursor(Qt::ArrowCursor);
+        break;
+    
     case ViewManager::EditMode:
-	setCursor(Qt::UpArrowCursor);
-	break;
-	
+        setCursor(Qt::UpArrowCursor);
+        break;
+    
     case ViewManager::DrawMode:
-	setCursor(Qt::CrossCursor);
-	break;
-	
+        setCursor(Qt::CrossCursor);
+        break;
+    
     case ViewManager::EraseMode:
-	setCursor(Qt::CrossCursor);
-	break;
+        setCursor(Qt::CrossCursor);
+        break;
 
     case ViewManager::MeasureMode:
         if (m_measureCursor1) setCursor(*m_measureCursor1);
-	break;
-
-/*	
+        break;
+
+        // GF: NoteEditMode uses the same default cursor as EditMode, but it will change in a context sensitive manner.
+    case ViewManager::NoteEditMode:
+        setCursor(Qt::UpArrowCursor);
+        break;
+
+/*  
     case ViewManager::TextMode:
-	setCursor(Qt::IBeamCursor);
-	break;
+    setCursor(Qt::IBeamCursor);
+    break;
 */
     }
 }
@@ -2509,7 +2662,7 @@
     }
 
     ViewManager::ToolMode mode = ViewManager::NavigateMode;
-    if (m_manager) mode = m_manager->getToolMode();
+    if (m_manager) mode = m_manager->getToolModeFor(this);
 
     bool editable = false;
     Layer *layer = getSelectedLayer();
@@ -2561,21 +2714,21 @@
     } else if (mode == ViewManager::DrawMode) {
         
         //!!! could call through to a layer function to find out exact meaning
-	if (editable) {
+        if (editable) {
             help = tr("Click to add a new item in the active layer");
         }
 
     } else if (mode == ViewManager::EraseMode) {
         
         //!!! could call through to a layer function to find out exact meaning
-	if (editable) {
+        if (editable) {
             help = tr("Click to erase an item from the active layer");
         }
         
     } else if (mode == ViewManager::EditMode) {
         
         //!!! could call through to layer
-	if (editable) {
+        if (editable) {
             help = tr("Click and drag an item in the active layer to move it; hold Shift to override initial resistance");
             if (pos) {
                 bool closeToLeft = false, closeToRight = false;
@@ -2619,8 +2772,8 @@
 {
     View::toXml
         (stream, indent,
-	 QString("type=\"pane\" centreLineVisible=\"%1\" height=\"%2\" %3")
-	 .arg(m_centreLineVisible).arg(height()).arg(extraAttributes));
+     QString("type=\"pane\" centreLineVisible=\"%1\" height=\"%2\" %3")
+     .arg(m_centreLineVisible).arg(height()).arg(extraAttributes));
 }