Mercurial > hg > svgui
comparison layer/TimeInstantLayer.cpp @ 360:d58701996fae
* Update remaining editable layers to support proper realignment on copy/paste
* Permit pasting when no suitable layer is current: create a new layer on paste
* Add preference for showing the splash screen or not
* Rename spectrogram smoothing prefs (partly following Craig's suggestions)
author | Chris Cannam |
---|---|
date | Wed, 06 Feb 2008 14:15:09 +0000 |
parents | 020c485aa7e0 |
children | e1a9e478b7f2 |
comparison
equal
deleted
inserted
replaced
359:020c485aa7e0 | 360:d58701996fae |
---|---|
28 #include "widgets/ListInputDialog.h" | 28 #include "widgets/ListInputDialog.h" |
29 | 29 |
30 #include <QPainter> | 30 #include <QPainter> |
31 #include <QMouseEvent> | 31 #include <QMouseEvent> |
32 #include <QTextStream> | 32 #include <QTextStream> |
33 #include <QMessageBox> | |
33 | 34 |
34 #include <iostream> | 35 #include <iostream> |
35 #include <cmath> | 36 #include <cmath> |
36 | 37 |
37 TimeInstantLayer::TimeInstantLayer() : | 38 TimeInstantLayer::TimeInstantLayer() : |
721 | 722 |
722 for (SparseOneDimensionalModel::PointList::iterator i = points.begin(); | 723 for (SparseOneDimensionalModel::PointList::iterator i = points.begin(); |
723 i != points.end(); ++i) { | 724 i != points.end(); ++i) { |
724 if (s.contains(i->frame)) { | 725 if (s.contains(i->frame)) { |
725 Clipboard::Point point(i->frame, i->label); | 726 Clipboard::Point point(i->frame, i->label); |
726 | |
727 //!!! This fails, because simply being "on the same pane as" a | |
728 // particular model is not enough to give this layer the same | |
729 // alignment as it. If it was generated by deriving from another | |
730 // layer's model, that would be... but it wasn't necessarily | |
731 | |
732 point.setReferenceFrame(alignToReference(v, i->frame)); | 727 point.setReferenceFrame(alignToReference(v, i->frame)); |
733 | |
734 std::cerr << "TimeInstantLayer::copy: frame = " << i->frame << ", reference frame = " << point.getReferenceFrame() << std::endl; | |
735 | |
736 to.addPoint(point); | 728 to.addPoint(point); |
737 } | 729 } |
738 } | 730 } |
739 } | 731 } |
740 | 732 |
741 bool | 733 bool |
742 TimeInstantLayer::clipboardAlignmentDiffers(View *v, const Clipboard &clip) const | 734 TimeInstantLayer::paste(View *v, const Clipboard &from, int frameOffset, bool) |
743 { | 735 { |
744 //!!! hoist -- all pastable layers will need this | |
745 | |
746 //!!! This fails, because simply being "on the same pane as" a | |
747 // particular model is not enough to give this layer the same | |
748 // alignment as it. If it was generated by deriving from another | |
749 // layer's model, that would be... but it wasn't necessarily | |
750 | |
751 if (!m_model) return false; | 736 if (!m_model) return false; |
752 | 737 |
753 std::cerr << "TimeInstantLayer::clipboardAlignmentDiffers" << std::endl; | 738 const Clipboard::PointList &points = from.getPoints(); |
754 | 739 |
755 for (Clipboard::PointList::const_iterator i = clip.getPoints().begin(); | 740 bool realign = false; |
756 i != clip.getPoints().end(); ++i) { | 741 |
757 | 742 if (clipboardHasDifferentAlignment(v, from)) { |
758 // In principle, we want to know whether the aligned version | 743 |
759 // of the reference frame in our model is the same as the | 744 QMessageBox::StandardButton button = |
760 // source frame contained in the clipboard point. However, | 745 QMessageBox::question(v, tr("Re-align pasted instants?"), |
761 // because of rounding during alignment, that won't | 746 tr("The instants 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?"), |
762 // necessarily be the case even if the clipboard point came | 747 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, |
763 // from our model! What we need to check is whether, if we | 748 QMessageBox::Yes); |
764 // aligned the clipboard point's frame back to the reference | 749 |
765 // using this model's alignment, we would obtain the same | 750 if (button == QMessageBox::Cancel) { |
766 // reference frame as that for the clipboard point. | 751 return false; |
767 | |
768 // What if the clipboard point has no reference frame? Then | |
769 // we have to treat it as having its own frame as the | |
770 // reference (i.e. having been copied from the reference | |
771 // model). | |
772 | |
773 long sourceFrame = i->getFrame(); | |
774 long referenceFrame = sourceFrame; | |
775 if (i->haveReferenceFrame()) { | |
776 referenceFrame = i->getReferenceFrame(); | |
777 } | 752 } |
778 long myMappedFrame = alignToReference(v, sourceFrame); | 753 |
779 | 754 if (button == QMessageBox::Yes) { |
780 std::cerr << "sourceFrame = " << sourceFrame << ", referenceFrame = " << referenceFrame << " (have = " << i->haveReferenceFrame() << "), myMappedFrame = " << myMappedFrame << std::endl; | 755 realign = true; |
781 | 756 } |
782 if (myMappedFrame != referenceFrame) return true; | |
783 } | |
784 | |
785 return false; | |
786 } | |
787 | |
788 bool | |
789 TimeInstantLayer::paste(View *v, const Clipboard &from, int frameOffset, bool) | |
790 { | |
791 if (!m_model) return false; | |
792 | |
793 const Clipboard::PointList &points = from.getPoints(); | |
794 | |
795 //!!! | |
796 | |
797 // Clipboard::haveReferenceFrames() will return true if any of the | |
798 // items in the clipboard came from an aligned, non-reference model. | |
799 | |
800 // We need to know whether these points came from our model or not | |
801 // -- if they did, we don't want to align them. | |
802 | |
803 // If they didn't come from our model, and if reference frames are | |
804 // available, then we want to offer to align them. If reference | |
805 // frames are unavailable but they came from the reference model, | |
806 // we want to offer to align them too. | |
807 | |
808 | |
809 //!!! | |
810 | |
811 // Each point may have a reference frame that may differ from the | |
812 // point's given frame (in its source model). If it has no | |
813 // reference frame, we have to assume the source model was not | |
814 // aligned or was the reference model: when cutting or copying | |
815 // points from a layer, we must always set their reference frame | |
816 // correctly if we are aligned. | |
817 // | |
818 // When pasting: | |
819 // - if point's reference and aligned frames differ: | |
820 // - if this layer is aligned: | |
821 // - if point's aligned frame matches this layer's aligned version | |
822 // of point's reference frame: | |
823 // - we can paste at reference frame or our frame | |
824 // - else | |
825 // - we can paste at reference frame, result of aligning reference | |
826 // frame in our model, or literal source frame | |
827 // - else | |
828 // - we can paste at reference (our) frame, or literal source frame | |
829 // - else | |
830 // - if this layer is aligned: | |
831 // - we can paste at reference (point's only available) frame, | |
832 // or result of aligning reference frame in our model | |
833 // - else | |
834 // - we can only paste at reference frame | |
835 // | |
836 // Which of these alternatives are useful? | |
837 // | |
838 // Example: we paste between two tracks that are aligned to the | |
839 // same reference, and the points are at 10s and 20s in the source | |
840 // track, corresponding to 5s and 10s in the reference but 20s and | |
841 // 30s in the target track. | |
842 // | |
843 // The obvious default is to paste at 20s and 30s; if we aren't | |
844 // doing that, would it be better to paste at 5s and 10s or at 10s | |
845 // and 20s? We probably don't ever want to do the former, do we? | |
846 // We either want to be literal all the way through, or aligned | |
847 // all the way through. | |
848 | |
849 bool realign = false; | |
850 | |
851 if (clipboardAlignmentDiffers(v, from)) { | |
852 | |
853 std::cerr << "Offer alignment option..." << std::endl; | |
854 | |
855 QStringList options; | |
856 options << "Use times unchanged from the original layer"; | |
857 options << "Re-align times to match the same points in the reference layer"; | |
858 | |
859 bool ok = false; | |
860 | |
861 QString selected = ListInputDialog::getItem | |
862 (0, tr("Choose alignment"), | |
863 tr("The points you are pasting originated in a layer with different alignment from the current layer. Would you like to re-align them when pasting?"), | |
864 options, 0, &ok); | |
865 if (!ok) return false; | |
866 | |
867 if (selected == options[1]) realign = true; | |
868 } | 757 } |
869 | 758 |
870 SparseOneDimensionalModel::EditCommand *command = | 759 SparseOneDimensionalModel::EditCommand *command = |
871 new SparseOneDimensionalModel::EditCommand(m_model, tr("Paste")); | 760 new SparseOneDimensionalModel::EditCommand(m_model, tr("Paste")); |
872 | 761 |