📄 compositionmodelimpl.cpp
字号:
void CompositionModelImpl::signalSelection(){ // RG_DEBUG << "CompositionModelImpl::signalSelection()\n"; emit selectedSegments(getSelectedSegments());}void CompositionModelImpl::signalContentChange(){ // RG_DEBUG << "CompositionModelImpl::signalContentChange" << endl; emit needContentUpdate();}void CompositionModelImpl::clearSelected(){ RG_DEBUG << "CompositionModelImpl::clearSelected" << endl; m_selectedSegments.clear(); emit needContentUpdate();}bool CompositionModelImpl::isSelected(const CompositionItem& ci) const{ const CompositionItemImpl* itemImpl = dynamic_cast<const CompositionItemImpl*>((_CompositionItem*)ci); return itemImpl ? isSelected(itemImpl->getSegment()) : 0;}bool CompositionModelImpl::isSelected(const Segment* s) const{ return m_selectedSegments.find(const_cast<Segment*>(s)) != m_selectedSegments.end();}bool CompositionModelImpl::isTmpSelected(const Segment* s) const{ return m_tmpSelectedSegments.find(const_cast<Segment*>(s)) != m_tmpSelectedSegments.end();}bool CompositionModelImpl::wasTmpSelected(const Segment* s) const{ return m_previousTmpSelectedSegments.find(const_cast<Segment*>(s)) != m_previousTmpSelectedSegments.end();}void CompositionModelImpl::startChange(const CompositionItem& item, CompositionModel::ChangeType change){ m_changeType = change; itemcontainer::iterator i = m_changingItems.find(item); // if an "identical" composition item has already been inserted, drop this one if (i != m_changingItems.end()) { RG_DEBUG << "CompositionModelImpl::startChange : item already in\n"; m_itemGC.push_back(item); } else { item->saveRect(); m_changingItems.insert(item); }}void CompositionModelImpl::startChangeSelection(CompositionModel::ChangeType change){ SegmentSelection::iterator i = m_selectedSegments.begin(); for (; i != m_selectedSegments.end(); ++i) { Segment* s = *i; CompositionRect sr = computeSegmentRect(*s); startChange(CompositionItem(new CompositionItemImpl(*s, sr)), change); }}void CompositionModelImpl::endChange(){ for (itemcontainer::const_iterator i = m_changingItems.begin(); i != m_changingItems.end(); ++i) { delete *i; } m_changingItems.clear(); for (itemgc::iterator i = m_itemGC.begin(); i != m_itemGC.end(); ++i) { delete *i; } m_itemGC.clear(); RG_DEBUG << "CompositionModelImpl::endChange\n"; emit needContentUpdate();}void CompositionModelImpl::setLength(int width){ timeT endMarker = m_grid.snapX(width); m_composition.setEndMarker(endMarker);}int CompositionModelImpl::getLength(){ timeT endMarker = m_composition.getEndMarker(); int w = int(nearbyint(m_grid.getRulerScale()->getWidthForDuration(0, endMarker))); return w;}timeT CompositionModelImpl::getRepeatTimeAt(const QPoint& p, const CompositionItem& cItem){ // timeT timeAtClick = m_grid.getRulerScale()->getTimeForX(p.x()); CompositionItemImpl* itemImpl = dynamic_cast<CompositionItemImpl*>((_CompositionItem*)cItem); const Segment* s = itemImpl->getSegment(); timeT startTime = s->getStartTime(); timeT endTime = s->getEndMarkerTime(); timeT repeatInterval = endTime - startTime; int rWidth = int(nearbyint(m_grid.getRulerScale()->getXForTime(repeatInterval))); int count = (p.x() - int(itemImpl->rect().x())) / rWidth; RG_DEBUG << "CompositionModelImpl::getRepeatTimeAt() : count = " << count << endl; return count != 0 ? startTime + (count * (s->getEndMarkerTime() - s->getStartTime())) : 0;}QPoint CompositionModelImpl::computeSegmentOrigin(const Segment& s){ // Profiler profiler("CompositionModelImpl::computeSegmentOrigin", true); int trackPosition = m_composition.getTrackById(s.getTrack())->getPosition(); timeT startTime = s.getStartTime(); QPoint res; res.setX(int(nearbyint(m_grid.getRulerScale()->getXForTime(startTime)))); res.setY(m_grid.getYBinCoordinate(trackPosition)); return res;}bool CompositionModelImpl::isCachedRectCurrent(const Segment& s, const CompositionRect& r, QPoint cachedSegmentOrigin, timeT cachedSegmentEndTime){ return s.isRepeating() == r.isRepeating() && ((cachedSegmentOrigin.x() != r.x() && s.getEndMarkerTime() != cachedSegmentEndTime) || (cachedSegmentOrigin.x() == r.x() && s.getEndMarkerTime() == cachedSegmentEndTime));}void CompositionModelImpl::clearInCache(const Segment* s, bool clearPreview){ if (s) { m_segmentRectMap.erase(s); m_segmentEndTimeMap.erase(s); if (clearPreview) removePreviewCache(s); } else { // clear the whole cache m_segmentRectMap.clear(); m_segmentEndTimeMap.clear(); if (clearPreview) clearPreviewCache(); }}void CompositionModelImpl::putInCache(const Segment*s, const CompositionRect& cr){ m_segmentRectMap[s] = cr; m_segmentEndTimeMap[s] = s->getEndMarkerTime();}CompositionRect CompositionModelImpl::computeSegmentRect(const Segment& s, bool computeZ){ // Profiler profiler("CompositionModelImpl::computeSegmentRect", true); QPoint origin = computeSegmentOrigin(s); bool isRecordingSegment = isRecording(&s); if (!isRecordingSegment) { timeT endTime = 0; CompositionRect cachedCR = getFromCache(&s, endTime); // don't cache repeating segments - it's just hopeless, because the segment's rect may have to be recomputed // in other cases than just when the segment itself is moved, // for instance if another segment is moved over it if (!s.isRepeating() && cachedCR.isValid() && isCachedRectCurrent(s, cachedCR, origin, endTime)) { // RG_DEBUG << "CompositionModelImpl::computeSegmentRect() : using cache for seg " // << &s << " - cached rect repeating = " << cachedCR.isRepeating() << " - base width = " // << cachedCR.getBaseWidth() << endl; bool xChanged = origin.x() != cachedCR.x(); bool yChanged = origin.y() != cachedCR.y(); cachedCR.moveTopLeft(origin); if (s.isRepeating() && (xChanged || yChanged)) { // update repeat marks // this doesn't work in the general case (if there's another segment on the same track for instance), // it's better to simply recompute all the marks // CompositionRect::repeatmarks repeatMarks = cachedCR.getRepeatMarks(); // for(unsigned int i = 0; i < repeatMarks.size(); ++i) { // repeatMarks[i] += deltaX; // } // cachedCR.setRepeatMarks(repeatMarks); computeRepeatMarks(cachedCR, &s); } putInCache(&s, cachedCR); return cachedCR; } } timeT startTime = s.getStartTime(); timeT endTime = isRecordingSegment ? m_pointerTimePos /*s.getEndTime()*/ : s.getEndMarkerTime(); int h = m_grid.getYSnap(); int w; // RG_DEBUG << "CompositionModelImpl::computeSegmentRect: x " << origin.x() << ", y " << origin.y() << " startTime " << startTime << ", endTime " << endTime << endl; if (s.isRepeating()) { timeT repeatStart = endTime; timeT repeatEnd = s.getRepeatEndTime(); w = int(nearbyint(m_grid.getRulerScale()->getWidthForDuration(startTime, repeatEnd - startTime))); // RG_DEBUG << "CompositionModelImpl::computeSegmentRect : s is repeating - repeatStart = " // << repeatStart << " - repeatEnd : " << repeatEnd // << " w = " << w << endl; } else { w = int(nearbyint(m_grid.getRulerScale()->getWidthForDuration(startTime, endTime - startTime))); // RG_DEBUG << "CompositionModelImpl::computeSegmentRect : s is NOT repeating" // << " w = " << w << " (x for time at start is " << m_grid.getRulerScale()->getXForTime(startTime) << ", end is " << m_grid.getRulerScale()->getXForTime(endTime) << ")" << endl; } CompositionRect cr(origin, QSize(w, h)); QString label = strtoqstr(s.getLabel()); if (s.getType() == Segment::Audio) { static QRegExp re1("( *\\([^)]*\\))*$"); // (inserted) (copied) (etc) static QRegExp re2("\\.[^.]+$"); // filename suffix label.replace(re1, "").replace(re2, ""); } cr.setLabel(label); if (s.isRepeating()) { computeRepeatMarks(cr, &s); } else { cr.setBaseWidth(cr.width()); } putInCache(&s, cr); return cr;}unsigned int CompositionModelImpl::computeZForSegment(const Rosegarden::Segment* s){ return m_segmentOrderer.getZForSegment(s);}const CompositionRect& CompositionModelImpl::getFromCache(const Rosegarden::Segment* s, timeT& endTime){ endTime = m_segmentEndTimeMap[s]; return m_segmentRectMap[s];}unsigned int CompositionModelImpl::getNbRows(){ return m_composition.getNbTracks();}const CompositionModel::rectcontainer& CompositionModelImpl::getRectanglesIn(const QRect& rect, RectRanges* npData, AudioPreviewDrawData* apData){ // Profiler profiler("CompositionModelImpl::getRectanglesIn", true); m_res.clear(); // RG_DEBUG << "CompositionModelImpl::getRectanglesIn: ruler scale is " // << (dynamic_cast<SimpleRulerScale *>(m_grid.getRulerScale()))->getUnitsPerPixel() << endl; const Composition::segmentcontainer& segments = m_composition.getSegments(); Composition::segmentcontainer::iterator segEnd = segments.end(); for (Composition::segmentcontainer::iterator i = segments.begin(); i != segEnd; ++i) { // RG_DEBUG << "CompositionModelImpl::getRectanglesIn: Composition contains segment " << *i << " (" << (*i)->getStartTime() << "->" << (*i)->getEndTime() << ")"<< endl; Segment* s = *i; if (isMoving(s)) continue; CompositionRect sr = computeSegmentRect(*s); // RG_DEBUG << "CompositionModelImpl::getRectanglesIn: seg rect = " << sr << endl; if (sr.intersects(rect)) { bool tmpSelected = isTmpSelected(s), pTmpSelected = wasTmpSelected(s);// RG_DEBUG << "CompositionModelImpl::getRectanglesIn: segment " << s // << " selected : " << isSelected(s) << " - tmpSelected : " << isTmpSelected(s) << endl; if (isSelected(s) || isTmpSelected(s) || sr.intersects(m_selectionRect)) { sr.setSelected(true); } if (pTmpSelected != tmpSelected) sr.setNeedsFullUpdate(true); bool isAudio = (s && s->getType() == Segment::Audio); if (!isRecording(s)) { QColor brushColor = GUIPalette::convertColour(m_composition. getSegmentColourMap().getColourByIndex(s->getColourIndex())); sr.setBrush(brushColor); sr.setPen(CompositionColourCache::getInstance()->SegmentBorder); } else { // border is the same for both audio and MIDI sr.setPen(CompositionColourCache::getInstance()->RecordingSegmentBorder); // audio color if (isAudio) { sr.setBrush(CompositionColourCache::getInstance()->RecordingAudioSegmentBlock); // MIDI/default color } else { sr.setBrush(CompositionColourCache::getInstance()->RecordingInternalSegmentBlock); } } // Notation preview data if (npData && s->getType() == Segment::Internal) { makeNotationPreviewRects(npData, QPoint(0, sr.y()), s, rect); // Audio preview data } else if (apData && s->getType() == Segment::Audio) { makeAudioPreviewRects(apData, s, sr, rect); } m_res.push_back(sr); } else { // RG_DEBUG << "CompositionModelImpl::getRectanglesIn: - segment out of rect\n"; } } // changing items itemcontainer::iterator movEnd = m_changingItems.end(); for (itemcontainer::iterator i = m_changingItems.begin(); i != movEnd; ++i) { CompositionRect sr((*i)->rect()); if (sr.intersects(rect)) { Segment* s = CompositionItemHelper::getSegment(*i); sr.setSelected(true); QColor brushColor = GUIPalette::convertColour(m_composition.getSegmentColourMap().getColourByIndex(s->getColourIndex())); sr.setBrush(brushColor); sr.setPen(CompositionColourCache::getInstance()->SegmentBorder); // Notation preview data if (npData && s->getType() == Segment::Internal) { makeNotationPreviewRectsMovingSegment(npData, sr.topLeft(), s, sr); // Audio preview data } else if (apData && s->getType() == Segment::Audio) { makeAudioPreviewRects(apData, s, sr, rect); } m_res.push_back(sr); } } return m_res;}CompositionModel::rectlist* CompositionModelImpl::getNotationPreviewData(const Segment* s){ rectlist* npData = m_notationPreviewDataCache[const_cast<Segment*>(s)]; if (!npData) { npData = makeNotationPreviewDataCache(s); } return npData;}CompositionModel::AudioPreviewData* CompositionModelImpl::getAudioPreviewData(const Segment* s){ // Profiler profiler("CompositionModelImpl::getAudioPreviewData", true); RG_DEBUG << "CompositionModelImpl::getAudioPreviewData\n"; AudioPreviewData* apData = m_audioPreviewDataCache[const_cast<Segment*>(s)]; if (!apData) { apData = makeAudioPreviewDataCache(s); } RG_DEBUG << "CompositionModelImpl::getAudioPreviewData returning\n"; return apData;}CompositionModel::rectlist* CompositionModelImpl::makeNotationPreviewDataCache(const Segment *s){ rectlist* npData = new rectlist(); updatePreviewCacheForNotationSegment(s, npData); m_notationPreviewDataCache.insert(const_cast<Segment*>(s), npData); return npData;}CompositionModel::AudioPreviewData* CompositionModelImpl::makeAudioPreviewDataCache(const Segment *s){ RG_DEBUG << "CompositionModelImpl::makeAudioPreviewDataCache(" << s << ")" << endl; AudioPreviewData* apData = new AudioPreviewData(false, 0); // 0 channels -> empty updatePreviewCacheForAudioSegment(s, apData); m_audioPreviewDataCache.insert(const_cast<Segment*>(s), apData); return apData;}}#include "CompositionModelImpl.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -