Example #1
0
void
TrackEditor::turnLinkedSegmentsToRealCopies()
{
    RG_DEBUG << "turnLinkedSegmentsToRealCopies()";

    SegmentSelection segments = m_compositionView->getSelectedSegments();

    if (segments.empty())
        return;

    QString text = tr("Turn %n Linked Segment(s) into Real Copies", "", segments.size());

    MacroCommand *macro = new MacroCommand(text);

    // For each selected segment
    for (SegmentSelection::iterator it = segments.begin();
         it != segments.end();
         ++it) {
        if ((*it)->isLinked()) {
            macro->addCommand(new SegmentLinkToCopyCommand(*it));
        }
    }

    addCommandToHistory(macro);
}
Example #2
0
void
TrackEditor::deleteSelectedSegments()
{
    SegmentSelection segments = m_compositionView->getSelectedSegments();

    if (segments.empty())
        return;

    // Clear the selection before erasing the Segments
    // the selection points to
    //
    m_compositionView->getModel()->clearSelected();

    MacroCommand *macro = new MacroCommand(tr("Delete Segments"));

    // For each selected segment
    for (SegmentSelection::iterator it = segments.begin();
         it != segments.end();
         ++it) {
        macro->addCommand(new SegmentEraseCommand(*it,
                          &m_doc->getAudioFileManager()));
    }

    addCommandToHistory(macro);
}
Example #3
0
SegmentColourCommand::SegmentColourCommand(
    SegmentSelection &segments,
    const unsigned int index):
        NamedCommand(tr("Change Segment Color")),
        m_newColourIndex(index)
{
    for (SegmentSelection::iterator i = segments.begin(); i != segments.end(); ++i)
        m_segments.push_back(*i);
}
SegmentLabelCommand::SegmentLabelCommand(
    SegmentSelection &segments,
    const QString &label):
        NamedCommand(tr("Label Segments")),
        m_newLabel(label)
{
    for (SegmentSelection::iterator i = segments.begin();
            i != segments.end(); ++i)
        m_segments.push_back(*i);
}
Example #5
0
CutCommand::CutCommand(SegmentSelection &selection,
                       Clipboard *clipboard) :
        MacroCommand(getGlobalName())
{
    addCommand(new CopyCommand(selection, clipboard));

    for (SegmentSelection::iterator i = selection.begin();
            i != selection.end(); ++i) {
        addCommand(new SegmentEraseCommand(*i));
    }
}
SegmentTransposeCommand::SegmentTransposeCommand(SegmentSelection selection, bool changeKey, int steps, int semitones, bool transposeSegmentBack) :
        MacroCommand(tr("Change segment transposition"))
{
    //SegmentSelection selection(m_view->getSelection());
    for (SegmentSelection::iterator i = selection.begin();
            i != selection.end(); ++i) 
    {
        Segment &segment = **i;    
        processSegment(segment, changeKey, steps, semitones, transposeSegmentBack);
    }
}
SegmentJoinCommand::SegmentJoinCommand(SegmentSelection &segments) :
        NamedCommand(getGlobalName()),
        m_newSegment(0),
        m_detached(false) // true if the old segments are detached, not the new
{
    for (SegmentSelection::iterator i = segments.begin();
            i != segments.end(); ++i)
    {
        m_oldSegments.push_back(*i);
    }

    Q_ASSERT_X(!m_oldSegments.empty(),
            "SegmentJoinCommand::SegmentJoinCommand()",
            "No segments to join");
}
Example #8
0
CopyCommand::CopyCommand(SegmentSelection &selection,
                         Clipboard *clipboard) :
        NamedCommand(getGlobalName()),
        m_targetClipboard(clipboard)
{
    m_sourceClipboard = new Clipboard;
    m_savedClipboard = 0;

    for (SegmentSelection::iterator i = selection.begin();
            i != selection.end(); ++i) {
        std::string label = (*i)->getLabel();
        m_sourceClipboard->newSegment(*i)->setLabel(
                appendLabel(label, qstrtostr(tr("(copied)"))));
    }
}
Example #9
0
int
SegmentSelector::mouseMoveEvent(QMouseEvent *e)
{
    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());
    m_lastMousePos = pos;

    // If no buttons are pressed, update the context help and bail.
    // Note: Mouse tracking must be on for this to work.  See
    //       QWidget::setMouseTracking().
    if (e->buttons() == Qt::NoButton) {
        setContextHelpFor(pos, e->modifiers());
        return RosegardenScrollView::NoFollow;
    }

    // If another tool has taken over, delegate.
    if (m_dispatchTool)
        return m_dispatchTool->mouseMoveEvent(e);

    // We only handle the left button.  The middle button is handled by
    // the dispatch tool (segment pencil) or ignored.
    if (e->buttons() != Qt::LeftButton)
        return RosegardenScrollView::NoFollow;

    // If we aren't moving anything, rubber band.
    if (!getChangingSegment()) {
        m_canvas->drawSelectionRectPos2(pos);
        m_canvas->getModel()->selectionHasChanged();

        return RosegardenScrollView::FollowHorizontal |
               RosegardenScrollView::FollowVertical;
    }

    // Moving

    // If the segment that was clicked on isn't selected, bail.
    if (!m_canvas->getModel()->isSelected(getChangingSegment()->getSegment()))
        return RosegardenScrollView::NoFollow;

    const int dx = pos.x() - m_clickPoint.x();
    const int dy = pos.y() - m_clickPoint.y();
    const int inertiaDistance = 8;

    // If we've not already exceeded the inertia distance, and we
    // still haven't, bail.
    if (!m_passedInertiaEdge  &&
        abs(dx) < inertiaDistance  &&
        abs(dy) < inertiaDistance) {
        return RosegardenScrollView::NoFollow;
    }

    m_passedInertiaEdge = true;

    m_canvas->viewport()->setCursor(Qt::SizeAllCursor);

