Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker::MarkerType markerType)
{
    Vector<IntRect> result;

    if (!possiblyHasMarkers(markerType))
        return result;
    ASSERT(!(m_markers.isEmpty()));

    // outer loop: process each node
    MarkerMap::iterator end = m_markers.end();
    for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
        // inner loop; process each marker in this node
        MarkerList* list = nodeIterator->value;
        unsigned markerCount = list->size();
        for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
            const RenderedDocumentMarker& marker = list->at(markerIndex);

            // skip marker that is wrong type
            if (marker.type() != markerType)
                continue;

            if (!marker.isRendered())
                continue;

            result.append(marker.renderedRect());
        }
    }

    return result;
}
void DocumentMarkerController::clearDescriptionOnMarkersIntersectingRange(Range* range, DocumentMarker::MarkerTypes markerTypes)
{
    if (!possiblyHasMarkers(markerTypes))
        return;
    ASSERT(!m_markers.isEmpty());

    Node* startContainer = range->startContainer();
    Node* endContainer = range->endContainer();

    Node* pastLastNode = range->pastLastNode();
    for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(node)) {
        unsigned startOffset = node == startContainer ? range->startOffset() : 0;
        unsigned endOffset = node == endContainer ? static_cast<unsigned>(range->endOffset()) : std::numeric_limits<unsigned>::max();
        MarkerList* list = m_markers.get(node);
        if (!list)
            continue;

        for (size_t i = 0; i < list->size(); ++i) {
            DocumentMarker& marker = list->at(i);

            // markers are returned in order, so stop if we are now past the specified range
            if (marker.startOffset() >= endOffset)
                break;

            // skip marker that is wrong type or before target
            if (marker.endOffset() <= startOffset || !markerTypes.contains(marker.type())) {
                i++;
                continue;
            }

            marker.clearDetails();
        }
    }
}
DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType)
{
    if (!possiblyHasMarkers(markerType))
        return 0;
    ASSERT(!(m_markers.isEmpty()));

    // outer loop: process each node that contains any markers
    MarkerMap::iterator end = m_markers.end();
    for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
        // inner loop; process each marker in this node
        MarkerList* list = nodeIterator->value;
        unsigned markerCount = list->size();
        for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
            RenderedDocumentMarker& marker = list->at(markerIndex);

            // skip marker that is wrong type
            if (marker.type() != markerType)
                continue;

            if (marker.contains(point))
                return &marker;
        }
    }

    return 0;
}
void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, int delta)
{
    if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
        return;
    ASSERT(!m_markers.isEmpty());

    MarkerList* list = m_markers.get(node);
    if (!list)
        return;

    bool docDirty = false;
    for (size_t i = 0; i != list->size(); ++i) {
        RenderedDocumentMarker& marker = list->at(i);
        if (marker.startOffset() >= startOffset) {
            ASSERT((int)marker.startOffset() + delta >= 0);
            marker.shiftOffsets(delta);
            docDirty = true;

            // Marker moved, so previously-computed rendered rectangle is now invalid
            marker.invalidate();
        }
    }

    // repaint the affected node
    if (docDirty && node->renderer())
        node->renderer()->repaint();
}
void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active)
{
    MarkerList* list = m_markers.get(node);
    if (!list)
        return;

    bool docDirty = false;
    for (size_t i = 0; i != list->size(); ++i) {
        DocumentMarker& marker = list->at(i);

        // Markers are returned in order, so stop if we are now past the specified range.
        if (marker.startOffset() >= endOffset)
            break;

        // Skip marker that is wrong type or before target.
        if (marker.endOffset() < startOffset || marker.type() != DocumentMarker::TextMatch)
            continue;

        marker.setActiveMatch(active);
        docDirty = true;
    }

    // repaint the affected node
    if (docDirty && node->renderer())
        node->renderer()->repaint();
}
void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes markerTypes)
{
    if (!possiblyHasMarkers(markerTypes))
        return;
    ASSERT(!m_markers.isEmpty());

    // outer loop: process each markered node in the document
    MarkerMap::iterator end = m_markers.end();
    for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
        Node* node = i->key.get();

        // inner loop: process each marker in the current node
        MarkerList* list = i->value.get();
        bool nodeNeedsRepaint = false;
        for (size_t i = 0; i != list->size(); ++i) {
            DocumentMarker marker = list->at(i);

            // skip nodes that are not of the specified type
            if (markerTypes.contains(marker.type())) {
                nodeNeedsRepaint = true;
                break;
            }
        }

        if (!nodeNeedsRepaint)
            continue;

        // cause the node to be redrawn
        if (auto renderer = node->renderer())
            renderer->repaint();
    }
}
void MarkerList::ValueTreeWrapper::readFrom (const MarkerList& markerList, UndoManager* undoManager)
{
    state.removeAllChildren (undoManager);

    for (int i = 0; i < markerList.getNumMarkers(); ++i)
        setMarker (*markerList.getMarker(i), undoManager);
}
示例#8
0
void CanvasNavigator::updateMarkers()
{
    MarkerList* markers = song->marker();
    for (iMarker m = markers->begin(); m != markers->end(); ++m)
    {
        QPointF point(calcSize(m->second.tick()), 0.0);
        QGraphicsRectItem* marker = m_markers.value(m->second.id());
        if(marker)
            marker->setPos(point);
    }
}
示例#9
0
// FIXME: Should be removed after all relevant patches are landed
Vector<DocumentMarker> DocumentMarkerController::markersForNode(Node* node)
{
    Vector<DocumentMarker> result;
    MarkerList* list = m_markers.get(node);
    if (!list)
        return result;

    for (size_t i = 0; i < list->size(); ++i)
        result.append(list->at(i));

    return result;
}
void DocumentMarkerController::invalidateRenderedRectsForMarkersInRect(const LayoutRect& r)
{
    // outer loop: process each markered node in the document
    MarkerMap::iterator end = m_markers.end();
    for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {

        // inner loop: process each rect in the current node
        MarkerList* list = i->value.get();
        for (size_t listIndex = 0; listIndex < list->size(); ++listIndex)
            list->at(listIndex).invalidate(r);
    }
}
Vector<RenderedDocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
{
    Vector<RenderedDocumentMarker*> result;
    MarkerList* list = m_markers.get(node);
    if (!list)
        return result;

    for (size_t i = 0; i < list->size(); ++i) {
        if (markerTypes.contains(list->at(i).type()))
            result.append(&(list->at(i)));
    }

    return result;
}
示例#12
0
void MarkerView::prevMarker()
{
	unsigned int curPos = song->cpos(); //prevent compiler warning: comparison of sigend/unsigned
	unsigned int nextPos = 0;
	MarkerList* marker = song->marker();
	for (iMarker i = marker->begin(); i != marker->end(); ++i)
	{
		if (i->second.tick() < curPos && i->second.tick() > nextPos)
			nextPos = i->second.tick();
	}
	/*      if (nextPos == 0)
			  return;*/
	Pos p(nextPos, true);
	song->setPos(0, p, true, true, false);
}
示例#13
0
void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMarker) 
{
    ASSERT(newMarker.endOffset() >= newMarker.startOffset());
    if (newMarker.endOffset() == newMarker.startOffset())
        return;

    m_possiblyExistingMarkerTypes.add(newMarker.type());

    MarkerList* list = m_markers.get(node);

    if (!list) {
        list = new MarkerList;
        list->append(RenderedDocumentMarker(newMarker));
        m_markers.set(node, list);
    } else {
        RenderedDocumentMarker toInsert(newMarker);
        size_t numMarkers = list->size();
        size_t i;
        // Iterate over all markers whose start offset is less than or equal to the new marker's.
        // If one of them is of the same type as the new marker and touches it or intersects with it
        // (there is at most one), remove it and adjust the new marker's start offset to encompass it.
        for (i = 0; i < numMarkers; ++i) {
            DocumentMarker marker = list->at(i);
            if (marker.startOffset() > toInsert.startOffset())
                break;
            if (marker.type() == toInsert.type() && marker.endOffset() >= toInsert.startOffset()) {
                toInsert.setStartOffset(marker.startOffset());
                list->remove(i);
                numMarkers--;
                break;
            }
        }
        size_t j = i;
        // Iterate over all markers whose end offset is less than or equal to the new marker's,
        // removing markers of the same type as the new marker which touch it or intersect with it,
        // adjusting the new marker's end offset to cover them if necessary.
        while (j < numMarkers) {
            DocumentMarker marker = list->at(j);
            if (marker.startOffset() > toInsert.endOffset())
                break;
            if (marker.type() == toInsert.type()) {
                list->remove(j);
                if (toInsert.endOffset() <= marker.endOffset()) {
                    toInsert.setEndOffset(marker.endOffset());
                    break;
                }
                numMarkers--;
            } else
                j++;
        }
        // At this point i points to the node before which we want to insert.
        list->insert(i, RenderedDocumentMarker(toInsert));
    }

    // repaint the affected node
    if (node->renderer())
        node->renderer()->repaint();
}
示例#14
0
void DocumentMarkerController::showMarkers() const
{
    fprintf(stderr, "%d nodes have markers:\n", m_markers.size());
    MarkerMap::const_iterator end = m_markers.end();
    for (MarkerMap::const_iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
        Node* node = nodeIterator->first.get();
        fprintf(stderr, "%p", node);
        MarkerList* list = nodeIterator->second;
        for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) {
            const DocumentMarker& marker = list->at(markerIndex);
            fprintf(stderr, " %d:[%d:%d](%d)", marker.type(), marker.startOffset(), marker.endOffset(), marker.activeMatch());
        }

        fprintf(stderr, "\n");
    }
}
//==============================================================================
void MarkerList::ValueTreeWrapper::applyTo (MarkerList& markerList)
{
    const int numMarkers = getNumMarkers();

    StringArray updatedMarkers;

    for (int i = 0; i < numMarkers; ++i)
    {
        const ValueTree marker (state.getChild (i));
        const String name (marker [nameProperty].toString());
        markerList.setMarker (name, RelativeCoordinate (marker [posProperty].toString()));
        updatedMarkers.add (name);
    }

    for (int i = markerList.getNumMarkers(); --i >= 0;)
        if (! updatedMarkers.contains (markerList.getMarker (i)->name))
            markerList.removeMarker (i);
}
示例#16
0
void MarkerView::markerChanged(int val)
{
	//if (val != Song::MARKER_CUR)
	//      return;
	// p3.3.43
	switch (val)
	{
			// MARKER_CUR, MARKER_ADD, MARKER_REMOVE, MARKER_NAME,
			// MARKER_TICK, MARKER_LOCK
		case Song::MARKER_ADD:
		case Song::MARKER_REMOVE:
			updateList();
			break; // Try falling through and let it try to select something. No, let updateList() do it...

		case Song::MARKER_CUR:
		{

			MarkerList* marker = song->marker();
			for (iMarker i = marker->begin(); i != marker->end(); ++i)
			{
				if (i->second.current())
				{
					MarkerItem* item = (MarkerItem*) table->topLevelItem(0);
					while (item)
					{
						if (item->marker() == &i->second)
						{
							table->setCurrentItem(item);
							return;
						}
						item = (MarkerItem*) table->itemBelow(item);
					}
				}
			}
		}
			break;

		default:
			break;
	}
}
// copies markers from srcNode to dstNode, applying the specified shift delta to the copies.  The shift is
// useful if, e.g., the caller has created the dstNode from a non-prefix substring of the srcNode.
void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta)
{
    if (length <= 0)
        return;

    if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
        return;
    ASSERT(!m_markers.isEmpty());

    MarkerList* list = m_markers.get(srcNode);
    if (!list)
        return;

    bool docDirty = false;
    unsigned endOffset = startOffset + length - 1;
    for (size_t i = 0; i != list->size(); ++i) {
        DocumentMarker marker = list->at(i);

        // stop if we are now past the specified range
        if (marker.startOffset() > endOffset)
            break;

        // skip marker that is before the specified range or is the wrong type
        if (marker.endOffset() < startOffset)
            continue;

        // pin the marker to the specified range and apply the shift delta
        docDirty = true;
        if (marker.startOffset() < startOffset)
            marker.setStartOffset(startOffset);
        if (marker.endOffset() > endOffset)
            marker.setEndOffset(endOffset);
        marker.shiftOffsets(delta);

        addMarker(dstNode, marker);
    }

    // repaint the affected node
    if (docDirty && dstNode->renderer())
        dstNode->renderer()->repaint();
}
void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterator, DocumentMarker::MarkerTypes markerTypes)
{
    bool needsRepainting = false;
    bool listCanBeRemoved;

    if (markerTypes == DocumentMarker::AllMarkers()) {
        needsRepainting = true;
        listCanBeRemoved = true;
    } else {
        MarkerList* list = iterator->value.get();

        for (size_t i = 0; i != list->size(); ) {
            DocumentMarker marker = list->at(i);

            // skip nodes that are not of the specified type
            if (!markerTypes.contains(marker.type())) {
                ++i;
                continue;
            }

            // pitch the old marker
            list->remove(i);
            needsRepainting = true;
            // i now is the index of the next marker
        }

        listCanBeRemoved = list->isEmpty();
    }

    if (needsRepainting) {
        if (auto renderer = iterator->key->renderer())
            renderer->repaint();
    }

    if (listCanBeRemoved) {
        m_markers.remove(iterator);
        if (m_markers.isEmpty())
            m_possiblyExistingMarkerTypes = 0;
    }
}
示例#19
0
  void Finish() {
    if (markers.empty())
      return;

    FlushScreen();
    markers.append().Set(NULL);

    for (unsigned i = 0; markers[i + 1].text != NULL; ++i) {
      const Marker &start = markers[i];
      const Marker &end = markers[i + 1];

      LogFormat("StopWatch '%s': clock=%lu cpu=%lu", start.text,
                (unsigned long)(end.clock - start.clock),
                (unsigned long)(end.cpu - start.cpu));
    }

    const Marker &start = markers.front();
    const Marker &end = markers.back();
    LogFormat("StopWatch total: clock=%lu cpu=%lu",
              (unsigned long)(end.clock - start.clock),
              (unsigned long)(end.cpu - start.cpu));

    markers.clear();
  }
