SegmentSplitCommand::SegmentVec SegmentSplitCommand:: getNewSegments(Segment *segment, timeT splitTime, bool keepLabel) { Segment * newSegmentA = segment->clone(false); Segment * newSegmentB = new Segment(); newSegmentB->setTrack(segment->getTrack()); newSegmentB->setStartTime(splitTime); // !!! Set Composition? Event *clefEvent = 0; Event *keyEvent = 0; // Copy the last occurrence of clef and key // from the left hand side of the split (nb. timesig events // don't appear in segments, only in composition) // Segment::iterator it = segment->findTime(splitTime); while (it != segment->begin()) { --it; if (!clefEvent && (*it)->isa(Clef::EventType)) { clefEvent = new Event(**it, splitTime); } if (!keyEvent && (*it)->isa(Key::EventType)) { keyEvent = new Event(**it, splitTime); } if (clefEvent && keyEvent) break; } // Insert relevant meta info if we've found some // if (clefEvent) newSegmentB->insert(clefEvent); if (keyEvent) newSegmentB->insert(keyEvent); // Copy through the Events // it = segment->findTime(splitTime); if (it != segment->end() && (*it)->getAbsoluteTime() > splitTime) { newSegmentB->fillWithRests((*it)->getAbsoluteTime()); } while (it != segment->end()) { newSegmentB->insert(new Event(**it)); ++it; } newSegmentB->setEndTime(segment->getEndTime()); newSegmentB->setEndMarkerTime(segment->getEndMarkerTime()); // Set labels // std::string label = segment->getLabel(); newSegmentA->setLabel(label); newSegmentB->setLabel(label); if (!keepLabel) { newSegmentA->setLabel(appendLabel(label, qstrtostr(tr("(split)")))); newSegmentB->setLabel(appendLabel(label, qstrtostr(tr("(split)")))); } newSegmentB->setColourIndex(segment->getColourIndex()); newSegmentB->setTranspose(segment->getTranspose()); newSegmentB->setDelay(segment->getDelay()); // Resize left hand Segment // std::vector<Event *> toErase, toInsert; for (Segment::iterator i = newSegmentA->findTime(splitTime); i != newSegmentA->end(); ++i) { if ((*i)->getAbsoluteTime() >= splitTime) break; if ((*i)->getAbsoluteTime() + (*i)->getDuration() > splitTime) { Event *e = new Event(**i, (*i)->getAbsoluteTime(), splitTime - (*i)->getAbsoluteTime()); toErase.push_back(*i); toInsert.push_back(e); } } for (size_t i = 0; i < toErase.size(); ++i) { newSegmentA->eraseSingle(toErase[i]); delete toErase[i]; } for (size_t i = 0; i < toInsert.size(); ++i) { newSegmentA->insert(toInsert[i]); } newSegmentA->setEndTime(splitTime); newSegmentA->setEndMarkerTime(splitTime); SegmentVec segmentVec; segmentVec.reserve(2); segmentVec.push_back(newSegmentA); segmentVec.push_back(newSegmentB); return segmentVec; }
Segment * SegmentGroupInsertRangeCommand:: splitRejoin(Segment *segment) { /* Initially we have: ---|--------- SSSSSSS */ SegmentVec segmentsAC = SegmentSplitCommand::getNewSegments(segment, m_splitTime, true); Segment *segmentA = segmentsAC[0]; Segment *segmentC = segmentsAC[1]; /* Now we have two segments: ---|--------- AAA CCC */ // Move segment C as if inserting the range into composition. // This moves its end marker too, etc. segmentC->setStartTime(segmentC->getStartTime() + getRangeDuration()); /* Now all of their times are as they will be after InsertRangeCommand has executed. ---|RANGE|--- AAA CCC */ // Join A and C. SegmentVec toBeJoined; toBeJoined.reserve(2); toBeJoined.push_back(segmentA); toBeJoined.push_back(segmentC); Segment * segmentFinal = SegmentJoinCommand::makeSegment(toBeJoined); // A and C themselves will never be seen. delete segmentA; delete segmentC; /* Now we have one segment in its the final version. It starts before the range and therefore won't be moved by OpenOrCloseRangeCommand. ---|RANGE|--- FFFFFFFFFFFF */ return segmentFinal; }