comparison layer/TimeValueLayer.cpp @ 997:296ccd36f626 tony-2.0-integration

Merge through to branch for Tony 2.0
author Chris Cannam
date Thu, 20 Aug 2015 14:54:21 +0100
parents fa96108d552d
children ee01a4062747
comparison
equal deleted inserted replaced
943:788b7623bfca 997:296ccd36f626
18 #include "data/model/Model.h" 18 #include "data/model/Model.h"
19 #include "base/RealTime.h" 19 #include "base/RealTime.h"
20 #include "base/Profiler.h" 20 #include "base/Profiler.h"
21 #include "base/LogRange.h" 21 #include "base/LogRange.h"
22 #include "base/RangeMapper.h" 22 #include "base/RangeMapper.h"
23 #include "base/Pitch.h"
23 #include "ColourDatabase.h" 24 #include "ColourDatabase.h"
24 #include "view/View.h" 25 #include "view/View.h"
25 26
26 #include "data/model/SparseTimeValueModel.h" 27 #include "data/model/SparseTimeValueModel.h"
27 #include "data/model/Labeller.h" 28 #include "data/model/Labeller.h"
313 m_derivative = show; 314 m_derivative = show;
314 emit layerParametersChanged(); 315 emit layerParametersChanged();
315 } 316 }
316 317
317 bool 318 bool
318 TimeValueLayer::isLayerScrollable(const View *v) const 319 TimeValueLayer::isLayerScrollable(const LayerGeometryProvider *v) const
319 { 320 {
320 // We don't illuminate sections in the line or curve modes, so 321 // We don't illuminate sections in the line or curve modes, so
321 // they're always scrollable 322 // they're always scrollable
322 323
323 if (m_plotStyle == PlotLines || 324 if (m_plotStyle == PlotLines ||
527 528
528 return mapper; 529 return mapper;
529 } 530 }
530 531
531 SparseTimeValueModel::PointList 532 SparseTimeValueModel::PointList
532 TimeValueLayer::getLocalPoints(View *v, int x) const 533 TimeValueLayer::getLocalPoints(LayerGeometryProvider *v, int x) const
533 { 534 {
534 if (!m_model) return SparseTimeValueModel::PointList(); 535 if (!m_model) return SparseTimeValueModel::PointList();
535 536
536 sv_frame_t frame = v->getFrameForX(x); 537 sv_frame_t frame = v->getFrameForX(x);
537 538
584 } 585 }
585 return ""; 586 return "";
586 } 587 }
587 588
588 QString 589 QString
589 TimeValueLayer::getFeatureDescription(View *v, QPoint &pos) const 590 TimeValueLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
590 { 591 {
591 int x = pos.x(); 592 int x = pos.x();
592 593
593 if (!m_model || !m_model->getSampleRate()) return ""; 594 if (!m_model || !m_model->getSampleRate()) return "";
594 595
604 605
605 sv_frame_t useFrame = points.begin()->frame; 606 sv_frame_t useFrame = points.begin()->frame;
606 607
607 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); 608 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
608 609
610 QString valueText;
611 float value = points.begin()->value;
612 QString unit = getScaleUnits();
613
614 if (unit == "Hz") {
615 valueText = tr("%1 Hz (%2, %3)")
616 .arg(value)
617 .arg(Pitch::getPitchLabelForFrequency(value))
618 .arg(Pitch::getPitchForFrequency(value));
619 } else if (unit != "") {
620 valueText = tr("%1 %2").arg(value).arg(unit);
621 } else {
622 valueText = tr("%1").arg(value);
623 }
624
609 QString text; 625 QString text;
610 QString unit = getScaleUnits();
611 if (unit != "") unit = " " + unit;
612 626
613 if (points.begin()->label == "") { 627 if (points.begin()->label == "") {
614 text = QString(tr("Time:\t%1\nValue:\t%2%3\nNo label")) 628 text = QString(tr("Time:\t%1\nValue:\t%2\nNo label"))
615 .arg(rt.toText(true).c_str()) 629 .arg(rt.toText(true).c_str())
616 .arg(points.begin()->value) 630 .arg(valueText);
617 .arg(unit);
618 } else { 631 } else {
619 text = QString(tr("Time:\t%1\nValue:\t%2%3\nLabel:\t%4")) 632 text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%4"))
620 .arg(rt.toText(true).c_str()) 633 .arg(rt.toText(true).c_str())
621 .arg(points.begin()->value) 634 .arg(valueText)
622 .arg(unit)
623 .arg(points.begin()->label); 635 .arg(points.begin()->label);
624 } 636 }
625 637
626 pos = QPoint(v->getXForFrame(useFrame), 638 pos = QPoint(v->getXForFrame(useFrame),
627 getYForValue(v, points.begin()->value)); 639 getYForValue(v, points.begin()->value));
628 return text; 640 return text;
629 } 641 }
630 642
631 bool 643 bool
632 TimeValueLayer::snapToFeatureFrame(View *v, sv_frame_t &frame, 644 TimeValueLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
633 int &resolution, 645 int &resolution,
634 SnapType snap) const 646 SnapType snap) const
635 { 647 {
636 if (!m_model) { 648 if (!m_model) {
637 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 649 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
699 frame = snapped; 711 frame = snapped;
700 return found; 712 return found;
701 } 713 }
702 714
703 bool 715 bool
704 TimeValueLayer::snapToSimilarFeature(View *v, sv_frame_t &frame, 716 TimeValueLayer::snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame,
705 int &resolution, 717 int &resolution,
706 SnapType snap) const 718 SnapType snap) const
707 { 719 {
708 if (!m_model) { 720 if (!m_model) {
709 return Layer::snapToSimilarFeature(v, frame, resolution, snap); 721 return Layer::snapToSimilarFeature(v, frame, resolution, snap);
780 frame = snapped; 792 frame = snapped;
781 return found; 793 return found;
782 } 794 }
783 795
784 void 796 void
785 TimeValueLayer::getScaleExtents(View *v, double &min, double &max, bool &log) const 797 TimeValueLayer::getScaleExtents(LayerGeometryProvider *v, double &min, double &max, bool &log) const
786 { 798 {
787 min = 0.0; 799 min = 0.0;
788 max = 0.0; 800 max = 0.0;
789 log = false; 801 log = false;
790 802
816 cerr << "TimeValueLayer::getScaleExtents: min = " << min << ", max = " << max << endl; 828 cerr << "TimeValueLayer::getScaleExtents: min = " << min << ", max = " << max << endl;
817 #endif 829 #endif
818 } 830 }
819 831
820 int 832 int
821 TimeValueLayer::getYForValue(View *v, double val) const 833 TimeValueLayer::getYForValue(LayerGeometryProvider *v, double val) const
822 { 834 {
823 double min = 0.0, max = 0.0; 835 double min = 0.0, max = 0.0;
824 bool logarithmic = false; 836 bool logarithmic = false;
825 int h = v->height(); 837 int h = v->getPaintHeight();
826 838
827 getScaleExtents(v, min, max, logarithmic); 839 getScaleExtents(v, min, max, logarithmic);
828 840
829 #ifdef DEBUG_TIME_VALUE_LAYER 841 #ifdef DEBUG_TIME_VALUE_LAYER
830 cerr << "getYForValue(" << val << "): min " << min << ", max " 842 cerr << "getYForValue(" << val << "): min " << min << ", max "
837 849
838 return int(h - ((val - min) * h) / (max - min)); 850 return int(h - ((val - min) * h) / (max - min));
839 } 851 }
840 852
841 double 853 double
842 TimeValueLayer::getValueForY(View *v, int y) const 854 TimeValueLayer::getValueForY(LayerGeometryProvider *v, int y) const
843 { 855 {
844 double min = 0.0, max = 0.0; 856 double min = 0.0, max = 0.0;
845 bool logarithmic = false; 857 bool logarithmic = false;
846 int h = v->height(); 858 int h = v->getPaintHeight();
847 859
848 getScaleExtents(v, min, max, logarithmic); 860 getScaleExtents(v, min, max, logarithmic);
849 861
850 double val = min + (double(h - y) * double(max - min)) / h; 862 double val = min + (double(h - y) * double(max - min)) / h;
851 863
863 QString unit = getScaleUnits(); 875 QString unit = getScaleUnits();
864 return (m_verticalScale == AutoAlignScale && unit != ""); 876 return (m_verticalScale == AutoAlignScale && unit != "");
865 } 877 }
866 878
867 QColor 879 QColor
868 TimeValueLayer::getColourForValue(View *v, double val) const 880 TimeValueLayer::getColourForValue(LayerGeometryProvider *v, double val) const
869 { 881 {
870 double min, max; 882 double min, max;
871 bool log; 883 bool log;
872 getScaleExtents(v, min, max, log); 884 getScaleExtents(v, min, max, log);
873 885
894 return ColourDatabase::getInstance()->getColourIndex 906 return ColourDatabase::getInstance()->getColourIndex
895 (QString(darkbg ? "Bright Green" : "Green")); 907 (QString(darkbg ? "Bright Green" : "Green"));
896 } 908 }
897 909
898 void 910 void
899 TimeValueLayer::paint(View *v, QPainter &paint, QRect rect) const 911 TimeValueLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
900 { 912 {
901 if (!m_model || !m_model->isOK()) return; 913 if (!m_model || !m_model->isOK()) return;
902 914
903 sv_samplerate_t sampleRate = m_model->getSampleRate(); 915 sv_samplerate_t sampleRate = m_model->getSampleRate();
904 if (!sampleRate) return; 916 if (!sampleRate) return;
929 941
930 double min = m_model->getValueMinimum(); 942 double min = m_model->getValueMinimum();
931 double max = m_model->getValueMaximum(); 943 double max = m_model->getValueMaximum();
932 if (max == min) max = min + 1.0; 944 if (max == min) max = min + 1.0;
933 945
934 int origin = int(nearbyint(v->height() - 946 int origin = int(nearbyint(v->getPaintHeight() -
935 (-min * v->height()) / (max - min))); 947 (-min * v->getPaintHeight()) / (max - min)));
936 948
937 QPoint localPos; 949 QPoint localPos;
938 sv_frame_t illuminateFrame = -1; 950 sv_frame_t illuminateFrame = -1;
939 951
940 if (v->shouldIlluminateLocalFeatures(this, localPos)) { 952 if (v->shouldIlluminateLocalFeatures(this, localPos)) {
964 int textY = 0; 976 int textY = 0;
965 if (m_plotStyle == PlotSegmentation) { 977 if (m_plotStyle == PlotSegmentation) {
966 textY = v->getTextLabelHeight(this, paint); 978 textY = v->getTextLabelHeight(this, paint);
967 } else { 979 } else {
968 int originY = getYForValue(v, 0.f); 980 int originY = getYForValue(v, 0.f);
969 if (originY > 0 && originY < v->height()) { 981 if (originY > 0 && originY < v->getPaintHeight()) {
970 paint.save(); 982 paint.save();
971 paint.setPen(getPartialShades(v)[1]); 983 paint.setPen(getPartialShades(v)[1]);
972 paint.drawLine(x0, originY, x1, originY); 984 paint.drawLine(x0, originY, x1, originY);
973 paint.restore(); 985 paint.restore();
974 } 986 }
1169 paint.setPen(QPen(getForegroundQColor(v), 2)); 1181 paint.setPen(QPen(getForegroundQColor(v), 2));
1170 1182
1171 if (!illuminate) { 1183 if (!illuminate) {
1172 if (!m_drawSegmentDivisions || 1184 if (!m_drawSegmentDivisions ||
1173 nx < x + 5 || 1185 nx < x + 5 ||
1174 x >= v->width() - 1) { 1186 x >= v->getPaintWidth() - 1) {
1175 paint.setPen(Qt::NoPen); 1187 paint.setPen(Qt::NoPen);
1176 } 1188 }
1177 } 1189 }
1178 1190
1179 paint.drawRect(x, -1, nx - x, v->height() + 1); 1191 paint.drawRect(x, -1, nx - x, v->getPaintHeight() + 1);
1180 } 1192 }
1181 1193
1182 if (v->shouldShowFeatureLabels()) { 1194 if (v->shouldShowFeatureLabels()) {
1183 1195
1184 QString label = p.label; 1196 QString label = p.label;
1217 if (m_plotStyle == PlotDiscreteCurves) { 1229 if (m_plotStyle == PlotDiscreteCurves) {
1218 paint.setRenderHint(QPainter::Antialiasing, true); 1230 paint.setRenderHint(QPainter::Antialiasing, true);
1219 paint.drawPath(path); 1231 paint.drawPath(path);
1220 } else if ((m_plotStyle == PlotCurve || m_plotStyle == PlotLines) 1232 } else if ((m_plotStyle == PlotCurve || m_plotStyle == PlotLines)
1221 && !path.isEmpty()) { 1233 && !path.isEmpty()) {
1222 paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->width()); 1234 paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->getPaintWidth());
1223 paint.drawPath(path); 1235 paint.drawPath(path);
1224 } 1236 }
1225 1237
1226 paint.restore(); 1238 paint.restore();
1227 1239
1228 // looks like save/restore doesn't deal with this: 1240 // looks like save/restore doesn't deal with this:
1229 paint.setRenderHint(QPainter::Antialiasing, false); 1241 paint.setRenderHint(QPainter::Antialiasing, false);
1230 } 1242 }
1231 1243
1232 int 1244 int
1233 TimeValueLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const 1245 TimeValueLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const
1234 { 1246 {
1235 if (!m_model || shouldAutoAlign()) { 1247 if (!m_model || shouldAutoAlign()) {
1236 return 0; 1248 return 0;
1237 } else if (m_plotStyle == PlotSegmentation) { 1249 } else if (m_plotStyle == PlotSegmentation) {
1238 if (m_verticalScale == LogScale) { 1250 if (m_verticalScale == LogScale) {
1248 } 1260 }
1249 } 1261 }
1250 } 1262 }
1251 1263
1252 void 1264 void
1253 TimeValueLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const 1265 TimeValueLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const
1254 { 1266 {
1255 if (!m_model || m_model->getPoints().empty()) return; 1267 if (!m_model || m_model->getPoints().empty()) return;
1256 1268
1257 QString unit; 1269 QString unit;
1258 double min, max; 1270 double min, max;
1259 bool logarithmic; 1271 bool logarithmic;
1260 1272
1261 int w = getVerticalScaleWidth(v, false, paint); 1273 int w = getVerticalScaleWidth(v, false, paint);
1262 int h = v->height(); 1274 int h = v->getPaintHeight();
1263 1275
1264 if (m_plotStyle == PlotSegmentation) { 1276 if (m_plotStyle == PlotSegmentation) {
1265 1277
1266 getValueExtents(min, max, logarithmic, unit); 1278 getValueExtents(min, max, logarithmic, unit);
1267 1279
1300 mw)); 1312 mw));
1301 } 1313 }
1302 } 1314 }
1303 1315
1304 void 1316 void
1305 TimeValueLayer::drawStart(View *v, QMouseEvent *e) 1317 TimeValueLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e)
1306 { 1318 {
1307 #ifdef DEBUG_TIME_VALUE_LAYER 1319 #ifdef DEBUG_TIME_VALUE_LAYER
1308 cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; 1320 cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
1309 #endif 1321 #endif
1310 1322
1350 1362
1351 m_editing = true; 1363 m_editing = true;
1352 } 1364 }
1353 1365
1354 void 1366 void
1355 TimeValueLayer::drawDrag(View *v, QMouseEvent *e) 1367 TimeValueLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e)
1356 { 1368 {
1357 #ifdef DEBUG_TIME_VALUE_LAYER 1369 #ifdef DEBUG_TIME_VALUE_LAYER
1358 cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; 1370 cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
1359 #endif 1371 #endif
1360 1372
1412 m_editingPoint.value = float(value); 1424 m_editingPoint.value = float(value);
1413 m_editingCommand->addPoint(m_editingPoint); 1425 m_editingCommand->addPoint(m_editingPoint);
1414 } 1426 }
1415 1427
1416 void 1428 void
1417 TimeValueLayer::drawEnd(View *, QMouseEvent *) 1429 TimeValueLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *)
1418 { 1430 {
1419 #ifdef DEBUG_TIME_VALUE_LAYER 1431 #ifdef DEBUG_TIME_VALUE_LAYER
1420 cerr << "TimeValueLayer::drawEnd" << endl; 1432 cerr << "TimeValueLayer::drawEnd" << endl;
1421 #endif 1433 #endif
1422 if (!m_model || !m_editing) return; 1434 if (!m_model || !m_editing) return;
1424 m_editingCommand = 0; 1436 m_editingCommand = 0;
1425 m_editing = false; 1437 m_editing = false;
1426 } 1438 }
1427 1439
1428 void 1440 void
1429 TimeValueLayer::eraseStart(View *v, QMouseEvent *e) 1441 TimeValueLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e)
1430 { 1442 {
1431 if (!m_model) return; 1443 if (!m_model) return;
1432 1444
1433 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1445 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x());
1434 if (points.empty()) return; 1446 if (points.empty()) return;
1442 1454
1443 m_editing = true; 1455 m_editing = true;
1444 } 1456 }
1445 1457
1446 void 1458 void
1447 TimeValueLayer::eraseDrag(View *, QMouseEvent *) 1459 TimeValueLayer::eraseDrag(LayerGeometryProvider *, QMouseEvent *)
1448 { 1460 {
1449 } 1461 }
1450 1462
1451 void 1463 void
1452 TimeValueLayer::eraseEnd(View *v, QMouseEvent *e) 1464 TimeValueLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e)
1453 { 1465 {
1454 if (!m_model || !m_editing) return; 1466 if (!m_model || !m_editing) return;
1455 1467
1456 m_editing = false; 1468 m_editing = false;
1457 1469
1469 m_editingCommand = 0; 1481 m_editingCommand = 0;
1470 m_editing = false; 1482 m_editing = false;
1471 } 1483 }
1472 1484
1473 void 1485 void
1474 TimeValueLayer::editStart(View *v, QMouseEvent *e) 1486 TimeValueLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e)
1475 { 1487 {
1476 #ifdef DEBUG_TIME_VALUE_LAYER 1488 #ifdef DEBUG_TIME_VALUE_LAYER
1477 cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; 1489 cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
1478 #endif 1490 #endif
1479 1491
1492 1504
1493 m_editing = true; 1505 m_editing = true;
1494 } 1506 }
1495 1507
1496 void 1508 void
1497 TimeValueLayer::editDrag(View *v, QMouseEvent *e) 1509 TimeValueLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e)
1498 { 1510 {
1499 #ifdef DEBUG_TIME_VALUE_LAYER 1511 #ifdef DEBUG_TIME_VALUE_LAYER
1500 cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; 1512 cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl;
1501 #endif 1513 #endif
1502 1514
1518 m_editingPoint.value = float(value); 1530 m_editingPoint.value = float(value);
1519 m_editingCommand->addPoint(m_editingPoint); 1531 m_editingCommand->addPoint(m_editingPoint);
1520 } 1532 }
1521 1533
1522 void 1534 void
1523 TimeValueLayer::editEnd(View *, QMouseEvent *) 1535 TimeValueLayer::editEnd(LayerGeometryProvider *, QMouseEvent *)
1524 { 1536 {
1525 #ifdef DEBUG_TIME_VALUE_LAYER 1537 #ifdef DEBUG_TIME_VALUE_LAYER
1526 cerr << "TimeValueLayer::editEnd" << endl; 1538 cerr << "TimeValueLayer::editEnd" << endl;
1527 #endif 1539 #endif
1528 if (!m_model || !m_editing) return; 1540 if (!m_model || !m_editing) return;
1548 m_editingCommand = 0; 1560 m_editingCommand = 0;
1549 m_editing = false; 1561 m_editing = false;
1550 } 1562 }
1551 1563
1552 bool 1564 bool
1553 TimeValueLayer::editOpen(View *v, QMouseEvent *e) 1565 TimeValueLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e)
1554 { 1566 {
1555 if (!m_model) return false; 1567 if (!m_model) return false;
1556 1568
1557 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1569 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x());
1558 if (points.empty()) return false; 1570 if (points.empty()) return false;
1671 1683
1672 finish(command); 1684 finish(command);
1673 } 1685 }
1674 1686
1675 void 1687 void
1676 TimeValueLayer::copy(View *v, Selection s, Clipboard &to) 1688 TimeValueLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
1677 { 1689 {
1678 if (!m_model) return; 1690 if (!m_model) return;
1679 1691
1680 SparseTimeValueModel::PointList points = 1692 SparseTimeValueModel::PointList points =
1681 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1693 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1689 } 1701 }
1690 } 1702 }
1691 } 1703 }
1692 1704
1693 bool 1705 bool
1694 TimeValueLayer::paste(View *v, const Clipboard &from, sv_frame_t /* frameOffset */, 1706 TimeValueLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */,
1695 bool interactive) 1707 bool interactive)
1696 { 1708 {
1697 if (!m_model) return false; 1709 if (!m_model) return false;
1698 1710
1699 const Clipboard::PointList &points = from.getPoints(); 1711 const Clipboard::PointList &points = from.getPoints();
1701 bool realign = false; 1713 bool realign = false;
1702 1714
1703 if (clipboardHasDifferentAlignment(v, from)) { 1715 if (clipboardHasDifferentAlignment(v, from)) {
1704 1716
1705 QMessageBox::StandardButton button = 1717 QMessageBox::StandardButton button =
1706 QMessageBox::question(v, tr("Re-align pasted items?"), 1718 QMessageBox::question(v->getView(), tr("Re-align pasted items?"),
1707 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?"), 1719 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?"),
1708 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, 1720 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
1709 QMessageBox::Yes); 1721 QMessageBox::Yes);
1710 1722
1711 if (button == QMessageBox::Cancel) { 1723 if (button == QMessageBox::Cancel) {