comparison src/MainWindow.cpp @ 174:e33f9d052503

Import pitch-track layer (currently csv-only)
author Chris Cannam
date Wed, 05 Feb 2014 19:23:55 +0000
parents 89bcb03a4849
children 515bfde8aab7
comparison
equal deleted inserted replaced
173:2067bce063a9 174:e33f9d052503
45 #include "base/Profiler.h" 45 #include "base/Profiler.h"
46 #include "base/UnitDatabase.h" 46 #include "base/UnitDatabase.h"
47 #include "layer/ColourDatabase.h" 47 #include "layer/ColourDatabase.h"
48 #include "base/Selection.h" 48 #include "base/Selection.h"
49 49
50 #include "rdf/RDFImporter.h"
51 #include "data/fileio/DataFileReaderFactory.h"
52 #include "data/fileio/CSVFormat.h"
50 #include "data/fileio/CSVFileWriter.h" 53 #include "data/fileio/CSVFileWriter.h"
51 #include "data/fileio/MIDIFileWriter.h" 54 #include "data/fileio/MIDIFileWriter.h"
52 #include "rdf/RDFExporter.h" 55 #include "rdf/RDFExporter.h"
53 56
54 // For version information 57 // For version information
421 setupRecentFilesMenu(); 424 setupRecentFilesMenu();
422 connect(&m_recentFiles, SIGNAL(recentChanged()), 425 connect(&m_recentFiles, SIGNAL(recentChanged()),
423 this, SLOT(setupRecentFilesMenu())); 426 this, SLOT(setupRecentFilesMenu()));
424 427
425 menu->addSeparator(); 428 menu->addSeparator();
429 action = new QAction(tr("Import Pitch Track Data..."), this);
430 action->setStatusTip(tr("Import pitch-track data from a file"));
431 connect(action, SIGNAL(triggered()), this, SLOT(importPitchLayer()));
432 connect(this, SIGNAL(canImportLayer(bool)), action, SLOT(setEnabled(bool)));
433 menu->addAction(action);
434
426 action = new QAction(tr("Export Pitch Track Data..."), this); 435 action = new QAction(tr("Export Pitch Track Data..."), this);
427 action->setStatusTip(tr("Export pitch-track data to a file")); 436 action->setStatusTip(tr("Export pitch-track data to a file"));
428 connect(action, SIGNAL(triggered()), this, SLOT(exportPitchLayer())); 437 connect(action, SIGNAL(triggered()), this, SLOT(exportPitchLayer()));
429 connect(this, SIGNAL(canExportLayer(bool)), action, SLOT(setEnabled(bool))); 438 connect(this, SIGNAL(canExportLayer(bool)), action, SLOT(setEnabled(bool)));
430 menu->addAction(action); 439 menu->addAction(action);
1480 return ""; 1489 return "";
1481 } 1490 }
1482 } 1491 }
1483 1492
1484 void 1493 void
1494 MainWindow::importPitchLayer()
1495 {
1496 QString path = getOpenFileName(FileFinder::LayerFileNoMidiNonSV);
1497 if (path == "") return;
1498
1499 FileOpenStatus status = importPitchLayer(path);
1500
1501 if (status == FileOpenFailed) {
1502 emit hideSplash();
1503 QMessageBox::critical(this, tr("Failed to open file"),
1504 tr("<b>File open failed</b><p>Layer file %1 could not be opened.").arg(path));
1505 return;
1506 } else if (status == FileOpenWrongMode) {
1507 emit hideSplash();
1508 QMessageBox::critical(this, tr("Failed to open file"),
1509 tr("<b>Audio required</b><p>Unable to load layer data from \"%1\" without an audio file.<br>Please load at least one audio file before importing annotations.").arg(path));
1510 }
1511 }
1512
1513 MainWindow::FileOpenStatus
1514 MainWindow::importPitchLayer(FileSource source)
1515 {
1516 if (!source.isAvailable()) return FileOpenFailed;
1517 source.waitForData();
1518
1519 QString path = source.getLocalFilename();
1520
1521 RDFImporter::RDFDocumentType rdfType =
1522 RDFImporter::identifyDocumentType(QUrl::fromLocalFile(path).toString());
1523
1524 if (rdfType != RDFImporter::NotRDF) {
1525
1526 //!!!
1527 return FileOpenFailed;
1528
1529 } else if (source.getExtension().toLower() == "svl" ||
1530 (source.getExtension().toLower() == "xml" &&
1531 (SVFileReader::identifyXmlFile(source.getLocalFilename())
1532 == SVFileReader::SVLayerFile))) {
1533
1534 //!!!
1535 return FileOpenFailed;
1536
1537 } else {
1538
1539 try {
1540
1541 CSVFormat format(path);
1542 format.setSampleRate(getMainModel()->getSampleRate());
1543
1544 if (format.getModelType() != CSVFormat::TwoDimensionalModel) {
1545 //!!! error report
1546 return FileOpenFailed;
1547 }
1548
1549 Model *model = DataFileReaderFactory::loadCSV
1550 (path, format, getMainModel()->getSampleRate());
1551
1552 if (model) {
1553
1554 SVDEBUG << "MainWindow::importPitchLayer: Have model" << endl;
1555
1556 CommandHistory::getInstance()->startCompoundOperation
1557 (tr("Import Pitch Track"), true);
1558
1559 Layer *newLayer = m_document->createImportedLayer(model);
1560
1561 m_analyser->takePitchTrackFrom(newLayer);
1562
1563 m_document->deleteLayer(newLayer);
1564
1565 CommandHistory::getInstance()->endCompoundOperation();
1566
1567 //!!! swap all data in to existing layer instead of this
1568
1569 m_recentFiles.addFile(source.getLocation());
1570
1571 if (!source.isRemote()) {
1572 registerLastOpenedFilePath
1573 (FileFinder::LayerFile,
1574 path); // for file dialog
1575 }
1576
1577 return FileOpenSucceeded;
1578 }
1579 } catch (DataFileReaderFactory::Exception e) {
1580 if (e == DataFileReaderFactory::ImportCancelled) {
1581 return FileOpenCancelled;
1582 }
1583 }
1584 }
1585
1586 return FileOpenFailed;
1587 }
1588
1589 void
1485 MainWindow::exportPitchLayer() 1590 MainWindow::exportPitchLayer()
1486 { 1591 {
1487 Layer *layer = 0; 1592 Layer *layer = m_analyser->getLayer(Analyser::PitchTrack);
1488 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
1489 Pane *pane = m_paneStack->getPane(i);
1490 for (int j = 0; j < pane->getLayerCount(); ++j) {
1491 layer = qobject_cast<TimeValueLayer *>(pane->getLayer(j));
1492 if (layer) break;
1493 }
1494 if (layer) break;
1495 }
1496
1497 if (!layer) return; 1593 if (!layer) return;
1498 1594
1499 SparseTimeValueModel *model = 1595 SparseTimeValueModel *model =
1500 qobject_cast<SparseTimeValueModel *>(layer->getModel()); 1596 qobject_cast<SparseTimeValueModel *>(layer->getModel());
1501 if (!model) return; 1597 if (!model) return;
1544 } 1640 }
1545 1641
1546 void 1642 void
1547 MainWindow::exportNoteLayer() 1643 MainWindow::exportNoteLayer()
1548 { 1644 {
1549 Layer *layer = 0; 1645 Layer *layer = m_analyser->getLayer(Analyser::Notes);
1550 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
1551 Pane *pane = m_paneStack->getPane(i);
1552 for (int j = 0; j < pane->getLayerCount(); ++j) {
1553 layer = qobject_cast<FlexiNoteLayer *>(pane->getLayer(j));
1554 if (layer) break;
1555 }
1556 if (layer) break;
1557 }
1558
1559 if (!layer) return; 1646 if (!layer) return;
1560 1647
1561 FlexiNoteModel *model = qobject_cast<FlexiNoteModel *>(layer->getModel()); 1648 FlexiNoteModel *model = qobject_cast<FlexiNoteModel *>(layer->getModel());
1562 if (!model) return; 1649 if (!model) return;
1563 1650
1607 if (error != "") { 1694 if (error != "") {
1608 QMessageBox::critical(this, tr("Failed to write file"), error); 1695 QMessageBox::critical(this, tr("Failed to write file"), error);
1609 } else { 1696 } else {
1610 m_recentFiles.addFile(path); 1697 m_recentFiles.addFile(path);
1611 emit activity(tr("Export layer to \"%1\"").arg(path)); 1698 emit activity(tr("Export layer to \"%1\"").arg(path));
1612 }
1613 }
1614
1615
1616 void
1617 MainWindow::renameCurrentLayer()
1618 {
1619 Pane *pane = m_paneStack->getCurrentPane();
1620 if (pane) {
1621 Layer *layer = pane->getSelectedLayer();
1622 if (layer) {
1623 bool ok = false;
1624 QString newName = QInputDialog::getText
1625 (this, tr("Rename Layer"),
1626 tr("New name for this layer:"),
1627 QLineEdit::Normal, layer->objectName(), &ok);
1628 if (ok) {
1629 layer->setObjectName(newName);
1630 }
1631 }
1632 } 1699 }
1633 } 1700 }
1634 1701
1635 void 1702 void
1636 MainWindow::doubleClickSelectInvoked(size_t frame) 1703 MainWindow::doubleClickSelectInvoked(size_t frame)
2181 m_playTarget, SLOT(setOutputGain(float))); 2248 m_playTarget, SLOT(setOutputGain(float)));
2182 } 2249 }
2183 2250
2184 if (model) { 2251 if (model) {
2185 if (m_paneStack) { 2252 if (m_paneStack) {
2186 Pane *pane = m_paneStack->getCurrentPane(); 2253
2187 if (!pane) { 2254 int pc = m_paneStack->getPaneCount();
2255 Pane *pane = 0;
2256
2257 if (pc < 1) {
2188 pane = m_paneStack->addPane(); 2258 pane = m_paneStack->addPane();
2189 2259
2190 Pane *selectionStrip = m_paneStack->addPane(); 2260 Pane *selectionStrip = m_paneStack->addPane();
2191 selectionStrip->setFixedHeight(26); 2261 selectionStrip->setFixedHeight(26);
2192 m_document->addLayerToView 2262 m_document->addLayerToView
2195 m_paneStack->sizePanesEqually(); 2265 m_paneStack->sizePanesEqually();
2196 2266
2197 m_viewManager->clearToolModeOverrides(); 2267 m_viewManager->clearToolModeOverrides();
2198 m_viewManager->setToolModeFor(selectionStrip, 2268 m_viewManager->setToolModeFor(selectionStrip,
2199 ViewManager::SelectMode); 2269 ViewManager::SelectMode);
2270 } else {
2271 pane = m_paneStack->getPane(0);
2200 } 2272 }
2273
2201 if (pane) { 2274 if (pane) {
2202 QString error = m_analyser->newFileLoaded 2275 QString error = m_analyser->newFileLoaded
2203 (m_document, getMainModel(), m_paneStack, pane); 2276 (m_document, getMainModel(), m_paneStack, pane);
2204 if (error != "") { 2277 if (error != "") {
2205 QMessageBox::warning 2278 QMessageBox::warning