#if 0
// ??? Moving to mouseReleaseEvent().
    if (m_segmentCopyMode  &&  !m_segmentQuickCopyDone) {
        // Make copies of the original Segment(s).  These copies will
        // take the place of the originals as the user drags the
        // the originals to a new location.

        MacroCommand *macroCommand = 0;
        
        if (m_segmentCopyingAsLink) {
            macroCommand = new MacroCommand(
                    SegmentQuickLinkCommand::getGlobalName());
        } else {
            macroCommand = new MacroCommand(
                    SegmentQuickCopyCommand::getGlobalName());
        }

        SegmentSelection selectedItems = m_canvas->getSelectedSegments();

        // for each selected segment
        for (SegmentSelection::iterator it = selectedItems.begin();
             it != selectedItems.end();
             ++it) {
            Segment *segment = *it;

            Command *command = 0;

            if (m_segmentCopyingAsLink) {
                command = new SegmentQuickLinkCommand(segment);
            } else {
                // if it's a link, copy as link
                if (segment->isTrulyLinked())
                    command = new SegmentQuickLinkCommand(segment);
                else  // copy as a non-link segment
                    command = new SegmentQuickCopyCommand(segment);
            }

            macroCommand->addCommand(command);
        }

        CommandHistory::getInstance()->addCommand(macroCommand);

        m_canvas->update();

        // Make sure we don't do it again.
        m_segmentQuickCopyDone = true;
    }
