18 #include "data/model/Model.h" 19 #include "data/model/SparseTimeValueModel.h" 20 #include "base/RealTime.h" 21 #include "base/Profiler.h" 22 #include "base/Pitch.h" 23 #include "base/LogRange.h" 24 #include "base/RangeMapper.h" 32 #include "data/model/FlexiNoteModel.h" 38 #include <QPainterPath> 39 #include <QMouseEvent> 40 #include <QTextStream> 41 #include <QMessageBox> 64 m_intelligentActions(true),
69 m_originalPoint(0, 0.0, 0, 1.f, tr(
"New Point")),
70 m_editingPoint(0, 0.0, 0, 1.f, tr(
"New Point")),
71 m_greatestLeftNeighbourFrame(0),
72 m_smallestRightNeighbourFrame(0),
74 m_verticalScale(AutoAlignScale),
99 list.push_back(
"Vertical Scale");
100 list.push_back(
"Scale Units");
107 if (name ==
"Vertical Scale")
return tr(
"Vertical Scale");
108 if (name ==
"Scale Units")
return tr(
"Scale Units");
115 if (name ==
"Scale Units")
return UnitsProperty;
116 if (name ==
"Vertical Scale")
return ValueProperty;
123 if (name ==
"Vertical Scale" || name ==
"Scale Units") {
138 int *min,
int *max,
int *deflt)
const 142 if (name ==
"Vertical Scale") {
150 }
else if (name ==
"Scale Units") {
152 if (deflt) *deflt = 0;
154 val = UnitDatabase::getInstance()->getUnitId
170 if (name ==
"Vertical Scale") {
173 case 0:
return tr(
"Auto-Align");
174 case 1:
return tr(
"Linear");
175 case 2:
return tr(
"Log");
176 case 3:
return tr(
"MIDI Notes");
185 if (name ==
"Vertical Scale") {
187 }
else if (name ==
"Scale Units") {
190 (UnitDatabase::getInstance()->getUnitById(value));
217 return (unit !=
"Hz");
226 bool &logarithmic, QString &unit)
const 229 min =
m_model->getValueMinimum();
230 max =
m_model->getValueMaximum();
234 min = Pitch::getFrequencyForPitch(lrintf(min));
235 max = Pitch::getFrequencyForPitch(lrintf(max + 1));
253 min = Pitch::getFrequencyForPitch(0);
254 max = Pitch::getFrequencyForPitch(127);
259 min =
m_model->getValueMinimum();
260 max =
m_model->getValueMaximum();
267 min = Pitch::getFrequencyForPitch(lrintf(min));
268 max = Pitch::getFrequencyForPitch(lrintf(max + 1));
271 #ifdef DEBUG_NOTE_LAYER 272 cerr <<
"NoteLayer::getDisplayExtents: min = " << min <<
", max = " << max <<
" (m_scaleMinimum = " <<
m_scaleMinimum <<
", m_scaleMaximum = " <<
m_scaleMaximum <<
")" << endl;
294 #ifdef DEBUG_NOTE_LAYER 295 cerr <<
"FlexiNoteLayer::setDisplayExtents: min = " << min <<
", max = " << max << endl;
319 if (!mapper)
return 0;
324 int nr = mapper->getPositionForValue(dmax - dmin);
350 float newdist = mapper->getValueForPosition(100 - step);
352 float newmin, newmax;
358 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2;
359 newmin = newmax - newdist;
364 float dmid = (dmax + dmin) / 2;
365 newmin = dmid - newdist / 2;
366 newmax = dmid + newdist / 2;
370 newmax += (min - newmin);
377 #ifdef DEBUG_NOTE_LAYER 378 cerr <<
"FlexiNoteLayer::setVerticalZoomStep: " << step <<
": " << newmin <<
" -> " << newmax <<
" (range " << newdist <<
")" << endl;
396 if (min == max)
return 0;
399 mapper =
new LogRangeMapper(0, 100, min, max, unit);
401 mapper =
new LinearRangeMapper(0, 100, min, max, unit);
407 FlexiNoteModel::PointList
410 if (!
m_model)
return FlexiNoteModel::PointList();
414 FlexiNoteModel::PointList onPoints =
417 if (!onPoints.empty()) {
421 FlexiNoteModel::PointList prevPoints =
422 m_model->getPreviousPoints(frame);
423 FlexiNoteModel::PointList nextPoints =
426 FlexiNoteModel::PointList usePoints = prevPoints;
428 if (prevPoints.empty()) {
429 usePoints = nextPoints;
432 usePoints = nextPoints;
433 }
else if (nextPoints.begin()->frame - frame <
434 frame - prevPoints.begin()->frame) {
435 usePoints = nextPoints;
438 if (!usePoints.empty()) {
441 if ((px > x && px - x > fuzz) ||
442 (px < x && x - px > fuzz + 1)) {
457 FlexiNoteModel::PointList onPoints =
m_model->getPoints(frame);
458 if (onPoints.empty())
return false;
462 int nearestDistance = -1;
464 for (FlexiNoteModel::PointList::const_iterator i = onPoints.begin();
465 i != onPoints.end(); ++i) {
468 if (distance < 0) distance = -distance;
469 if (nearestDistance == -1 || distance < nearestDistance) {
470 nearestDistance = distance;
486 FlexiNoteModel::PointList onPoints =
m_model->getPoints(frame);
487 if (onPoints.empty())
return false;
491 int nearestDistance = -1;
493 for (FlexiNoteModel::PointList::const_iterator i = onPoints.begin();
494 i != onPoints.end(); ++i) {
497 if (distance < 0) distance = -distance;
498 if (nearestDistance == -1 || distance < nearestDistance) {
499 nearestDistance = distance;
516 if (points.empty()) {
518 return tr(
"In progress");
520 return tr(
"No local points");
525 FlexiNoteModel::PointList::iterator i;
527 for (i = points.begin(); i != points.end(); ++i) {
532 if (
m_model->getValueQuantization() != 0.0) {
538 if (pos.y() >= y - 4 && pos.y() <= y + h) {
544 if (i == points.end())
return tr(
"No local points");
546 RealTime rt = RealTime::frame2RealTime(note.frame,
548 RealTime rd = RealTime::frame2RealTime(note.duration,
555 int mnote = lrintf(note.value);
556 int cents = lrintf((note.value - mnote) * 100);
557 float freq = Pitch::getFrequencyForPitch(mnote, cents);
558 pitchText = tr(
"%1 (%2, %3 Hz)")
559 .arg(Pitch::getPitchLabel(mnote, cents))
565 pitchText = tr(
"%1 Hz (%2, %3)")
567 .arg(Pitch::getPitchLabelForFrequency(note.value))
568 .arg(Pitch::getPitchForFrequency(note.value));
571 pitchText = tr(
"%1 %2")
577 if (note.label ==
"") {
578 text = QString(tr(
"Time:\t%1\nPitch:\t%2\nDuration:\t%3\nNo label"))
579 .arg(rt.toText(
true).c_str())
581 .arg(rd.toText(
true).c_str());
583 text = QString(tr(
"Time:\t%1\nPitch:\t%2\nDuration:\t%3\nLabel:\t%4"))
584 .arg(rt.toText(
true).c_str())
586 .arg(rd.toText(
true).c_str())
604 resolution =
m_model->getResolution();
605 FlexiNoteModel::PointList points;
610 if (points.empty())
return false;
611 frame = points.begin()->frame;
615 points =
m_model->getPoints(frame, frame);
619 for (FlexiNoteModel::PointList::const_iterator i = points.begin();
620 i != points.end(); ++i) {
622 cerr <<
"FlexiNoteModel: point at " << i->frame << endl;
626 if (i->frame > frame) {
630 }
else if (i->frame + i->duration >= frame) {
631 snapped = i->frame + i->duration;
638 if (i->frame <= frame) {
647 FlexiNoteModel::PointList::const_iterator j = i;
650 if (j == points.end()) {
656 }
else if (j->frame >= frame) {
658 if (j->frame - frame < frame - i->frame) {
669 cerr <<
"snapToFeatureFrame: frame " << frame <<
" -> snapped " << snapped <<
", found = " << found << endl;
690 min =
m_model->getValueMinimum();
691 max =
m_model->getValueMaximum();
694 min = Pitch::getFrequencyForPitch(lrintf(min));
695 max = Pitch::getFrequencyForPitch(lrintf(max + 1));
698 #ifdef DEBUG_NOTE_LAYER 699 cerr <<
"FlexiNoteLayer[" <<
this <<
"]::getScaleExtents: min = " << min <<
", max = " << max <<
", log = " << log << endl;
704 LogRange::mapRange(min, max);
706 #ifdef DEBUG_NOTE_LAYER 707 cerr <<
"FlexiNoteLayer[" <<
this <<
"]::getScaleExtents: min = " << min <<
", max = " << max <<
", log = " << log << endl;
716 min = Pitch::getFrequencyForPitch(0);
717 max = Pitch::getFrequencyForPitch(70);
719 min = Pitch::getFrequencyForPitch(lrintf(min));
720 max = Pitch::getFrequencyForPitch(lrintf(max + 1));
724 LogRange::mapRange(min, max);
729 if (max == min) max = min + 1.0;
735 float min = 0.0, max = 0.0;
736 bool logarithmic =
false;
741 #ifdef DEBUG_NOTE_LAYER 742 cerr <<
"FlexiNoteLayer[" <<
this <<
"]::getYForValue(" << val <<
"): min = " << min <<
", max = " << max <<
", log = " << logarithmic << endl;
746 val = Pitch::getFrequencyForPitch(lrintf(val),
747 lrintf((val - lrintf(val)) * 100));
748 #ifdef DEBUG_NOTE_LAYER 749 cerr <<
"shouldConvertMIDIToHz true, val now = " << val << endl;
754 val = LogRange::map(val);
755 #ifdef DEBUG_NOTE_LAYER 756 cerr <<
"logarithmic true, val now = " << val << endl;
760 int y = int(h - ((val - min) * h) / (max - min)) - 1;
761 #ifdef DEBUG_NOTE_LAYER 762 cerr <<
"y = " << y << endl;
770 float min = 0.0, max = 0.0;
771 bool logarithmic =
false;
776 float val = min + (float(h - y) * float(max - min)) / h;
779 val = powf(10.f, val);
783 val = Pitch::getPitchForFrequency(val);
801 int sampleRate =
m_model->getSampleRate();
802 if (!sampleRate)
return;
806 int x1 = rect.right();
809 FlexiNoteModel::PointList points(
m_model->getPoints(0, frame1));
810 if (points.empty())
return;
815 brushColour.setAlpha(80);
820 float min =
m_model->getValueMinimum();
821 float max =
m_model->getValueMaximum();
822 if (max == min) max = min + 1.0;
825 FlexiNoteModel::Point illuminatePoint(0);
826 bool shouldIlluminate =
false;
834 paint.setRenderHint(QPainter::Antialiasing,
false);
838 for (FlexiNoteModel::PointList::const_iterator i = points.begin();
839 i != points.end(); ++i) {
842 const FlexiNoteModel::Point &p(*i);
849 if (
m_model->getValueQuantization() != 0.0) {
856 paint.setBrush(brushColour);
858 if (shouldIlluminate &&
860 !FlexiNoteModel::Point::Comparator()(illuminatePoint, p) &&
861 !FlexiNoteModel::Point::Comparator()(p, illuminatePoint)) {
863 paint.drawLine(x, -1, x, v->height() + 1);
864 paint.drawLine(x+w, -1, x+w, v->height() + 1);
869 QString vlabel = QString(
"freq: %1%2").arg(p.value).arg(
m_model->getScaleUnits());
877 y - h/2 - 2 -
paint.fontMetrics().height()
878 -
paint.fontMetrics().descent(),
881 QString hlabel =
"dur: " + QString(RealTime::frame2RealTime
882 (p.duration,
m_model->getSampleRate()).toText(
true).c_str());
885 y - h/2 -
paint.fontMetrics().descent() - 2,
888 QString llabel = QString(
"%1").arg(p.label);
891 y + h + 2 +
paint.fontMetrics().descent(),
893 QString nlabel = QString(
"%1").arg(noteNumber);
895 x +
paint.fontMetrics().averageCharWidth() / 2,
896 y + h/2 -
paint.fontMetrics().descent(),
900 paint.drawRect(x, y - h/2, w, h);
942 (v,
paint, QRect(w - 10, 0, 10, h),
943 LogRange::unmap(min),
944 LogRange::unmap(max));
945 paint.drawLine(w, 0, w, h);
951 5 +
paint.fontMetrics().ascent(),
966 if (frame < 0) frame = 0;
967 frame = frame /
m_model->getResolution() *
m_model->getResolution();
971 m_editingPoint = FlexiNoteModel::Point(frame, value, 0, 0.8, tr(
"New Point"));
990 if (frame < 0) frame = 0;
991 frame = frame /
m_model->getResolution() *
m_model->getResolution();
996 int newDuration = frame - newFrame;
997 if (newDuration < 0) {
999 newDuration = -newDuration;
1000 }
else if (newDuration == 0) {
1048 FlexiNoteModel::Point p(0);
1065 std::cerr <<
"FlexiNoteLayer::editStart(" << e->x() <<
"," << e->y() <<
")" << std::endl;
1094 for (FlexiNoteModel::PointList::const_iterator i =
m_model->getPoints().begin();
1095 i !=
m_model->getPoints().end(); ++i) {
1096 FlexiNote currentNote = *i;
1099 if (currentNote.frame + currentNote.duration - 1 < onset) {
1104 if (currentNote.frame > offset) {
1116 std::cerr <<
"FlexiNoteLayer::editDrag(" << e->x() <<
"," << e->y() <<
")" << std::endl;
1126 if (dragFrame < 0) dragFrame = 0;
1127 dragFrame = dragFrame /
m_model->getResolution() *
m_model->getResolution();
1138 std::cerr <<
"edit mode: " <<
m_editMode << std::endl;
1183 std::cerr <<
"FlexiNoteLayer::editEnd(" << e->x() <<
"," << e->y() <<
")" << std::endl;
1193 newName = tr(
"Edit Point");
1195 newName = tr(
"Relocate Point");
1198 newName = tr(
"Change Point Value");
1213 std::cerr <<
"splitStart" << std::endl;
1237 std::cerr <<
"splitEnd" << std::endl;
1242 if (xdist != 0 || ydist != 0) {
1243 std::cerr <<
"mouse moved" << std::endl;
1261 FlexiNoteModel::PointList onPoints =
m_model->getPoints(frame);
1262 if (onPoints.empty())
return;
1264 FlexiNote note(*onPoints.begin());
1266 FlexiNoteModel::EditCommand *command =
new FlexiNoteModel::EditCommand
1268 command->deletePoint(note);
1270 if (!e || !(e->modifiers() & Qt::ShiftModifier)) {
1274 FlexiNote newNote1(note.frame, note.value,
1275 frame - note.frame - gap,
1276 note.level, note.label);
1278 FlexiNote newNote2(frame, note.value,
1279 note.duration - newNote1.duration,
1280 note.level, note.label);
1284 command->addPoint(newNote1);
1287 command->addPoint(newNote2);
1290 command->addPoint(newNote1);
1291 command->addPoint(newNote2);
1301 std::cerr <<
"addNote" << std::endl;
1304 int duration = 10000;
1309 FlexiNoteModel::PointList noteList =
m_model->getPoints();
1312 int smallestRightNeighbourFrame = 0;
1313 for (FlexiNoteModel::PointList::const_iterator i = noteList.begin();
1314 i != noteList.end(); ++i) {
1315 FlexiNote currentNote = *i;
1316 if (currentNote.frame > frame) {
1317 smallestRightNeighbourFrame = currentNote.frame;
1321 if (smallestRightNeighbourFrame > 0) {
1322 duration = std::min(smallestRightNeighbourFrame - frame + 1, duration);
1323 duration = (duration > 0) ? duration : 0;
1328 (
m_model->getPoints(frame).empty() && duration > 0)) {
1329 FlexiNote newNote(frame, value, duration, 100,
"new note");
1330 FlexiNoteModel::EditCommand *command =
new FlexiNoteModel::EditCommand
1332 command->addPoint(newNote);
1337 SparseTimeValueModel *
1342 cerr <<
"FlexiNoteLayer::getAssociatedPitchModel()" << endl;
1348 cerr <<
"FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
1349 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
1351 cerr <<
"FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
1352 if (model && model->getScaleUnits() ==
"Hz") {
1353 cerr <<
"FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl;
1366 FlexiNoteModel::PointList points =
1367 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1369 FlexiNoteModel::EditCommand *command =
new FlexiNoteModel::EditCommand
1372 cerr <<
"snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() <<
" to " << s.getEndFrame() << endl;
1374 for (FlexiNoteModel::PointList::iterator i = points.begin();
1375 i != points.end(); ++i) {
1379 cerr <<
"snapSelectedNotesToPitchTrack: looking at note from " << note.frame <<
" to " << note.frame + note.duration << endl;
1381 if (!s.contains(note.frame) &&
1382 !s.contains(note.frame + note.duration - 1)) {
1386 cerr <<
"snapSelectedNotesToPitchTrack: making new note" << endl;
1387 FlexiNote newNote(note);
1389 command->deletePoint(note);
1392 command->addPoint(newNote);
1402 FlexiNoteModel::PointList points =
1403 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1405 FlexiNoteModel::PointList::iterator i = points.begin();
1407 while (i != points.end() && i->frame + i->duration < s.getStartFrame()) {
1411 while (i != points.end() && i->frame < s.getStartFrame()) {
1416 if (i == points.end())
return;
1418 FlexiNoteModel::EditCommand *command =
1419 new FlexiNoteModel::EditCommand(
m_model, tr(
"Merge Notes"));
1421 FlexiNote newNote(*i);
1423 while (i != points.end()) {
1426 if (i->frame >= s.getEndFrame())
break;
1428 if (i->frame + i->duration > s.getEndFrame())
break;
1431 newNote.duration = i->frame + i->duration - newNote.frame;
1432 command->deletePoint(*i);
1438 command->addPoint(newNote);
1446 if (!model)
return false;
1448 std::cerr << model->getTypeName() << std::endl;
1450 SparseModel<TimeValuePoint>::PointList dataPoints =
1451 model->getPoints(note.frame, note.frame + note.duration);
1453 std::cerr <<
"frame " << note.frame <<
": " << dataPoints.size() <<
" candidate points" << std::endl;
1455 if (dataPoints.empty())
return false;
1457 std::vector<float> pitchValues;
1459 for (SparseModel<TimeValuePoint>::PointList::const_iterator i =
1460 dataPoints.begin(); i != dataPoints.end(); ++i) {
1461 if (i->frame >= note.frame &&
1462 i->frame < note.frame + note.duration) {
1463 pitchValues.push_back(i->value);
1467 if (pitchValues.empty())
return false;
1469 sort(pitchValues.begin(), pitchValues.end());
1470 int size = pitchValues.size();
1473 if (size % 2 == 0) {
1474 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2;
1476 median = pitchValues[size/2];
1479 note.value = median;
1489 FlexiNoteModel::Point note(0);
1495 bool closeToLeft =
false, closeToRight =
false, closeToTop =
false, closeToBottom =
false;
1505 v->setCursor(Qt::ArrowCursor);
1507 std::cerr <<
"Mouse moved in edit mode over FlexiNoteLayer" << std::endl;
1520 int noteEndX = v->
getXForFrame(note.frame + note.duration);
1525 bool closeToNote =
false;
1527 if (y >= noteStartY-ctol && y <= noteEndY+ctol && x >= noteStartX-ctol && x <= noteEndX+ctol) closeToNote =
true;
1528 if (!closeToNote)
return;
1532 if (x >= noteStartX - tol && x <= noteStartX + tol) closeToLeft =
true;
1533 if (x >= noteEndX - tol && x <= noteEndX + tol) closeToRight =
true;
1534 if (y >= noteStartY - tol && y <= noteStartY + tol) closeToTop =
true;
1535 if (y >= noteEndY - tol && y <= noteEndY + tol) closeToBottom =
true;
1544 std::cerr <<
"Opening note editor dialog" << std::endl;
1547 FlexiNoteModel::Point note(0);
1565 if (dialog->exec() == QDialog::Accepted) {
1567 FlexiNoteModel::Point newNote = note;
1569 newNote.value = dialog->
getValue();
1571 newNote.label = dialog->
getText();
1573 FlexiNoteModel::EditCommand *command =
new FlexiNoteModel::EditCommand
1575 command->deletePoint(note);
1576 command->addPoint(newNote);
1589 FlexiNoteModel::EditCommand *command =
1590 new FlexiNoteModel::EditCommand(
m_model, tr(
"Drag Selection"));
1592 FlexiNoteModel::PointList points =
1593 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1595 for (FlexiNoteModel::PointList::iterator i = points.begin();
1596 i != points.end(); ++i) {
1598 if (s.contains(i->frame)) {
1599 FlexiNoteModel::Point newPoint(*i);
1600 newPoint.frame = i->frame + newStartFrame - s.getStartFrame();
1601 command->deletePoint(*i);
1602 command->addPoint(newPoint);
1614 FlexiNoteModel::EditCommand *command =
1615 new FlexiNoteModel::EditCommand(
m_model, tr(
"Resize Selection"));
1617 FlexiNoteModel::PointList points =
1618 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1621 double(newSize.getEndFrame() - newSize.getStartFrame()) /
1622 double(s.getEndFrame() - s.getStartFrame());
1624 for (FlexiNoteModel::PointList::iterator i = points.begin();
1625 i != points.end(); ++i) {
1627 if (s.contains(i->frame)) {
1629 double targetStart = i->frame;
1630 targetStart = newSize.getStartFrame() +
1631 double(targetStart - s.getStartFrame()) * ratio;
1633 double targetEnd = i->frame + i->duration;
1634 targetEnd = newSize.getStartFrame() +
1635 double(targetEnd - s.getStartFrame()) * ratio;
1637 FlexiNoteModel::Point newPoint(*i);
1638 newPoint.frame = lrint(targetStart);
1639 newPoint.duration = lrint(targetEnd - targetStart);
1640 command->deletePoint(*i);
1641 command->addPoint(newPoint);
1653 FlexiNoteModel::EditCommand *command =
1654 new FlexiNoteModel::EditCommand(
m_model, tr(
"Delete Selected Points"));
1656 FlexiNoteModel::PointList points =
1657 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1659 for (FlexiNoteModel::PointList::iterator i = points.begin();
1660 i != points.end(); ++i) {
1662 if (s.contains(i->frame)) {
1663 command->deletePoint(*i);
1675 FlexiNoteModel::EditCommand *command =
1676 new FlexiNoteModel::EditCommand(
m_model, tr(
"Delete Selected Points"));
1678 FlexiNoteModel::PointList points =
1679 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1681 for (FlexiNoteModel::PointList::iterator i = points.begin();
1682 i != points.end(); ++i) {
1684 ((s.getStartFrame() <= i->frame) && (s.getEndFrame() <= i->frame)) ||
1685 ((s.getStartFrame() >= (i->frame+i->duration)) && (s.getEndFrame() >= (i->frame+i->duration)))
1688 command->deletePoint(*i);
1700 FlexiNoteModel::PointList points =
1701 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1703 for (FlexiNoteModel::PointList::iterator i = points.begin();
1704 i != points.end(); ++i) {
1705 if (s.contains(i->frame)) {
1706 Clipboard::Point point(i->frame, i->value, i->duration, i->level, i->label);
1718 const Clipboard::PointList &points = from.getPoints();
1720 bool realign =
false;
1724 QMessageBox::StandardButton button =
1725 QMessageBox::question(v, tr(
"Re-align pasted items?"),
1726 tr(
"The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"),
1727 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
1730 if (button == QMessageBox::Cancel) {
1734 if (button == QMessageBox::Yes) {
1739 FlexiNoteModel::EditCommand *command =
1740 new FlexiNoteModel::EditCommand(
m_model, tr(
"Paste"));
1742 for (Clipboard::PointList::const_iterator i = points.begin();
1743 i != points.end(); ++i) {
1745 if (!i->haveFrame())
continue;
1750 frame = i->getFrame();
1754 if (i->haveReferenceFrame()) {
1755 frame = i->getReferenceFrame();
1758 frame = i->getFrame();
1762 FlexiNoteModel::Point newPoint(frame);
1764 if (i->haveLabel()) newPoint.label = i->getLabel();
1765 if (i->haveValue()) newPoint.value = i->getValue();
1766 else newPoint.value = (
m_model->getValueMinimum() +
1767 m_model->getValueMaximum()) / 2;
1768 if (i->haveLevel()) newPoint.level = i->getLevel();
1769 if (i->haveDuration()) newPoint.duration = i->getDuration();
1771 int nextFrame = frame;
1772 Clipboard::PointList::const_iterator j = i;
1773 for (; j != points.end(); ++j) {
1774 if (!j->haveFrame())
continue;
1777 if (j != points.end()) {
1778 nextFrame = j->getFrame();
1780 if (nextFrame == frame) {
1781 newPoint.duration =
m_model->getResolution();
1783 newPoint.duration = nextFrame - frame;
1787 command->addPoint(newPoint);
1797 m_pendingNoteOns.insert(FlexiNote(frame, pitch, 0,
float(velocity) / 127.0,
""));
1805 if (lrintf((*i).value) == pitch) {
1808 note.duration = frame - note.frame;
1810 FlexiNoteModel::AddPointCommand *c =
new FlexiNoteModel::AddPointCommand
1811 (
m_model, note, tr(
"Record FlexiNote"));
1831 (QString(darkbg ?
"White" :
"Black"));
1836 QString indent, QString extraAttributes)
const 1839 QString(
" verticalScale=\"%1\" scaleMinimum=\"%2\" scaleMaximum=\"%3\" ")
1852 attributes.value(
"verticalScale").toInt(&ok);
1864 float minf = std::numeric_limits<float>::max();
1867 for (FlexiNoteModel::PointList::const_iterator i =
m_model->getPoints().begin();
1868 i !=
m_model->getPoints().end(); ++i) {
1870 FlexiNote note = *i;
1871 if (note.value < minf) minf = note.value;
1872 if (note.value > maxf) maxf = note.value;
1875 std::cerr <<
"min frequency:" << minf <<
", max frequency: " << maxf << std::endl;
virtual QString getScaleUnits() const
void paintPianoVertical(View *v, QPainter &paint, QRect rect, float minf, float maxf)
int getFrameForX(int x) const
Return the closest frame to the given pixel x-coordinate.
virtual QString getPropertyGroupName(const PropertyName &) const
virtual RangeMapper * getNewVerticalZoomRangeMapper() const
Create and return a range mapper for vertical zoom step values.
void setFrameTime(int frame)
virtual void setProperty(const PropertyName &, int value)
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
The base class for visual representations of the data found in a Model.
virtual void drawStart(View *v, QMouseEvent *)
virtual bool getValueExtents(float &min, float &max, bool &log, QString &unit) const
Return the minimum and maximum values for the y axis of the model in this layer, as well as whether t...
int m_smallestRightNeighbourFrame
virtual QString getPropertyLabel(const PropertyName &) const
virtual int getYForValue(View *v, float value) const
VerticalScaleLayer methods.
virtual bool snapToFeatureFrame(View *, int &, int &resolution, SnapType) const
Adjust the given frame to snap to the nearest feature, if possible.
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
bool getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &) const
void connectSignals(const Model *)
virtual float getValueForY(View *v, int y) const
virtual void eraseEnd(View *v, QMouseEvent *)
bool shouldConvertMIDIToHz() const
virtual void editEnd(View *v, QMouseEvent *)
virtual QColor getForeground() const
virtual bool getValueExtents(QString unit, float &min, float &max, bool &log) const
virtual int getLayerCount() const
Return the number of layers, regardless of whether visible or dormant, i.e.
static QString abbreviate(QString text, int maxLength, Policy policy=ElideEnd, bool fuzzy=true, QString ellipsis="")
Abbreviate the given text to the given maximum length (including ellipsis), using the given abbreviat...
virtual void copy(View *v, Selection s, Clipboard &to)
virtual int getCurrentVerticalZoomStep() const
Get the current vertical zoom step.
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
void addCommand(Command *command)
Add a command to the command history.
virtual bool getDisplayExtents(float &min, float &max) const
Return the minimum and maximum values within the displayed range for the y axis, if only a subset of ...
FlexiNoteModel::Point m_editingPoint
virtual bool editOpen(View *v, QMouseEvent *)
Open an editor on the item under the mouse (e.g.
bool shouldAutoAlign() const
virtual bool isLayerScrollable(const View *v) const
This should return true if the layer can safely be scrolled automatically by a given view (simply cop...
void setVerticalScale(VerticalScale scale)
virtual int getVerticalZoomSteps(int &defaultStep) const
Get the number of vertical zoom steps available for this layer.
virtual void deleteSelectionInclusive(Selection s)
virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const
virtual void eraseDrag(View *v, QMouseEvent *)
virtual void moveSelection(Selection s, int newStartFrame)
void paintVertical(View *v, const VerticalScaleLayer *layer, QPainter &paint, int x0, float minlog, float maxlog)
virtual QString getFeatureDescription(View *v, QPoint &) const
virtual bool setDisplayExtents(float min, float max)
Set the displayed minimum and maximum values for the y axis to the given range, if supported.
void addNoteOff(int frame, int pitch)
Add a note-off.
virtual QColor getBaseQColor() const
virtual void splitEnd(View *v, QMouseEvent *)
void setText(QString text)
void setModel(FlexiNoteModel *model)
FlexiNoteModel::Point m_originalPoint
void getRelativeMousePosition(View *v, FlexiNoteModel::Point ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const
virtual void deleteSelection(Selection s)
virtual void paint(View *v, QPainter &paint, QRect rect) const
Paint the given rectangle of this layer onto the given view using the given painter,...
int getColourIndex(QString name) const
int getWidth(View *v, QPainter &paint)
virtual QString getPropertyLabel(const PropertyName &) const
int getStartFrame() const
Retrieve the first visible sample frame on the widget.
virtual void editStart(View *v, QMouseEvent *)
virtual void addNote(View *v, QMouseEvent *e)
void paintVertical(View *v, const VerticalScaleLayer *layer, QPainter &paint, int x0, float minf, float maxf)
void layerParametersChanged()
FlexiNoteSet m_pendingNoteOns
virtual QString getPropertyGroupName(const PropertyName &) const
virtual bool setDisplayExtents(float, float)
Set the displayed minimum and maximum values for the y axis to the given range, if supported.
int getWidth(View *v, QPainter &paint)
virtual void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
int getEndFrame() const
Retrieve the last visible sample frame on the widget.
void mergeNotes(View *v, Selection s, bool inclusive)
virtual void editDrag(View *v, QMouseEvent *)
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
static CommandHistory * getInstance()
bool clipboardHasDifferentAlignment(View *v, const Clipboard &clip) const
virtual void eraseStart(View *v, QMouseEvent *)
VerticalScale m_verticalScale
virtual bool snapToFeatureFrame(View *v, int &frame, int &resolution, SnapType snap) const
Adjust the given frame to snap to the nearest feature, if possible.
virtual Layer * getLayer(int n)
Return the nth layer, counted in stacking order.
FlexiNoteModel::PointList getLocalPoints(View *v, int) const
void abandonNoteOns()
Abandon all pending note-on events.
void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
virtual void setVerticalZoomStep(int)
!! lots of duplication with TimeValueLayer
virtual bool paste(View *v, const Clipboard &from, int frameOffset, bool interactive)
Paste from the given clipboard onto the layer at the given frame offset.
void finish(FlexiNoteModel::EditCommand *command)
virtual int alignFromReference(View *v, int frame) const
virtual int alignToReference(View *v, int frame) const
bool getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &) const
virtual const Model * getModel() const =0
void snapSelectedNotesToPitchTrack(View *v, Selection s)
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
bool updateNoteValue(View *v, FlexiNoteModel::Point ¬e) const
FlexiNoteModel::EditCommand * m_editingCommand
SparseTimeValueModel * getAssociatedPitchModel(View *v) const
virtual void mouseMoveEvent(View *v, QMouseEvent *)
virtual int getDefaultColourHint(bool dark, bool &impose)
virtual void resizeSelection(Selection s, Selection newSize)
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
virtual void drawVisibleText(QPainter &p, int x, int y, QString text, TextStyle style) const
void setVerticalRangeToNoteRange(View *v)
virtual void drawEnd(View *v, QMouseEvent *)
virtual int getVerticalScaleWidth(View *v, bool, QPainter &) const
int getFrameDuration() const
void splitNotesAt(View *v, int frame)
virtual PropertyList getProperties() const
virtual PropertyList getProperties() const
virtual void drawDrag(View *v, QMouseEvent *)
virtual void paintVerticalScale(View *v, bool, QPainter &paint, QRect rect) const
virtual PropertyType getPropertyType(const PropertyName &) const
virtual QString getLayerPresentationName() const
virtual void splitStart(View *v, QMouseEvent *)
bool m_intelligentActions
void getScaleExtents(View *, float &min, float &max, bool &log) const
virtual PropertyType getPropertyType(const PropertyName &) const
int getXForFrame(int frame) const
Return the pixel x-coordinate corresponding to a given sample frame (which may be negative).
static ColourDatabase * getInstance()
virtual void setProperty(const PropertyName &, int value)
int m_greatestLeftNeighbourFrame
void setValue(float value)
void setFrameDuration(int frame)
void addNoteOn(int frame, int pitch, int velocity)
Add a note-on.