示例#20
0
bool MarkerList::operator== (const MarkerList& other) const noexcept
{
    if (other.markers.size() != markers.size())
        return false;

    for (int i = markers.size(); --i >= 0;)
    {
        const Marker* const m1 = markers.getUnchecked(i);
        jassert (m1 != nullptr);

        const Marker* const m2 = other.getMarker (m1->name);

        if (m2 == nullptr || *m1 != *m2)
            return false;
    }

    return true;
}
示例#21
0
void MarkerView::updateList()
{
	// Added p3.3.43 Manage selected item, due to clearing of table...
	MarkerList* marker = song->marker();
	MarkerItem* selitem = (MarkerItem*) table->currentItem();
	Marker* selm = selitem ? selitem->marker() : 0;
	// p3.3.44 Look for removed markers before added markers...
	if (selitem)
	{
		MarkerItem* mitem = (MarkerItem*) table->topLevelItem(0);
		while (mitem)
		{
			bool found = false;
			for (iMarker i = marker->begin(); i != marker->end(); ++i)
			{
				Marker* m = &i->second;
				if (m == mitem->marker())
				{
					found = true;
					break;
				}
			}
			// Anything removed from the marker list?
			if (!found)
			{
				// If it is the current selected item, it no longer exists. Make the next item be selected.
				if (mitem == selitem)
				{
					MarkerItem* mi = (MarkerItem*) table->itemBelow(selitem);
					if (mi)
					{
						selitem = mi;
						selm = selitem->marker();
					}
				}
			}
			mitem = (MarkerItem*) table->itemBelow(mitem);
		}
	}
	// Look for added markers...
	for (iMarker i = marker->begin(); i != marker->end(); ++i)
	{
		Marker* m = &i->second;
		bool found = false;
		MarkerItem* item = (MarkerItem*) table->topLevelItem(0);
		while (item)
		{
			if (item->marker() == m)
			{
				found = true;
				break;
			}
			item = (MarkerItem*) table->itemBelow(item);
		}
		// Anything new found in the marker list?
		if (!found)
			selm = m;
	}

	// Block signals added. Triggers itemSelectionChanged() causing crash. Tim.
	table->blockSignals(true);
	table->clear();
	table->blockSignals(false);

	//MarkerList* marker = song->marker();
	for (iMarker i = marker->begin(); i != marker->end(); ++i)
	{
		Marker* m = &i->second;

		// Changed p3.3.43
		//QString tick;
		//tick.setNum(i->first);
		//new MarkerItem(table, m);
		MarkerItem* item = new MarkerItem(table, m);
		if (m == selm)
		{
			m->setCurrent(true);
			table->setCurrentItem(item);
		}
		else
		{
			m->setCurrent(false);
		}
	}
}
示例#22
0
 void Mark(const char *text) {
   FlushScreen();
   markers.append().Set(text);
 }