#endif

    setSnapTime(e, SnapGrid::SnapToBeat);

    // start move on selected items only once
    if (!m_selectionMoveStarted) {
        m_selectionMoveStarted = true;

        m_canvas->getModel()->startChangeSelection(
                m_segmentCopyMode ? CompositionModelImpl::ChangeCopy :
                                    CompositionModelImpl::ChangeMove);

        // The call to startChangeSelection() generates a new changing segment.
        // Get it.
        ChangingSegmentPtr newChangingSegment =
                m_canvas->getModel()->findChangingSegment(
                          getChangingSegment()->getSegment());

        if (newChangingSegment) {
            // Toss the local "changing" segment since it isn't going to
            // be moving at all.  Swap it for the same changing segment in
            // CompositionModelImpl.  That one *will* be moving and can be
            // used to drive the guides.
            setChangingSegment(newChangingSegment);
        }
    }

    // Display help for the Shift key.
    setContextHelpFor(pos, e->modifiers());

    Composition &comp = m_doc->getComposition();

    const int startDragTrackPos = m_canvas->grid().getYBin(m_clickPoint.y());
    const int currentTrackPos = m_canvas->grid().getYBin(pos.y());
    const int trackDiff = currentTrackPos - startDragTrackPos;

    CompositionModelImpl::ChangingSegmentSet &changingSegments =
            m_canvas->getModel()->getChangingSegments();

    // For each changing segment
    for (CompositionModelImpl::ChangingSegmentSet::iterator it =
                 changingSegments.begin();
         it != changingSegments.end();
         ++it) {
        ChangingSegmentPtr changingSegment = *it;

        const timeT newStartTime = m_canvas->grid().snapX(
                changingSegment->savedRect().x() + dx);

        const int newX = lround(
                m_canvas->grid().getRulerScale()->getXForTime(newStartTime));

        int newTrackPos = m_canvas->grid().getYBin(
                changingSegment->savedRect().y()) + trackDiff;

        // Limit to [0, comp.getNbTracks()-1].
        if (newTrackPos < 0)
            newTrackPos = 0;
        if (newTrackPos > static_cast<int>(comp.getNbTracks()) - 1)
            newTrackPos = comp.getNbTracks() - 1;

        const int newY = m_canvas->grid().getYBinCoordinate(newTrackPos);

        changingSegment->moveTo(newX, newY);
        m_changeMade = true;
    }

    if (m_changeMade) {
        // Make sure the segments are redrawn.
        // Note: The update() call below doesn't cause the segments to be
        //       redrawn.  It just updates from the cache.
        m_canvas->slotUpdateAll();
    }

    // Guides

    const int guideX = getChangingSegment()->rect().x();
    const int guideY = getChangingSegment()->rect().y();

    m_canvas->drawGuides(guideX, guideY);

    // Text Float

    const timeT guideTime = m_canvas->grid().snapX(guideX);

    RealTime time = comp.getElapsedRealTime(guideTime);
    QString msecs;
    msecs.sprintf("%03d", time.msec());

    int bar;
    int beat;
    int fraction;
    int remainder;
    comp.getMusicalTimeForAbsoluteTime(guideTime, bar, beat, fraction, remainder);

    QString posString = QString("%1.%2s (%3, %4, %5)").
            arg(time.sec).arg(msecs).arg(bar + 1).arg(beat).arg(fraction);

    m_canvas->drawTextFloat(guideX + 10, guideY - 30, posString);

    m_canvas->update();

    return RosegardenScrollView::FollowHorizontal |
           RosegardenScrollView::FollowVertical;
}
Example #10
0
void
SegmentSelector::mouseReleaseEvent(QMouseEvent *e)
{
    // We only care about the left and middle mouse buttons.
    if (e->button() != Qt::LeftButton  &&
        e->button() != Qt::MidButton)
        return;

    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());

    // If another tool (SegmentPencil or SegmentResizer) has taken
    // over, delegate.
    if (m_dispatchTool) {
        m_dispatchTool->mouseReleaseEvent(e);
        m_dispatchTool->stow();

        // Forget about the tool.
        // Note that this is not a memory leak.  There is only one instance
        // of each tool stored in BaseToolBox::m_tools.
        m_dispatchTool = 0;

        // Back to this tool.
        ready();

        return;
    }

    // We only handle the left button.  The middle button is handled by
    // the dispatch tool (segment pencil) or ignored.
    if (e->button() != Qt::LeftButton)
        return;

    // The left button has been released.

    m_canvas->hideGuides();
    m_canvas->hideTextFloat();

    // If rubber band mode
    if (!getChangingSegment()) {
        m_canvas->hideSelectionRect();
        m_canvas->getModel()->finalizeSelectionRect();
        m_canvas->getModel()->selectionHasChanged();
        return;
    }

    m_canvas->viewport()->setCursor(Qt::ArrowCursor);

    if (m_canvas->getModel()->isSelected(getChangingSegment()->getSegment())) {

        if (m_changeMade) {

            MacroCommand *macroCommand = 0;

            CompositionModelImpl::ChangingSegmentSet &changingSegments =
                    m_canvas->getModel()->getChangingSegments();

            if (m_segmentCopyMode) {
                if (m_segmentCopyingAsLink) {
                    macroCommand = new MacroCommand(
                            tr("Copy %n Segment(s) as link(s)", "", changingSegments.size()));
                } else {
                    macroCommand = new MacroCommand(
                            tr("Copy %n Segment(s)", "", changingSegments.size()));
                }
            } else {
                macroCommand = new MacroCommand(
                        tr("Move %n Segment(s)", "", changingSegments.size()));
            }

            if (m_segmentCopyMode) {
                // Make copies of the original Segment(s).  These copies will
                // take the place of the originals.

                SegmentSelection selectedItems = m_canvas->getSelectedSegments();

                // for each selected segment
                for (SegmentSelection::iterator it = selectedItems.begin();
                     it != selectedItems.end();
                     ++it) {
                    Segment *segment = *it;

                    Command *command = 0;

                    if (m_segmentCopyingAsLink) {
                        command = new SegmentQuickLinkCommand(segment);
                    } else {
                        // if it's a link, copy as link
                        if (segment->isTrulyLinked())
                            command = new SegmentQuickLinkCommand(segment);
                        else  // copy as a non-link segment
                            command = new SegmentQuickCopyCommand(segment);
                    }

                    macroCommand->addCommand(command);
                }
            }

            const int startDragTrackPos =
                    m_canvas->grid().getYBin(m_clickPoint.y());
            const int currentTrackPos = m_canvas->grid().getYBin(pos.y());
            const int trackDiff = currentTrackPos - startDragTrackPos;

            Composition &comp = m_doc->getComposition();

            SegmentReconfigureCommand *segmentReconfigureCommand =
                    new SegmentReconfigureCommand("", &comp);

            // For each changing segment, add the segment to the
            // SegmentReconfigureCommand.
            for (CompositionModelImpl::ChangingSegmentSet::iterator it =
                         changingSegments.begin();
                 it != changingSegments.end();
                 ++it) {
                ChangingSegmentPtr changingSegment = *it;
                Segment *segment = changingSegment->getSegment();

                TrackId origTrackId = segment->getTrack();
                int newTrackPos =
                        comp.getTrackPositionById(origTrackId) + trackDiff;

                // Limit to [0, comp.getNbTracks()-1]
                if (newTrackPos < 0)
                    newTrackPos = 0;
                if (newTrackPos > static_cast<int>(comp.getNbTracks()) - 1)
                    newTrackPos = comp.getNbTracks() - 1;

                Track *newTrack = comp.getTrackByPosition(newTrackPos);
                int newTrackId = origTrackId;
                if (newTrack)
                    newTrackId = newTrack->getId();

                timeT startTime =
                        changingSegment->getStartTime(m_canvas->grid());

                // endTime = startTime + segment duration
                // We absolutely don't want to snap the end time to
                // the grid.  We want it to remain exactly the same as
                // it was, but relative to the new start time.
                timeT endTime = startTime +
                        segment->getEndMarkerTime(false) -
                        segment->getStartTime();

                segmentReconfigureCommand->addSegment(
                        segment, startTime, endTime, newTrackId);
            }

            macroCommand->addCommand(segmentReconfigureCommand);

            CommandHistory::getInstance()->addCommand(macroCommand);

            m_canvas->update();
        }

        m_canvas->getModel()->endChange();
        m_canvas->slotUpdateAll();
    }

    // Get ready for the next button press.
    m_segmentQuickCopyDone = false;
    m_changeMade = false;
    m_selectionMoveStarted = false;
    setChangingSegment(ChangingSegmentPtr());

    setContextHelpFor(pos);
}
/// 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);
    }

}