SegmentList SegmentList::clone() const { SegmentList dl; Segment* s = _first; for (int i = 0; i < _size; ++i) { Segment* ns = s->clone(); dl.push_back(ns); s = s->next(); } dl.check(); return dl; }
/// Initialize ExpandFigurationCommand /// @author Tom Breton (Tehom) void ExpandFigurationCommand::initialise(SegmentSelection selection) { FigurationVector figs; int figSourceID = -1; bool gotFigSource = false; RG_DEBUG << "Initializing ExpandFigurationCommand" << endl; // Update, because if we need new IDs they mustn't duplicate old // IDs, so we must be up to date on what IDs are there. SegmentFigData::SegmentFigDataMap segMap = SegmentFigData::getInvolvedSegments(true, this); for (SegmentSelection::iterator i = selection.begin(); i != selection.end(); ++i) { SegmentFigData& segmentData = SegmentFigData::findOrAdd(segMap, *i); // If it's used here, it's not uninvolved, so unless it's a // figuration, it's a chord source. if (segmentData.isa(SegmentFigData::Uninvolved)) { segmentData.convertType(SegmentFigData::ChordSource); } segmentData.addTagIfNeeded(*i, this); if (gotFigSource || !segmentData.isa(SegmentFigData::FigurationSource)) { continue; } figSourceID = segmentData.getID(); figs = FigurationSourceMap::getFigurations(*i); if (!figs.empty()) { gotFigSource = true; } } // If we didn't find a real figuration, there's nothing to do. if (!gotFigSource) { return; } SourcedFiguration sourcedfigs(figSourceID, figs); // Expand figuration in each segment in selection except the // figuration segment itself. for (SegmentSelection::iterator i = selection.begin(); i != selection.end(); ++i) { Segment *s = (*i); SegmentFigData::SegmentFigDataMap::iterator it = segMap.find(*i); Q_ASSERT_X(it != segMap.end(), "ExpandFigurationCommand::initialise", "didn't find the segment"); SegmentFigData& segmentData = it->second; if (!segmentData.isa(SegmentFigData::ChordSource)) { continue; } // Make a target segment Segment *target = s->clone(false); // Temporarily attach it to composition so that expand can // work. m_composition->weakAddSegment(target); target->clear(); target->fillWithRests(s->getEndTime()); SegmentFigData::addTag(target, this, SegmentID::Target); m_newSegments.insert(target); /** Add notes to target segment **/ for (Segment::iterator e = s->begin(); e != s->end(); ++e) { // Non-notes they don't imply there's a chord here. // We add them to target segment in case they are // clefs or key changes. if ((*e)->isa(SegmentID::EventType)) { continue; } if (!(*e)->isa(Note::EventType)) { target->insert(new Event(**e)); } } // rawStartTime is the apparent start time before we take bars // into account. We step it along the composition, finding // valid places to expand. Specifically, on bar lines not // already part of an expansion. timeT rawStartTime = s->getStartTime(); while (1) { timeT figurationStartTime = rawStartTimeToExact(rawStartTime); if (rawStartTime >= s->getEndTime()) { break; } timeT timePastFiguration = SegmentFigData::expand(sourcedfigs, ChordSegment(s, segmentData.getID()), target, figurationStartTime); // If we didn't expand, ensure we don't try endlessly at // the same place. if (timePastFiguration == figurationStartTime) { ++timePastFiguration; } rawStartTime = timePastFiguration; } // Detach from composition, because SegmentInsertCommand does // the actual placing m_composition->weakDetachSegment(target); Command *c = new SegmentInsertCommand(m_composition, target, s->getTrack()); addCommand(c); } }