示例#23
0
void CanvasNavigator::updateParts()/*{{{*/
{
    m_editing = true;
    m_playhead = 0;
    m_start = 0;
    m_canvasBox =  0;
    m_punchIn = 0;
    m_punchOut = 0;
    m_parts.clear();
    m_markers.clear();
    m_scene->clear();
    /*foreach(PartItem* i, m_parts)
        m_scene->removeItem(i);
    while(m_parts.size())
        delete m_parts.takeFirst();*/
    m_heightList.clear();
    m_scene->setSceneRect(QRectF());
    int index = 1;
    //QList<QGraphicsItem*> group;
    MidiTrackList* tl = song->visibletracks();
    ciMidiTrack ci = tl->begin();
    for(; ci != tl->end(); ci++)
    {
        m_heightList.append((*ci)->height());
    }
    ci = tl->begin();
    if(ci != tl->end())
    {
        int mh = (*ci)->height();
        double partHeight = (mh * 8)/100;
        m_start = m_scene->addRect(0.0, 0.0, calcSize(song->len()), partHeight);
        m_start->setBrush(QColor(63, 63, 63));
        m_start->setPen(QPen(QColor(63, 63, 63)));
        m_start->setZValue(-50);
        ci++;//Special case for master
    }
    for(; ci != tl->end(); ci++)
    {
        MidiTrack* track = *ci;
        if(track)
        {
            QList<int> list = m_heightList.mid(0, index);
            int ypos = 0;
            foreach(int i, list)
                ypos += i;
            ypos = (ypos * 8)/100;
            int ih = m_heightList.at(index);
            double partHeight = (ih * 8)/100;

            //qDebug("CanvasNavigator::updateParts: partHeight: %2f, ypos: %d", partHeight, ypos);
            PartList* parts = track->parts();
            if(parts && !parts->empty())
            {
                for(iPart p = parts->begin(); p != parts->end(); p++)
                {
                    Part *part =  p->second;

                    int tick, len;
                    if(part)
                    {
                        tick = part->tick();
                        len = part->lenTick();
                    }
                    double w = calcSize(len);
                    double pos = calcSize(tick);

                    PartItem* item = new PartItem(pos, ypos, w, partHeight);
                    item->setPart(part);
                    m_parts.append(item);
                    //group.append((QGraphicsItem*)item);
                    int i = part->colorIndex();
                    QColor partWaveColor(config.partWaveColors[i]);
                    QColor partColor(config.partColors[i]);
                    //partWaveColor.setAlpha(150);
                    partColor.setAlpha(150);
                    item->setBrush(part->selected() ? partWaveColor : partColor);
                    item->setPen(part->selected() ? partColor : partWaveColor);
                    m_scene->addItem(item);
                }
            }
            ++index;
        }
    }
    QColor colTimeLine = QColor(0, 186, 255);
    int kpos = 0;
    foreach(int i, m_heightList)
        kpos += i;
    //kpos = ((kpos + 400) * 8)/100;
    kpos = ((kpos + 400) * 8)/100;

    m_playhead = new QGraphicsRectItem(0, 0, 1, kpos);
    m_playhead->setBrush(colTimeLine);
    m_playhead->setPen(Qt::NoPen);
    m_playhead->setZValue(124001.0f);
    m_playhead->setFlags(QGraphicsItem::ItemIgnoresTransformations);
    m_scene->addItem(m_playhead);
    QColor loopColor(139, 225, 69);
    QColor markerColor(243,191,124);
    MarkerList* markers = song->marker();
    for (iMarker m = markers->begin(); m != markers->end(); ++m)
    {
        //double xp = calcSize(m->second.tick());
        QGraphicsRectItem *marker = m_scene->addRect(0, 0, 1, kpos);
        marker->setData(Qt::UserRole, m->second.id());
        m_markers[m->second.id()] = marker;
        marker->setPen(Qt::NoPen);
        marker->setBrush(markerColor);
        marker->setZValue(124002.0f);
        marker->setFlags(QGraphicsItem::ItemIgnoresTransformations);
        m_updateMarkers = true;
    }

    m_punchIn = new QGraphicsRectItem(0, 0, 1, kpos);
    m_punchIn->setBrush(loopColor);
    m_punchIn->setPen(Qt::NoPen);
    m_punchIn->setZValue(124003.0f);
    m_punchIn->setFlags(QGraphicsItem::ItemIgnoresTransformations);
    m_scene->addItem(m_punchIn);
    m_punchIn->setVisible(song->loop() || song->punchin());

    m_punchOut = new QGraphicsRectItem(0, 0, 1, kpos);
    m_punchOut->setBrush(loopColor);
    m_punchOut->setPen(Qt::NoPen);
    m_punchOut->setZValue(124003.0f);
    m_punchOut->setFlags(QGraphicsItem::ItemIgnoresTransformations);
    m_scene->addItem(m_punchOut);
    m_punchOut->setVisible(song->loop() || song->punchout());

    createCanvasBox();

    //group.append((QGraphicsItem*)m_start);
    //group.append((QGraphicsItem*)m_playhead);
    //if(group.size())
    //{
    //	m_partGroup = m_scene->createItemGroup(group);
    //}
    //else
    m_partGroup = 0;
    updateSpacing();
    m_editing = false;
}/*}}}*/
示例#24
0
void adjustGlobalLists(Undo& operations, int startPos, int diff)
{
  const TempoList* t = &MusEGlobal::tempomap;
  const AL::SigList* s   = &AL::sigmap;
  const KeyList* k   = &MusEGlobal::keymap;

  criTEvent it   = t->rbegin();
  AL::criSigEvent is = s->rbegin();
  criKeyEvent ik = k->rbegin();

  // key
  for (; ik != k->rend(); ik++) {
    const KeyEvent &ev = (KeyEvent)ik->second;
    int tick = ev.tick;
    int key = ev.key;
    if (tick < startPos )
      break;

    if (tick > startPos && tick +diff < startPos ) { // remove
      operations.push_back(UndoOp(UndoOp::DeleteKey, tick, key));
    }
    else {
      operations.push_back(UndoOp(UndoOp::DeleteKey,tick, key));
      operations.push_back(UndoOp(UndoOp::AddKey,tick+diff, key));
      }
  }

  // tempo
  for (; it != t->rend(); it++) {
    const TEvent* ev = (TEvent*)it->second;
    int tick = ev->tick;
    int tempo = ev->tempo;
    if (tick < startPos )
      break;

    if (tick > startPos && tick +diff < startPos ) { // remove
      operations.push_back(UndoOp(UndoOp::DeleteTempo,tick, tempo));
    }
    else {
      operations.push_back(UndoOp(UndoOp::DeleteTempo,tick, tempo));
      operations.push_back(UndoOp(UndoOp::AddTempo,tick+diff, tempo));
      }
  }

  // sig
  for (; is != s->rend(); is++) {
    const AL::SigEvent* ev = (AL::SigEvent*)is->second;
    int tick = ev->tick;
    if (tick < startPos )
      break;

    int z = ev->sig.z;
    int n = ev->sig.n;
    if (tick > startPos && tick +diff < startPos ) { // remove
      operations.push_back(UndoOp(UndoOp::DeleteSig,tick, z, n));
    }
    else {
      operations.push_back(UndoOp(UndoOp::DeleteSig,tick, z, n));
      operations.push_back(UndoOp(UndoOp::AddSig,tick+diff, z, n));
    }
  }

  MarkerList *markerlist = MusEGlobal::song->marker();
  for(iMarker i = markerlist->begin(); i != markerlist->end(); ++i)
  {
      Marker* m = &i->second;
      int tick = m->tick();
      if (tick > startPos)
      {
        if (tick + diff < startPos ) { // these ticks should be removed
          operations.push_back(UndoOp(UndoOp::ModifyMarker, 0, m));    
        } else {
          Marker *newMarker = new Marker();
          *newMarker = *m;
          newMarker->setTick(tick + diff);  
          operations.push_back(UndoOp(UndoOp::ModifyMarker, newMarker, m));
        }
      }
  }

}
void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
{
    if (length <= 0)
        return;

    if (!possiblyHasMarkers(markerTypes))
        return;
    ASSERT(!(m_markers.isEmpty()));

    MarkerList* list = m_markers.get(node);
    if (!list)
        return;

    bool docDirty = false;
    unsigned endOffset = startOffset + length;
    for (size_t i = 0; i < list->size();) {
        DocumentMarker marker = list->at(i);

        // markers are returned in order, so stop if we are now past the specified range
        if (marker.startOffset() >= endOffset)
            break;

        // skip marker that is wrong type or before target
        if (marker.endOffset() <= startOffset || !markerTypes.contains(marker.type())) {
            i++;
            continue;
        }

        // at this point we know that marker and target intersect in some way
        docDirty = true;

        // pitch the old marker
        list->remove(i);

        if (shouldRemovePartiallyOverlappingMarker)
            // Stop here. Don't add resulting slices back.
            continue;

        // add either of the resulting slices that are left after removing target
        if (startOffset > marker.startOffset()) {
            DocumentMarker newLeft = marker;
            newLeft.setEndOffset(startOffset);
            list->insert(i, RenderedDocumentMarker(newLeft));
            // i now points to the newly-inserted node, but we want to skip that one
            i++;
        }
        if (marker.endOffset() > endOffset) {
            DocumentMarker newRight = marker;
            newRight.setStartOffset(endOffset);
            list->insert(i, RenderedDocumentMarker(newRight));
            // i now points to the newly-inserted node, but we want to skip that one
            i++;
        }
    }

    if (list->isEmpty()) {
        m_markers.remove(node);
        if (m_markers.isEmpty())
            m_possiblyExistingMarkerTypes = 0;
    }

    // repaint the affected node
    if (docDirty && node->renderer())
        node->renderer()->repaint();
}
示例#26
0
文件: mtscale.cpp 项目: Adamiko/los
void MTScale::pdraw(QPainter& p, const QRect& r)
{
	QColor colTimeLine = QColor(172,181,176);
	int x = r.x();
	int w = r.width();

	//printf("MTScale::pdraw x:%d w:%d\n", x, w);

	x -= 20;
	w += 40; // wg. Text

	//---------------------------------------------------
	//    draw Marker
	//---------------------------------------------------

	int y = 12;
	p.setPen(colTimeLine);
	p.setFont(QFont("fixed-width", 9, QFont::Bold));
	p.drawLine(r.x(), y + 1, r.x() + r.width(), y + 1);
	QRect tr(r);
	tr.setHeight(12);
	MarkerList* marker = song->marker();
	for (iMarker m = marker->begin(); m != marker->end(); ++m)
	{

		int xp;
		if (waveMode)
			xp = mapx(m->second.frame());
		else
			xp = mapx(m->second.tick());
		if (xp > x + w)
			break;
		int xe = r.x() + r.width();
		iMarker mm = m;
		++mm;
		if (mm != marker->end())
		{

			if (waveMode)
				xe = mapx(tempomap.tick2frame(mm->first));
			else
				xe = mapx(mm->first);
		}

		QRect tr(xp, 0, xe - xp, 13);

		QRect wr = r.intersect(tr);
		if (!wr.isEmpty())
		{
			if (m->second.current())
			{
				p.fillRect(wr, QColor(89, 89, 102));
			}

			int x2;
			if (mm != marker->end())
			{
				if (waveMode)
					x2 = mapx(tempomap.tick2frame(mm->first));
				else
					x2 = mapx(mm->first);
			}
			else
				x2 = xp + 200;

			//printf("MTScale::pdraw marker %s xp:%d y:%d h:%d r.x:%d r.w:%d\n", m->second.name().toLatin1(), xp, height(), y, r.x(), r.width());

			// Must be reasonable about very low negative x values! With long songs > 15min
			//  and with high horizontal magnification, 'ghost' drawings appeared,
			//  apparently the result of truncation later (xp = -65006 caused ghosting
			//  at bar 245 with magnification at max.), even with correct clipping region
			//  applied to painter in View::paint(). Tim.  Apr 5 2009
			// Quote: "Warning: Note that QPainter does not attempt to work around
			//  coordinate limitations in the underlying window system. Some platforms may
			//  behave incorrectly with coordinates as small as +/-4000."
			if (xp >= -32)
				p.drawPixmap(xp, 0, *flagIconS);

			if (xp >= -1023)
			{
				QRect r = QRect(xp + 10, 0, x2 - xp, 12);
				p.setPen(colTimeLine);
				p.drawText(r, Qt::AlignLeft | Qt::AlignVCenter, m->second.name());
			}

			if (xp >= 0)
			{
				p.setPen(colTimeLine);
				p.drawLine(xp, y, xp, height());
			}
		}
	}
	unsigned ctick;
	int bar1, bar2, beat;
	unsigned tick;

	if (waveMode)
	{
		ctick = tempomap.frame2tick(mapxDev(x));
		AL::sigmap.tickValues(ctick, &bar1, &beat, &tick);
		AL::sigmap.tickValues(tempomap.frame2tick(mapxDev(x + w)),
				&bar2, &beat, &tick);
	}
	else
	{
		ctick = mapxDev(x);
		AL::sigmap.tickValues(ctick, &bar1, &beat, &tick);
		AL::sigmap.tickValues(mapxDev(x + w), &bar2, &beat, &tick);
	}

	//printf("bar %d  %d-%d=%d\n", bar, ntick, stick, ntick-stick);
	int h = height() - 12;

	int stick = AL::sigmap.bar2tick(bar1, 0, 0);
	int ntick;
	for (int bar = bar1; bar <= bar2; bar++, stick = ntick)
	{
		ntick = AL::sigmap.bar2tick(bar + 1, 0, 0);
		int tpix, a, b = 0;
		if (waveMode)
		{
			a = tempomap.tick2frame(ntick);
			b = tempomap.tick2frame(stick);
			tpix = rmapx(a - b);
		}
		else
		{
			tpix = rmapx(ntick - stick);
		}
		if (tpix < 64)
		{
			// don�t show beats if measure is this small
			int n = 1;
			if (tpix < 32)
				n = 2;
			if (tpix <= 16)
				n = 4;
			if (tpix < 8)
				n = 8;
			if (tpix <= 4)
				n = 16;
			if (tpix <= 2)
				n = 32;
			if (bar % n)
				continue;
			int x = mapx(waveMode ? b : stick);
			QString s;
			s.setNum(bar + 1);
			p.drawLine(x, y + 1, x, y + 1 + h);
			QRect r = QRect(x + 2, y, 1000, h);
			p.setFont(QFont("fixed-width", 9, QFont::Bold));
			p.drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip, s);
		}
		else
		{
			int z, n;
			AL::sigmap.timesig(stick, z, n);
			for (int beat = 0; beat < z; beat++)
			{
				int xx = AL::sigmap.bar2tick(bar, beat, 0);
				if (waveMode)
					xx = tempomap.tick2frame(xx);
				int xp = mapx(xx);
				QString s;
				QRect r(xp + 2, y, 1000, h);
				int y1;
				int num;
				if (beat == 0)
				{
					num = bar + 1;
					y1 = y + 1;
					p.setFont(QFont("fixed-width", 9, QFont::Bold));
				}
				else
				{
					num = beat + 1;
					y1 = y + 7;
					p.setFont(QFont("fixed-width", 7, QFont::Normal));
					r.setY(y + 3);
				}
				s.setNum(num);
				p.drawLine(xp, y1, xp, y + 1 + h);
				p.drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip, s);
			}
		}
	}

	//---------------------------------------------------
	//    draw location marker
	//---------------------------------------------------

	//Christopher here is your color
	p.setPen(QColor(156,75,219));

	if (pos[3] != MAXINT)
	{
		int xp = mapx(pos[3]);
		if (xp >= x && xp < x + w)
			p.drawLine(xp, 0, xp, height());
	}

	p.setPen(colTimeLine);
	if (barLocator)
	{
		p.setPen(QColor(0, 186, 255));
		int xp = mapx(pos[0]);
		if (xp >= x && xp < x + w)
			p.drawLine(xp, 0, xp, height());
		p.setPen(QColor(139, 225, 69));
		xp = mapx(pos[1]);
		if (xp >= x && xp < x + w)
			p.drawLine(xp, 0, xp, height());
		xp = mapx(pos[2]);
		if (xp >= x && xp < x + w)
			p.drawLine(xp, 0, xp, height());
	}
	else
	{
		for (int i = 0; i < 3; ++i)
		{
			int xp = mapx(pos[i]);
			if (xp >= x && xp < x + w)
			{
				QPixmap* pm = markIcon[i];
				p.drawPixmap(xp - pm->width() / 2, y - 1, *pm);
			}
		}
	}
}