changeset 552:2e8194a30f40 sv-v1.7.1

* Layer data editor window: fix sorting for columns in region model, add Find feature * RDF import: assign names to layers based on event types, if no suitable labels are found in the RDF * Add label to status bar showing the last text that was passed in current layer (so e.g. counting 1, 2, 3, 4 if that's what beats are labelled) * Better layout of text labels for region layers in segmentation mode when they are close together * Give text layer the same method for finding "nearest point" as region and note layers, should improve its editability
author Chris Cannam
date Thu, 22 Oct 2009 15:54:21 +0000
parents c2ba2796cbee
children 97e60a895211
files layer/Layer.h layer/RegionLayer.cpp layer/RegionLayer.h layer/TextLayer.cpp layer/TextLayer.h layer/TimeInstantLayer.cpp layer/TimeInstantLayer.h layer/TimeValueLayer.cpp layer/TimeValueLayer.h widgets/ModelDataTableDialog.cpp widgets/ModelDataTableDialog.h widgets/PropertyStack.cpp
diffstat 12 files changed, 198 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Layer.h	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/Layer.h	Thu Oct 22 15:54:21 2009 +0000
@@ -33,6 +33,8 @@
 #include <map>
 #include <set>
 
+#include <iostream>
+
 class ZoomConstraint;
 class Model;
 class QPainter;
@@ -145,6 +147,10 @@
 	return "";
     }
 
+    virtual QString getLabelPreceding(size_t frame) const {
+        return "";
+    }
+
     enum SnapType {
 	SnapLeft,
 	SnapRight,
--- a/layer/RegionLayer.cpp	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/RegionLayer.cpp	Thu Oct 22 15:54:21 2009 +0000
@@ -353,6 +353,18 @@
 }
 
 QString
+RegionLayer::getLabelPreceding(size_t frame) const
+{
+    if (!m_model) return "";
+    RegionModel::PointList points = m_model->getPreviousPoints(frame);
+    for (RegionModel::PointList::const_iterator i = points.begin();
+         i != points.end(); ++i) {
+        if (i->label != "") return i->label;
+    }
+    return "";
+}
+
+QString
 RegionLayer::getFeatureDescription(View *v, QPoint &pos) const
 {
     int x = pos.x();
@@ -751,7 +763,7 @@
 
 //    Profiler profiler("RegionLayer::paint", true);
 
-    int x0 = rect.left(), x1 = rect.right();
+    int x0 = rect.left() - 40, x1 = rect.right();
     long frame0 = v->getFrameForX(x0);
     long frame1 = v->getFrameForX(x1);
 
@@ -826,8 +838,6 @@
             paint.setBrush(brushColour);
         }
 
-        bool illuminated = false;
-
 	if (m_plotStyle == PlotSegmentation) {
 
 	    if (ex <= x) continue;
@@ -837,12 +847,14 @@
                 RegionModel::Point::Comparator()(illuminatePoint, p) ||
                 RegionModel::Point::Comparator()(p, illuminatePoint)) {
 
-//	    if (illuminateFrame != p.frame &&
-//		(ex < x + 5 || x >= v->width() - 1)) {
+                paint.drawLine(x, 0, x, v->height());
                 paint.setPen(Qt::NoPen);
+
+            } else {
+                paint.setPen(QPen(getForegroundQColor(v), 2));
             }
 
-	    paint.drawRect(x, -1, ex - x, v->height() + 1);
+	    paint.drawRect(x, 0, ex - x, v->height() + 1);
 
 	} else {
 
@@ -867,8 +879,6 @@
                                    x,
                                    y - h/2 - paint.fontMetrics().descent() - 2,
                                    hlabel, View::OutlinedText);
-
-                illuminated = true;
             }
             
             paint.drawLine(x, y-1, x + w, y-1);
@@ -876,6 +886,31 @@
             paint.drawLine(x, y - h/2, x, y + h/2);
             paint.drawLine(x+w, y - h/2, x + w, y + h/2);
         }
