comparison framework/MainWindowBase.cpp @ 101:89a689720ee9 spectrogram-cache-rejig

* Merge from trunk
author Chris Cannam
date Wed, 27 Feb 2008 11:59:42 +0000
parents eb596ef12041
children
comparison
equal deleted inserted replaced
59:bf1a53489ccc 101:89a689720ee9
199 m_labeller->setCounterCycleSize(cycle); 199 m_labeller->setCounterCycleSize(cycle);
200 } 200 }
201 201
202 MainWindowBase::~MainWindowBase() 202 MainWindowBase::~MainWindowBase()
203 { 203 {
204 delete m_playTarget; 204 if (m_playTarget) m_playTarget->shutdown();
205 // delete m_playTarget;
205 delete m_playSource; 206 delete m_playSource;
206 delete m_viewManager; 207 delete m_viewManager;
207 delete m_oscQueue; 208 delete m_oscQueue;
208 Profiles::getInstance()->dump(); 209 Profiles::getInstance()->dump();
209 } 210 }
274 Pane *currentPane = 0; 275 Pane *currentPane = 0;
275 Layer *currentLayer = 0; 276 Layer *currentLayer = 0;
276 277
277 if (m_paneStack) currentPane = m_paneStack->getCurrentPane(); 278 if (m_paneStack) currentPane = m_paneStack->getCurrentPane();
278 if (currentPane) currentLayer = currentPane->getSelectedLayer(); 279 if (currentPane) currentLayer = currentPane->getSelectedLayer();
280
281 bool havePrevPane = false, haveNextPane = false;
282 bool havePrevLayer = false, haveNextLayer = false;
283
284 if (currentPane) {
285 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
286 if (m_paneStack->getPane(i) == currentPane) {
287 if (i > 0) havePrevPane = true;
288 if (i < m_paneStack->getPaneCount()-1) haveNextPane = true;
289 break;
290 }
291 }
292 if (currentLayer) {
293 for (int i = 0; i < currentPane->getLayerCount(); ++i) {
294 if (currentPane->getLayer(i) == currentLayer) {
295 if (i > 0) havePrevLayer = true;
296 if (i < currentPane->getLayerCount()-1) haveNextLayer = true;
297 break;
298 }
299 }
300 }
301 }
279 302
280 bool haveCurrentPane = 303 bool haveCurrentPane =
281 (currentPane != 0); 304 (currentPane != 0);
282 bool haveCurrentLayer = 305 bool haveCurrentLayer =
283 (haveCurrentPane && 306 (haveCurrentPane &&
319 emit canMeasureLayer(haveCurrentLayer); 342 emit canMeasureLayer(haveCurrentLayer);
320 emit canSelect(haveMainModel && haveCurrentPane); 343 emit canSelect(haveMainModel && haveCurrentPane);
321 emit canPlay(havePlayTarget); 344 emit canPlay(havePlayTarget);
322 emit canFfwd(true); 345 emit canFfwd(true);
323 emit canRewind(true); 346 emit canRewind(true);
324 emit canPaste(haveCurrentEditableLayer && haveClipboardContents); 347 emit canPaste(haveClipboardContents);
325 emit canInsertInstant(haveCurrentPane); 348 emit canInsertInstant(haveCurrentPane);
326 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection); 349 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection);
327 emit canRenumberInstants(haveCurrentTimeInstantsLayer && haveSelection); 350 emit canRenumberInstants(haveCurrentTimeInstantsLayer && haveSelection);
328 emit canPlaySelection(haveMainModel && havePlayTarget && haveSelection); 351 emit canPlaySelection(haveMainModel && havePlayTarget && haveSelection);
329 emit canClearSelection(haveSelection); 352 emit canClearSelection(haveSelection);
330 emit canEditSelection(haveSelection && haveCurrentEditableLayer); 353 emit canEditSelection(haveSelection && haveCurrentEditableLayer);
331 emit canSave(m_sessionFile != "" && m_documentModified); 354 emit canSave(m_sessionFile != "" && m_documentModified);
355 emit canSelectPreviousPane(havePrevPane);
356 emit canSelectNextPane(haveNextPane);
357 emit canSelectPreviousLayer(havePrevLayer);
358 emit canSelectNextLayer(haveNextLayer);
332 } 359 }
333 360
334 void 361 void
335 MainWindowBase::documentModified() 362 MainWindowBase::documentModified()
336 { 363 {
420 if (m_viewManager) m_viewManager->setPlaybackModel(0); 447 if (m_viewManager) m_viewManager->setPlaybackModel(0);
421 return; 448 return;
422 } 449 }
423 450
424 Model *prevPlaybackModel = m_viewManager->getPlaybackModel(); 451 Model *prevPlaybackModel = m_viewManager->getPlaybackModel();
452
453 // What we want here is not the currently playing frame (unless we
454 // are about to clear out the audio playback buffers -- which may
455 // or may not be possible, depending on the audio driver). What
456 // we want is the frame that was last committed to the soundcard
457 // buffers, as the audio driver will continue playing up to that
458 // frame before switching to whichever one we decide we want to
459 // switch to, regardless of our efforts.
460
461 int frame = m_playSource->getCurrentBufferedFrame();
462
463 // std::cerr << "currentPaneChanged: current frame (in ref model) = " << frame << std::endl;
425 464
426 View::ModelSet soloModels = p->getModels(); 465 View::ModelSet soloModels = p->getModels();
427 466
428 View::ModelSet sources; 467 View::ModelSet sources;
429 for (View::ModelSet::iterator mi = soloModels.begin(); 468 for (View::ModelSet::iterator mi = soloModels.begin();
435 for (View::ModelSet::iterator mi = sources.begin(); 474 for (View::ModelSet::iterator mi = sources.begin();
436 mi != sources.end(); ++mi) { 475 mi != sources.end(); ++mi) {
437 soloModels.insert(*mi); 476 soloModels.insert(*mi);
438 } 477 }
439 478
479 //!!! Need an "atomic" way of telling the play source that the
480 //playback model has changed, and changing it on ViewManager --
481 //the play source should be making the setPlaybackModel call to
482 //ViewManager
483
440 for (View::ModelSet::iterator mi = soloModels.begin(); 484 for (View::ModelSet::iterator mi = soloModels.begin();
441 mi != soloModels.end(); ++mi) { 485 mi != soloModels.end(); ++mi) {
442 if (dynamic_cast<RangeSummarisableTimeValueModel *>(*mi)) { 486 if (dynamic_cast<RangeSummarisableTimeValueModel *>(*mi)) {
443 m_viewManager->setPlaybackModel(*mi); 487 m_viewManager->setPlaybackModel(*mi);
444 } 488 }
451 getPlaybackModel()); 495 getPlaybackModel());
452 496
453 m_playSource->setSoloModelSet(soloModels); 497 m_playSource->setSoloModelSet(soloModels);
454 498
455 if (a && b && (a != b)) { 499 if (a && b && (a != b)) {
456 int frame = m_playSource->getCurrentPlayingFrame(); 500 if (m_playSource->isPlaying()) m_playSource->play(frame);
457 //!!! I don't really believe that these functions are the right way around
458 int rframe = a->alignFromReference(frame);
459 int bframe = b->alignToReference(rframe);
460 if (m_playSource->isPlaying()) m_playSource->play(bframe);
461 } 501 }
462 } 502 }
463 503
464 void 504 void
465 MainWindowBase::currentLayerChanged(Pane *p, Layer *) 505 MainWindowBase::currentLayerChanged(Pane *p, Layer *)
534 574
535 CommandHistory::getInstance()->startCompoundOperation(tr("Cut"), true); 575 CommandHistory::getInstance()->startCompoundOperation(tr("Cut"), true);
536 576
537 for (MultiSelection::SelectionList::iterator i = selections.begin(); 577 for (MultiSelection::SelectionList::iterator i = selections.begin();
538 i != selections.end(); ++i) { 578 i != selections.end(); ++i) {
539 layer->copy(*i, clipboard); 579 layer->copy(currentPane, *i, clipboard);
540 layer->deleteSelection(*i); 580 layer->deleteSelection(*i);
541 } 581 }
542 582
543 CommandHistory::getInstance()->endCompoundOperation(); 583 CommandHistory::getInstance()->endCompoundOperation();
544 } 584 }
557 597
558 MultiSelection::SelectionList selections = m_viewManager->getSelections(); 598 MultiSelection::SelectionList selections = m_viewManager->getSelections();
559 599
560 for (MultiSelection::SelectionList::iterator i = selections.begin(); 600 for (MultiSelection::SelectionList::iterator i = selections.begin();
561 i != selections.end(); ++i) { 601 i != selections.end(); ++i) {
562 layer->copy(*i, clipboard); 602 layer->copy(currentPane, *i, clipboard);
563 } 603 }
564 } 604 }
565 605
566 void 606 void
567 MainWindowBase::paste() 607 MainWindowBase::paste()
568 { 608 {
569 Pane *currentPane = m_paneStack->getCurrentPane(); 609 Pane *currentPane = m_paneStack->getCurrentPane();
570 if (!currentPane) return; 610 if (!currentPane) return;
571 611
572 //!!! if we have no current layer, we should create one of the most
573 // appropriate type
574
575 Layer *layer = currentPane->getSelectedLayer(); 612 Layer *layer = currentPane->getSelectedLayer();
576 if (!layer) return;
577 613
578 Clipboard &clipboard = m_viewManager->getClipboard(); 614 Clipboard &clipboard = m_viewManager->getClipboard();
579 Clipboard::PointList contents = clipboard.getPoints(); 615 // Clipboard::PointList contents = clipboard.getPoints();
580 /* 616
581 long minFrame = 0; 617 bool inCompound = false;
582 bool have = false; 618
583 for (int i = 0; i < contents.size(); ++i) { 619 if (!layer || !layer->isLayerEditable()) {
584 if (!contents[i].haveFrame()) continue; 620
585 if (!have || contents[i].getFrame() < minFrame) { 621 CommandHistory::getInstance()->startCompoundOperation
586 minFrame = contents[i].getFrame(); 622 (tr("Paste"), true);
587 have = true; 623
588 } 624 // no suitable current layer: create one of the most
589 } 625 // appropriate sort
590 626 LayerFactory::LayerType type =
591 long frameOffset = long(m_viewManager->getGlobalCentreFrame()) - minFrame; 627 LayerFactory::getInstance()->getLayerTypeForClipboardContents(clipboard);
592 628 layer = m_document->createEmptyLayer(type);
593 layer->paste(clipboard, frameOffset); 629
594 */ 630 if (!layer) {
595 layer->paste(clipboard, 0, true); 631 CommandHistory::getInstance()->endCompoundOperation();
632 return;
633 }
634
635 m_document->addLayerToView(currentPane, layer);
636 m_paneStack->setCurrentLayer(currentPane, layer);
637
638 inCompound = true;
639 }
640
641 layer->paste(currentPane, clipboard, 0, true);
642
643 if (inCompound) CommandHistory::getInstance()->endCompoundOperation();
596 } 644 }
597 645
598 void 646 void
599 MainWindowBase::deleteSelected() 647 MainWindowBase::deleteSelected()
600 { 648 {
648 { 696 {
649 Pane *pane = m_paneStack->getCurrentPane(); 697 Pane *pane = m_paneStack->getCurrentPane();
650 if (!pane) { 698 if (!pane) {
651 return; 699 return;
652 } 700 }
701
702 frame = pane->alignFromReference(frame);
653 703
654 Layer *layer = dynamic_cast<TimeInstantLayer *> 704 Layer *layer = dynamic_cast<TimeInstantLayer *>
655 (pane->getSelectedLayer()); 705 (pane->getSelectedLayer());
656 706
657 if (!layer) { 707 if (!layer) {
685 bool havePrevPoint = false; 735 bool havePrevPoint = false;
686 736
687 SparseOneDimensionalModel::EditCommand *command = 737 SparseOneDimensionalModel::EditCommand *command =
688 new SparseOneDimensionalModel::EditCommand(sodm, tr("Add Point")); 738 new SparseOneDimensionalModel::EditCommand(sodm, tr("Add Point"));
689 739
690 if (m_labeller->actingOnPrevPoint()) { 740 if (m_labeller->requiresPrevPoint()) {
691 741
692 SparseOneDimensionalModel::PointList prevPoints = 742 SparseOneDimensionalModel::PointList prevPoints =
693 sodm->getPreviousPoints(frame); 743 sodm->getPreviousPoints(frame);
694 744
695 if (!prevPoints.empty()) { 745 if (!prevPoints.empty()) {
700 750
701 if (m_labeller) { 751 if (m_labeller) {
702 752
703 m_labeller->setSampleRate(sodm->getSampleRate()); 753 m_labeller->setSampleRate(sodm->getSampleRate());
704 754
705 if (havePrevPoint) { 755 if (m_labeller->actingOnPrevPoint()) {
706 command->deletePoint(prevPoint); 756 command->deletePoint(prevPoint);
707 } 757 }
708 758
709 m_labeller->label<SparseOneDimensionalModel::Point> 759 m_labeller->label<SparseOneDimensionalModel::Point>
710 (point, havePrevPoint ? &prevPoint : 0); 760 (point, havePrevPoint ? &prevPoint : 0);
711 761
712 if (havePrevPoint) { 762 if (m_labeller->actingOnPrevPoint()) {
713 command->addPoint(prevPoint); 763 command->addPoint(prevPoint);
714 } 764 }
715 } 765 }
716 766
717 command->addPoint(point); 767 command->addPoint(point);
754 } 804 }
755 805
756 MainWindowBase::FileOpenStatus 806 MainWindowBase::FileOpenStatus
757 MainWindowBase::open(QString fileOrUrl, AudioFileOpenMode mode) 807 MainWindowBase::open(QString fileOrUrl, AudioFileOpenMode mode)
758 { 808 {
759 return open(FileSource(fileOrUrl, true), mode); 809 return open(FileSource(fileOrUrl, FileSource::ProgressDialog), mode);
760 } 810 }
761 811
762 MainWindowBase::FileOpenStatus 812 MainWindowBase::FileOpenStatus
763 MainWindowBase::open(FileSource source, AudioFileOpenMode mode) 813 MainWindowBase::open(FileSource source, AudioFileOpenMode mode)
764 { 814 {
996 bool someSuccess = false; 1046 bool someSuccess = false;
997 1047
998 for (PlaylistFileReader::Playlist::const_iterator i = playlist.begin(); 1048 for (PlaylistFileReader::Playlist::const_iterator i = playlist.begin();
999 i != playlist.end(); ++i) { 1049 i != playlist.end(); ++i) {
1000 1050
1001 FileOpenStatus status = openAudio(*i, mode); 1051 FileOpenStatus status = openAudio
1052 (FileSource(*i, FileSource::ProgressDialog), mode);
1002 1053
1003 if (status == FileOpenCancelled) { 1054 if (status == FileOpenCancelled) {
1004 return FileOpenCancelled; 1055 return FileOpenCancelled;
1005 } 1056 }
1006 1057
1047 << "): Failed to open file for reading" << std::endl; 1098 << "): Failed to open file for reading" << std::endl;
1048 return FileOpenFailed; 1099 return FileOpenFailed;
1049 } 1100 }
1050 1101
1051 SVFileReader reader(m_document, callback, source.getLocation()); 1102 SVFileReader reader(m_document, callback, source.getLocation());
1103 connect
1104 (&reader, SIGNAL(modelRegenerationFailed(QString, QString, QString)),
1105 this, SLOT(modelRegenerationFailed(QString, QString, QString)));
1106 connect
1107 (&reader, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
1108 this, SLOT(modelRegenerationWarning(QString, QString, QString)));
1052 reader.setCurrentPane(pane); 1109 reader.setCurrentPane(pane);
1053 1110
1054 QXmlInputSource inputSource(&file); 1111 QXmlInputSource inputSource(&file);
1055 reader.parse(inputSource); 1112 reader.parse(inputSource);
1056 1113
1066 1123
1067 if (!source.isRemote()) { 1124 if (!source.isRemote()) {
1068 registerLastOpenedFilePath(FileFinder::LayerFile, path); // for file dialog 1125 registerLastOpenedFilePath(FileFinder::LayerFile, path); // for file dialog
1069 } 1126 }
1070 1127
1128 return FileOpenSucceeded;
1129
1071 } else { 1130 } else {
1072 1131
1073 try { 1132 try {
1074 1133
1075 Model *model = DataFileReaderFactory::load 1134 Model *model = DataFileReaderFactory::load
1082 Layer *newLayer = m_document->createImportedLayer(model); 1141 Layer *newLayer = m_document->createImportedLayer(model);
1083 1142
1084 if (newLayer) { 1143 if (newLayer) {
1085 1144
1086 m_document->addLayerToView(pane, newLayer); 1145 m_document->addLayerToView(pane, newLayer);
1146 m_paneStack->setCurrentLayer(pane, newLayer);
1147
1087 m_recentFiles.addFile(source.getLocation()); 1148 m_recentFiles.addFile(source.getLocation());
1088 1149
1089 if (!source.isRemote()) { 1150 if (!source.isRemote()) {
1090 registerLastOpenedFilePath 1151 registerLastOpenedFilePath
1091 (FileFinder::LayerFile, 1152 (FileFinder::LayerFile,
1092 path); // for file dialog 1153 path); // for file dialog
1093 } 1154 }
1094 1155
1095 return FileOpenSucceeded; 1156 return FileOpenSucceeded;
1096 } 1157 }
1097 } 1158 }
1098 } catch (DataFileReaderFactory::Exception e) { 1159 } catch (DataFileReaderFactory::Exception e) {
1099 if (e == DataFileReaderFactory::ImportCancelled) { 1160 if (e == DataFileReaderFactory::ImportCancelled) {
1100 return FileOpenCancelled; 1161 return FileOpenCancelled;
1101 } 1162 }
1102 } 1163 }
1103 } 1164 }
1104 1165
1105 source.setLeaveLocalFile(true);
1106 return FileOpenFailed; 1166 return FileOpenFailed;
1107 } 1167 }
1108 1168
1109 MainWindowBase::FileOpenStatus 1169 MainWindowBase::FileOpenStatus
1110 MainWindowBase::openImage(FileSource source) 1170 MainWindowBase::openImage(FileSource source)
1157 } 1217 }
1158 1218
1159 MainWindowBase::FileOpenStatus 1219 MainWindowBase::FileOpenStatus
1160 MainWindowBase::openSessionFile(QString fileOrUrl) 1220 MainWindowBase::openSessionFile(QString fileOrUrl)
1161 { 1221 {
1162 return openSession(FileSource(fileOrUrl, true)); 1222 return openSession(FileSource(fileOrUrl, FileSource::ProgressDialog));
1163 } 1223 }
1164 1224
1165 MainWindowBase::FileOpenStatus 1225 MainWindowBase::FileOpenStatus
1166 MainWindowBase::openSession(FileSource source) 1226 MainWindowBase::openSession(FileSource source)
1167 { 1227 {
1180 1240
1181 PaneCallback callback(this); 1241 PaneCallback callback(this);
1182 m_viewManager->clearSelections(); 1242 m_viewManager->clearSelections();
1183 1243
1184 SVFileReader reader(m_document, callback, source.getLocation()); 1244 SVFileReader reader(m_document, callback, source.getLocation());
1245 connect
1246 (&reader, SIGNAL(modelRegenerationFailed(QString, QString, QString)),
1247 this, SLOT(modelRegenerationFailed(QString, QString, QString)));
1248 connect
1249 (&reader, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
1250 this, SLOT(modelRegenerationWarning(QString, QString, QString)));
1185 QXmlInputSource inputSource(&bzFile); 1251 QXmlInputSource inputSource(&bzFile);
1186 reader.parse(inputSource); 1252 reader.parse(inputSource);
1187 1253
1188 if (!reader.isOK()) { 1254 if (!reader.isOK()) {
1189 error = tr("SV XML file read error:\n%1").arg(reader.getErrorString()); 1255 error = tr("SV XML file read error:\n%1").arg(reader.getErrorString());
1270 connect(m_document, SIGNAL(mainModelChanged(WaveFileModel *)), 1336 connect(m_document, SIGNAL(mainModelChanged(WaveFileModel *)),
1271 this, SLOT(mainModelChanged(WaveFileModel *))); 1337 this, SLOT(mainModelChanged(WaveFileModel *)));
1272 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)), 1338 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)),
1273 this, SLOT(modelAboutToBeDeleted(Model *))); 1339 this, SLOT(modelAboutToBeDeleted(Model *)));
1274 1340
1275 connect(m_document, SIGNAL(modelGenerationFailed(QString)), 1341 connect(m_document, SIGNAL(modelGenerationFailed(QString, QString)),
1276 this, SLOT(modelGenerationFailed(QString))); 1342 this, SLOT(modelGenerationFailed(QString, QString)));
1277 connect(m_document, SIGNAL(modelRegenerationFailed(QString, QString)), 1343 connect(m_document, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
1278 this, SLOT(modelRegenerationFailed(QString, QString))); 1344 this, SLOT(modelRegenerationWarning(QString, QString, QString)));
1345 connect(m_document, SIGNAL(modelGenerationFailed(QString, QString)),
1346 this, SLOT(modelGenerationFailed(QString, QString)));
1347 connect(m_document, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
1348 this, SLOT(modelRegenerationWarning(QString, QString, QString)));
1349 connect(m_document, SIGNAL(alignmentFailed(QString, QString)),
1350 this, SLOT(alignmentFailed(QString, QString)));
1279 } 1351 }
1280 1352
1281 bool 1353 bool
1282 MainWindowBase::saveSessionFile(QString path) 1354 MainWindowBase::saveSessionFile(QString path)
1283 { 1355 {
1373 Model *model = getMainModel(); 1445 Model *model = getMainModel();
1374 if (!model) return; 1446 if (!model) return;
1375 1447
1376 size_t start = model->getStartFrame(); 1448 size_t start = model->getStartFrame();
1377 size_t end = model->getEndFrame(); 1449 size_t end = model->getEndFrame();
1450 if (m_playSource) end = std::max(end, m_playSource->getPlayEndFrame());
1378 size_t pixels = currentPane->width(); 1451 size_t pixels = currentPane->width();
1379 1452
1380 size_t sw = currentPane->getVerticalScaleWidth(); 1453 size_t sw = currentPane->getVerticalScaleWidth();
1381 if (pixels > sw * 2) pixels -= sw * 2; 1454 if (pixels > sw * 2) pixels -= sw * 2;
1382 else pixels = 1; 1455 else pixels = 1;
1532 if (!getMainModel()) return; 1605 if (!getMainModel()) return;
1533 1606
1534 int frame = m_viewManager->getPlaybackFrame(); 1607 int frame = m_viewManager->getPlaybackFrame();
1535 ++frame; 1608 ++frame;
1536 1609
1610 Pane *pane = m_paneStack->getCurrentPane();
1537 Layer *layer = getSnapLayer(); 1611 Layer *layer = getSnapLayer();
1538 size_t sr = getMainModel()->getSampleRate(); 1612 size_t sr = getMainModel()->getSampleRate();
1539 1613
1540 if (!layer) { 1614 if (!layer) {
1541 1615
1546 } 1620 }
1547 1621
1548 } else { 1622 } else {
1549 1623
1550 size_t resolution = 0; 1624 size_t resolution = 0;
1551 if (!layer->snapToFeatureFrame(m_paneStack->getCurrentPane(), 1625 if (layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
1552 frame, resolution, Layer::SnapRight)) { 1626 frame, resolution, Layer::SnapRight)) {
1627 if (pane) frame = pane->alignToReference(frame);
1628 } else {
1553 frame = getMainModel()->getEndFrame(); 1629 frame = getMainModel()->getEndFrame();
1554 } 1630 }
1555 } 1631 }
1556 1632
1557 if (frame < 0) frame = 0; 1633 if (frame < 0) frame = 0;
1583 if (!getMainModel()) return; 1659 if (!getMainModel()) return;
1584 1660
1585 int frame = m_viewManager->getPlaybackFrame(); 1661 int frame = m_viewManager->getPlaybackFrame();
1586 if (frame > 0) --frame; 1662 if (frame > 0) --frame;
1587 1663
1664 Pane *pane = m_paneStack->getCurrentPane();
1588 Layer *layer = getSnapLayer(); 1665 Layer *layer = getSnapLayer();
1589 size_t sr = getMainModel()->getSampleRate(); 1666 size_t sr = getMainModel()->getSampleRate();
1590 1667
1591 // when rewinding during playback, we want to allow a period 1668 // when rewinding during playback, we want to allow a period
1592 // following a rewind target point at which the rewind will go to 1669 // following a rewind target point at which the rewind will go to
1609 } 1686 }
1610 1687
1611 } else { 1688 } else {
1612 1689
1613 size_t resolution = 0; 1690 size_t resolution = 0;
1614 if (!layer->snapToFeatureFrame(m_paneStack->getCurrentPane(), 1691 if (layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
1615 frame, resolution, Layer::SnapLeft)) { 1692 frame, resolution, Layer::SnapLeft)) {
1693
1694 if (pane) frame = pane->alignToReference(frame);
1695 } else {
1616 frame = getMainModel()->getStartFrame(); 1696 frame = getMainModel()->getStartFrame();
1617 } 1697 }
1618 } 1698 }
1619 1699
1620 if (frame < 0) frame = 0; 1700 if (frame < 0) frame = 0;
1796 if (layer) { 1876 if (layer) {
1797 m_document->removeLayerFromView(pane, layer); 1877 m_document->removeLayerFromView(pane, layer);
1798 } 1878 }
1799 } 1879 }
1800 updateMenuStates(); 1880 updateMenuStates();
1881 }
1882
1883 void
1884 MainWindowBase::previousPane()
1885 {
1886 if (!m_paneStack) return;
1887
1888 Pane *currentPane = m_paneStack->getCurrentPane();
1889 if (!currentPane) return;
1890
1891 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
1892 if (m_paneStack->getPane(i) == currentPane) {
1893 if (i == 0) return;
1894 m_paneStack->setCurrentPane(m_paneStack->getPane(i-1));
1895 updateMenuStates();
1896 return;
1897 }
1898 }
1899 }
1900
1901 void
1902 MainWindowBase::nextPane()
1903 {
1904 if (!m_paneStack) return;
1905
1906 Pane *currentPane = m_paneStack->getCurrentPane();
1907 if (!currentPane) return;
1908
1909 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
1910 if (m_paneStack->getPane(i) == currentPane) {
1911 if (i == m_paneStack->getPaneCount()-1) return;
1912 m_paneStack->setCurrentPane(m_paneStack->getPane(i+1));
1913 updateMenuStates();
1914 return;
1915 }
1916 }
1917 }
1918
1919 void
1920 MainWindowBase::previousLayer()
1921 {
1922 //!!! Not right -- pane lists layers in stacking order
1923
1924 if (!m_paneStack) return;
1925
1926 Pane *currentPane = m_paneStack->getCurrentPane();
1927 if (!currentPane) return;
1928
1929 Layer *currentLayer = currentPane->getSelectedLayer();
1930 if (!currentLayer) return;
1931
1932 for (int i = 0; i < currentPane->getLayerCount(); ++i) {
1933 if (currentPane->getLayer(i) == currentLayer) {
1934 if (i == 0) return;
1935 m_paneStack->setCurrentLayer(currentPane,
1936 currentPane->getLayer(i-1));
1937 updateMenuStates();
1938 return;
1939 }
1940 }
1941 }
1942
1943 void
1944 MainWindowBase::nextLayer()
1945 {
1946 //!!! Not right -- pane lists layers in stacking order
1947
1948 if (!m_paneStack) return;
1949
1950 Pane *currentPane = m_paneStack->getCurrentPane();
1951 if (!currentPane) return;
1952
1953 Layer *currentLayer = currentPane->getSelectedLayer();
1954 if (!currentLayer) return;
1955
1956 for (int i = 0; i < currentPane->getLayerCount(); ++i) {
1957 if (currentPane->getLayer(i) == currentLayer) {
1958 if (i == currentPane->getLayerCount()-1) return;
1959 m_paneStack->setCurrentLayer(currentPane,
1960 currentPane->getLayer(i+1));
1961 updateMenuStates();
1962 return;
1963 }
1964 }
1801 } 1965 }
1802 1966
1803 void 1967 void
1804 MainWindowBase::playbackFrameChanged(unsigned long frame) 1968 MainWindowBase::playbackFrameChanged(unsigned long frame)
1805 { 1969 {