+    }
+
+    int nextLabelMinX = -100;
+    int lastLabelY = 0;
+
+    for (RegionModel::PointList::const_iterator i = points.begin();
+	 i != points.end(); ++i) {
+
+	const RegionModel::Point &p(*i);
+
+	int x = v->getXForFrame(p.frame);
+	int y = getYForValue(v, p.value);
+
+        bool illuminated = false;
+
+	if (m_plotStyle != PlotSegmentation) {
+
+            if (shouldIlluminate &&
+                // "illuminatePoint == p"
+                !RegionModel::Point::Comparator()(illuminatePoint, p) &&
+                !RegionModel::Point::Comparator()(p, illuminatePoint)) {
+
+                illuminated = true;
+            }
+        }
 
         if (!illuminated) {
             QString label = p.label;
@@ -883,18 +918,25 @@
                 label = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
             }
 
+            int labelX, labelY;
+
             if (m_plotStyle != PlotSegmentation) {
-                v->drawVisibleText(paint,
-                                   x - paint.fontMetrics().width(label) - 2,
-                                   y + paint.fontMetrics().height()/2
-                                     - paint.fontMetrics().descent(), 
-                                   label, View::OutlinedText);
+                labelX = x - paint.fontMetrics().width(label) - 2;
+                labelY = y + paint.fontMetrics().height()/2 
+                    - paint.fontMetrics().descent();
             } else {
-                v->drawVisibleText(paint,
-                                   x + 5,
-                                   v->getTextLabelHeight(this, paint),
-                                   label, View::OutlinedText);
+                labelX = x + 5;
+                labelY = v->getTextLabelHeight(this, paint);
+                if (labelX < nextLabelMinX) {
+                    if (lastLabelY < v->height()/2) {
+                        labelY = lastLabelY + fontHeight;
+                    }
+                }
+                lastLabelY = labelY;
+                nextLabelMinX = labelX + paint.fontMetrics().width(label);
             }
+
+            v->drawVisibleText(paint, labelX, labelY, label, View::OutlinedText);
         }
     }
 
@@ -1101,16 +1143,10 @@
 RegionLayer::editOpen(View *v, QMouseEvent *e)
 {
     if (!m_model) return false;
-/*
-    RegionModel::PointList points = getLocalPoints(v, e->x());
-    if (points.empty()) return false;
-*/
 
     RegionModel::Point region(0);
     if (!getPointToDrag(v, e->x(), e->y(), region)) return false;
 
-//    RegionModel::Point region = *points.begin();
-
     ItemEditDialog *dialog = new ItemEditDialog
         (m_model->getSampleRate(),
          ItemEditDialog::ShowTime |
--- a/layer/RegionLayer.h	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/RegionLayer.h	Thu Oct 22 15:54:21 2009 +0000
@@ -37,6 +37,7 @@
     virtual void paint(View *v, QPainter &paint, QRect rect) const;
 
     virtual QString getFeatureDescription(View *v, QPoint &) const;
+    virtual QString getLabelPreceding(size_t) const;
 
     virtual bool snapToFeatureFrame(View *v, int &frame,
 				    size_t &resolution,
--- a/layer/TextLayer.cpp	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/TextLayer.cpp	Thu Oct 22 15:54:21 2009 +0000
@@ -120,7 +120,7 @@
     TextModel::PointList points(m_model->getPoints(frame0, frame1));
 
     TextModel::PointList rv;
-    QFontMetrics metrics = QPainter().fontMetrics();
+    QFontMetrics metrics = QFontMetrics(QFont());
 
     for (TextModel::PointList::iterator i = points.begin();
 	 i != points.end(); ++i) {
@@ -153,6 +153,34 @@
     return rv;
 }
 
+bool
+TextLayer::getPointToDrag(View *v, int x, int y, TextModel::Point &p) const
+{
+    if (!m_model) return false;
+
+    long a = v->getFrameForX(x - 120);
+    long b = v->getFrameForX(x + 10);
+    TextModel::PointList onPoints = m_model->getPoints(a, b);
+    if (onPoints.empty()) return false;
+
+    float nearestDistance = -1;
+
+    for (TextModel::PointList::const_iterator i = onPoints.begin();
+         i != onPoints.end(); ++i) {
+
+        int yd = getYForHeight(v, (*i).height) - y;
+        int xd = v->getXForFrame((*i).frame) - x;
+        float distance = sqrt(yd*yd + xd*xd);
+
+        if (nearestDistance == -1 || distance < nearestDistance) {
+            nearestDistance = distance;
+            p = *i;
+        }
+    }
+
+    return true;
+}
+
 QString
 TextLayer::getFeatureDescription(View *v, QPoint &pos) const
 {
@@ -307,12 +335,12 @@
 //	      << m_model->getResolution() << " frames" << std::endl;
 
     QPoint localPos;
-    long illuminateFrame = -1;
+    TextModel::Point illuminatePoint(0);
+    bool shouldIlluminate;
 
     if (v->shouldIlluminateLocalFeatures(this, localPos)) {
-	TextModel::PointList localPoints = getLocalPoints(v, localPos.x(),
-							  localPos.y());
-	if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
+        shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(),
+                                          illuminatePoint);
     }
 
     int boxMaxWidth = 150;
@@ -329,12 +357,15 @@
 	int x = v->getXForFrame(p.frame);
 	int y = getYForHeight(v, p.height);
 
-	if (illuminateFrame == p.frame) {
+        if (!shouldIlluminate ||
+            // "illuminatePoint != p"
+            TextModel::Point::Comparator()(illuminatePoint, p) ||
+            TextModel::Point::Comparator()(p, illuminatePoint)) {
+	    paint.setPen(penColour);
+	    paint.setBrush(brushColour);
+        } else {
 	    paint.setBrush(penColour);
             paint.setPen(v->getBackground());
-	} else {
-	    paint.setPen(penColour);
-	    paint.setBrush(brushColour);
 	}
 
 	QString label = p.label;
@@ -453,10 +484,7 @@
 {
     if (!m_model) return;
 
-    TextModel::PointList points = getLocalPoints(v, e->x(), e->y());
-    if (points.empty()) return;
-
-    m_editingPoint = *points.begin();
+    if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
 
     if (m_editingCommand) {
 	finish(m_editingCommand);
@@ -478,10 +506,9 @@
 
     m_editing = false;
 
-    TextModel::PointList points = getLocalPoints(v, e->x(), e->y());
-    if (points.empty()) return;
-    if (points.begin()->frame != m_editingPoint.frame ||
-        points.begin()->height != m_editingPoint.height) return;
+    TextModel::Point p(0);
+    if (!getPointToDrag(v, e->x(), e->y(), p)) return;
+    if (p.frame != m_editingPoint.frame || p.height != m_editingPoint.height) return;
 
     m_editingCommand = new TextModel::EditCommand
         (m_model, tr("Erase Point"));
@@ -500,11 +527,11 @@
 
     if (!m_model) return;
 
-    TextModel::PointList points = getLocalPoints(v, e->x(), e->y());
-    if (points.empty()) return;
+    if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) {
+        return;
+    }
 
     m_editOrigin = e->pos();
-    m_editingPoint = *points.begin();
     m_originalPoint = m_editingPoint;
 
     if (m_editingCommand) {
@@ -575,18 +602,18 @@
 {
     if (!m_model) return false;
 
-    TextModel::PointList points = getLocalPoints(v, e->x(), e->y());
-    if (points.empty()) return false;
+    TextModel::Point text(0);
+    if (!getPointToDrag(v, e->x(), e->y(), text)) return false;
 
-    QString label = points.begin()->label;
+    QString label = text.label;
 
     bool ok = false;
     label = QInputDialog::getText(v, tr("Enter label"),
 				  tr("Please enter a new label:"),
 				  QLineEdit::Normal, label, &ok);
-    if (ok && label != points.begin()->label) {
+    if (ok && label != text.label) {
 	TextModel::RelabelCommand *command =
-	    new TextModel::RelabelCommand(m_model, *points.begin(), label);
+	    new TextModel::RelabelCommand(m_model, text, label);
 	CommandHistory::getInstance()->addCommand(command);
     }
 
--- a/layer/TextLayer.h	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/TextLayer.h	Thu Oct 22 15:54:21 2009 +0000
@@ -96,6 +96,8 @@
 
     TextModel::PointList getLocalPoints(View *v, int x, int y) const;
 
+    bool getPointToDrag(View *v, int x, int y, TextModel::Point &) const;
+
     TextModel *m_model;
     bool m_editing;
     QPoint m_editOrigin;
--- a/layer/TimeInstantLayer.cpp	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/TimeInstantLayer.cpp	Thu Oct 22 15:54:21 2009 +0000
@@ -201,6 +201,18 @@
 }
 
 QString
+TimeInstantLayer::getLabelPreceding(size_t frame) const
+{
+    if (!m_model) return "";
+    SparseOneDimensionalModel::PointList points = m_model->getPreviousPoints(frame);
+    for (SparseOneDimensionalModel::PointList::const_iterator i = points.begin();
+         i != points.end(); ++i) {
+        if (i->label != "") return i->label;
+    }
+    return "";
+}
+
+QString
 TimeInstantLayer::getFeatureDescription(View *v, QPoint &pos) const
 {
     int x = pos.x();
--- a/layer/TimeInstantLayer.h	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/TimeInstantLayer.h	Thu Oct 22 15:54:21 2009 +0000
@@ -35,6 +35,7 @@
 
     virtual void paint(View *v, QPainter &paint, QRect rect) const;
 
+    virtual QString getLabelPreceding(size_t) const;
     virtual QString getFeatureDescription(View *v, QPoint &) const;
 
     virtual bool snapToFeatureFrame(View *v, int &frame,
--- a/layer/TimeValueLayer.cpp	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/TimeValueLayer.cpp	Thu Oct 22 15:54:21 2009 +0000
@@ -505,6 +505,18 @@
 }
 
 QString
+TimeValueLayer::getLabelPreceding(size_t frame) const
+{
+    if (!m_model) return "";
+    SparseTimeValueModel::PointList points = m_model->getPreviousPoints(frame);
+    for (SparseTimeValueModel::PointList::const_iterator i = points.begin();
+         i != points.end(); ++i) {
+        if (i->label != "") return i->label;
+    }
+    return "";
+}
+
+QString
 TimeValueLayer::getFeatureDescription(View *v, QPoint &pos) const
 {
     int x = pos.x();
--- a/layer/TimeValueLayer.h	Fri Oct 02 13:56:10 2009 +0000
+++ b/layer/TimeValueLayer.h	Thu Oct 22 15:54:21 2009 +0000
@@ -38,6 +38,7 @@
     virtual void paintVerticalScale(View *v, QPainter &paint, QRect rect) const;
 
     virtual QString getFeatureDescription(View *v, QPoint &) const;
+    virtual QString getLabelPreceding(size_t) const;
 
     virtual bool snapToFeatureFrame(View *v, int &frame,
 				    size_t &resolution,
--- a/widgets/ModelDataTableDialog.cpp	Fri Oct 02 13:56:10 2009 +0000
+++ b/widgets/ModelDataTableDialog.cpp	Thu Oct 22 15:54:21 2009 +0000
@@ -23,7 +23,9 @@
 #include "IconLoader.h"
 
 #include <QTableView>
+#include <QLineEdit>
 #include <QGridLayout>
+#include <QLabel>
 #include <QGroupBox>
 #include <QDialogButtonBox>
 #include <QHeaderView>
@@ -102,17 +104,26 @@
     subgrid->setSpacing(0);
     subgrid->setMargin(5);
 
+    subgrid->addWidget(new QLabel(tr("Find:")), 1, 0);
+    subgrid->addWidget(new QLabel(tr(" ")), 1, 1);
+    m_find = new QLineEdit;
+    subgrid->addWidget(m_find, 1, 2);
+    connect(m_find, SIGNAL(textChanged(const QString &)),
+            this, SLOT(searchTextChanged(const QString &)));
+    connect(m_find, SIGNAL(returnPressed()),
+            this, SLOT(searchRepeated()));
+
     m_tableView = new QTableView;
-    subgrid->addWidget(m_tableView);
+    subgrid->addWidget(m_tableView, 0, 0, 1, 3);
 
-//    m_tableView->verticalHeader()->hide();
-//    m_tableView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
     m_tableView->setSortingEnabled(true);
     m_tableView->sortByColumn(0, Qt::AscendingOrder);
 
     m_table = new ModelDataTableModel(model);
     m_tableView->setModel(m_table);
 
+    m_tableView->horizontalHeader()->setStretchLastSection(true);
+
     connect(m_tableView, SIGNAL(clicked(const QModelIndex &)),
             this, SLOT(viewClicked(const QModelIndex &)));
     connect(m_tableView, SIGNAL(pressed(const QModelIndex &)),
@@ -141,8 +152,11 @@
     if (height < 370) {
         if (available.height() > 500) height = 370;
     }
-    if (width < 500) {
-        if (available.width() > 650) width = 500;
+    if (width < 650) {
+        if (available.width() > 750) width = 650;
+        else if (width < 500) {
+            if (available.width() > 650) width = 500;
+        }
     }
 
     resize(width, height);
@@ -170,6 +184,28 @@
 }
 
 void
+ModelDataTableDialog::searchTextChanged(const QString &text)
+{
+    QModelIndex mi = m_table->findText(text);
+    if (mi.isValid()) {
+        makeCurrent(mi.row());
+        m_tableView->selectionModel()->setCurrentIndex
+            (mi, QItemSelectionModel::ClearAndSelect);
+    }
+}
+
+void
+ModelDataTableDialog::searchRepeated()
+{
+    QModelIndex mi = m_table->findText(m_find->text());
+    if (mi.isValid()) {
+        makeCurrent(mi.row());
+        m_tableView->selectionModel()->setCurrentIndex
+            (mi, QItemSelectionModel::ClearAndSelect);
+    }
+}
+
+void
 ModelDataTableDialog::makeCurrent(int row)
 {
     int rh = m_tableView->height() / m_tableView->rowHeight(0);
--- a/widgets/ModelDataTableDialog.h	Fri Oct 02 13:56:10 2009 +0000
+++ b/widgets/ModelDataTableDialog.h	Thu Oct 22 15:54:21 2009 +0000
@@ -24,6 +24,7 @@
 class QModelIndex;
 class Command;
 class QToolBar;
+class QLineEdit;
 
 class ModelDataTableDialog : public QMainWindow
 {
@@ -49,6 +50,8 @@
     void viewPressed(const QModelIndex &);
     void currentChanged(const QModelIndex &, const QModelIndex &);
     void currentChangedThroughResort(const QModelIndex &);
+    void searchTextChanged(const QString &);
+    void searchRepeated();
     
     void insertRow();
     void deleteRows();
@@ -62,6 +65,7 @@
     ModelDataTableModel *m_table;
     QToolBar *m_playToolbar;
     QTableView *m_tableView;
+    QLineEdit *m_find;
     int m_currentRow;
     bool m_trackPlayback;
 };
--- a/widgets/PropertyStack.cpp	Fri Oct 02 13:56:10 2009 +0000
+++ b/widgets/PropertyStack.cpp	Thu Oct 22 15:54:21 2009 +0000
@@ -112,8 +112,12 @@
         if (layer) {
             shortName = LayerFactory::getInstance()->getLayerPresentationName
                 (LayerFactory::getInstance()->getLayerType(layer));
+            if (layer->getLayerPresentationName() != "") {
+                name = layer->getLayerPresentationName();
+            }
         }
 
+        bool nameDiffers = (name != shortName);
         shortName = QString("&%1 %2").arg(i + 1).arg(shortName);
 
 	QString iconName = container->getPropertyContainerIconName();
@@ -121,6 +125,9 @@
         QIcon icon(IconLoader().load(iconName));
 	if (icon.isNull()) {
 	    addTab(box, shortName);
+            if (nameDiffers) {
+                setTabToolTip(i, name);
+            }
 	} else {
 	    addTab(box, icon, QString("&%1").arg(i + 1));
 	    setTabToolTip(i, name);