예제 #1
0
MacroCommand *SummaryTaskGeneralPanel::buildCommand() {
    MacroCommand *cmd = new MacroCommand(kundo2_i18n("Modify task"));
    bool modified = false;

    if (!namefield->isHidden() && m_task.name() != namefield->text()) {
        cmd->addCommand(new NodeModifyNameCmd(m_task, namefield->text()));
        modified = true;
    }
    if (!leaderfield->isHidden() && m_task.leader() != leaderfield->text()) {
        cmd->addCommand(new NodeModifyLeaderCmd(m_task, leaderfield->text()));
        modified = true;
    }
/*    if (!descriptionfield->isHidden() && 
        m_task.description() != descriptionfield->text()) {
        cmd->addCommand(new NodeModifyDescriptionCmd(m_task, descriptionfield->text()));
        modified = true;
    }*/
    MacroCommand *m = m_description->buildCommand();
    if ( m ) {
        cmd->addCommand( m );
        modified = true;
    }
    if (!modified) {
        delete cmd;
        return 0;
    }
    return cmd;
}
예제 #2
0
void TrackEditor::deleteTracks(std::vector<TrackId> tracks)
{
    MacroCommand *macro = new MacroCommand(tr("Delete Tracks"));

    Composition &comp = m_doc->getComposition();
    const SegmentMultiSet &segments = comp.getSegments();

    // Delete the segments.

    // for each track we are deleting
    for (size_t i = 0; i < tracks.size(); ++i) {
        const TrackId trackId = tracks[i];

        // for each segment in the composition
        for (SegmentMultiSet::const_iterator segmentIter = segments.begin();
             segmentIter != segments.end();
             ++segmentIter) {
            Segment *segment = *segmentIter;

            // if this segment is in the track
            if (segment->getTrack() == trackId) {
                macro->addCommand(new SegmentEraseCommand(
                        segment, &m_doc->getAudioFileManager()));
            }
        }
    }

    // Delete the tracks.
    macro->addCommand(new DeleteTracksCommand(&comp, tracks));

    addCommandToHistory(macro);
}
예제 #3
0
MacroCommand *TaskCostPanel::buildCommand() {
    MacroCommand *cmd = new MacroCommand(i18nc("(qtundo-format)", "Modify Task Cost"));
    bool modified = false;
    
    if ((m_oldrunning == 0 && runningAccount->currentIndex() != 0) ||
        (m_oldrunning && m_oldrunning->name() != runningAccount->currentText())) {
        cmd->addCommand(new NodeModifyRunningAccountCmd(m_task, m_oldrunning, m_accounts.findAccount(runningAccount->currentText())));
        modified = true;
    }
    if ((m_oldstartup == 0 && startupAccount->currentIndex() != 0) ||
        (m_oldstartup && m_oldstartup->name() != startupAccount->currentText())) {
        cmd->addCommand(new NodeModifyStartupAccountCmd(m_task, m_oldstartup,  m_accounts.findAccount(startupAccount->currentText())));
        modified = true;
    }
    if ((m_oldshutdown == 0 && shutdownAccount->currentIndex() != 0) ||
        (m_oldshutdown && m_oldshutdown->name() != shutdownAccount->currentText())) {
        cmd->addCommand(new NodeModifyShutdownAccountCmd(m_task, m_oldshutdown,  m_accounts.findAccount(shutdownAccount->currentText())));
        modified = true;
    }
    double money = m_locale->readMoney(startupCost->text());
    if (money != m_task.startupCost()) {
        cmd->addCommand(new NodeModifyStartupCostCmd(m_task, money));
        modified = true;
    }
    money = m_locale->readMoney(shutdownCost->text());
    if (money != m_task.shutdownCost()) {
        cmd->addCommand(new NodeModifyShutdownCostCmd(m_task, money));
        modified = true;
    }
    if (!modified) {
        delete cmd;
        return 0;
    }
    return cmd;
}
예제 #4
0
파일: localemon.cpp 프로젝트: KDE/calligra
MacroCommand *LocaleConfigMoney::buildCommand()
{
    MacroCommand *m = new MacroCommand();
    if ( m_locale->currencySymbolExplicit() != m_edMonCurSym->text() ) {
        m->addCommand( new ModifyCurrencySymolCmd( m_locale, m_edMonCurSym->text() ) );
    }
    if (m_locale->monetaryDecimalPlaces() != m_inMonFraDig->value()) {
        m->addCommand( new ModifyCurrencyFractionalDigitsCmd( m_locale, m_inMonFraDig->value() ) );
    }
    debugPlan<<"buildCommand:"<<m->isEmpty();
    if ( m->isEmpty() ) {
        delete m;
        return 0;
    }
    return m;
}
예제 #5
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);
}
예제 #6
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);
}
예제 #7
0
MacroCommand *MainProjectDialog::buildCommand() {
    MacroCommand *m = 0;
    KUndo2MagicString c = kundo2_i18n("Modify main project");
    MacroCommand *cmd = panel->buildCommand();
    if (cmd) {
        if (!m) m = new MacroCommand(c);
        m->addCommand(cmd);
    }
    return m;
}
KUndo2Command *LocaleConfigMoneyDialog::buildCommand( Project &project ) {
    MacroCommand *m = new ModifyProjectLocaleCmd( project, kundo2_i18n( "Modify currency settings" ) );
    MacroCommand *cmd = m_panel->buildCommand();
    if (cmd) {
        m->addCommand(cmd);
    }
    if ( m->isEmpty() ) {
        delete m;
        return 0;
    }
    return m;
}
예제 #9
0
MacroCommand *SummaryTaskDialog::buildCommand() {
    MacroCommand *m = new MacroCommand(kundo2_i18n("Modify Summary Task"));
    bool modified = false;
    MacroCommand *cmd = m_generalTab->buildCommand();
    if (cmd) {
        m->addCommand(cmd);
        modified = true;
    }
    if (!modified) {
        delete m;
        return 0;
    }
    return m;
}
예제 #10
0
MacroCommand *StandardWorktimeDialog::buildCommand() {
    //kDebug(planDbg());
    KUndo2MagicString n = kundo2_i18n("Modify Estimate Conversions");
    MacroCommand *cmd = 0;
    if (m_original->year() != dia->inYear()) {
        if (cmd == 0) cmd = new MacroCommand(n);
        cmd->addCommand(new ModifyStandardWorktimeYearCmd(m_original, m_original->year(), dia->inYear()));
    }
    if (m_original->month() != dia->inMonth()) {
        if (cmd == 0) cmd = new MacroCommand(n);
        cmd->addCommand(new ModifyStandardWorktimeMonthCmd(m_original, m_original->month(), dia->inMonth()));
    }
    if (m_original->week() != dia->inWeek()) {
        if (cmd == 0) cmd = new MacroCommand(n);
        cmd->addCommand(new ModifyStandardWorktimeWeekCmd(m_original, m_original->week(), dia->inWeek()));
    }
    if (m_original->day() != dia->inDay()) {
        if (cmd == 0) cmd = new MacroCommand(n);
        cmd->addCommand(new ModifyStandardWorktimeDayCmd(m_original, m_original->day(), dia->inDay()));
    }
    return cmd;

}
예제 #11
0
MacroCommand *TaskProgressDialog::buildCommand() {
    MacroCommand *m = new MacroCommand(kundo2_i18n("Modify Task Progress"));
    bool modified = false;
    MacroCommand *cmd = m_panel->buildCommand();
    if (cmd) {
        m->addCommand(cmd);
        modified = true;
    }
    if (!modified) {
        delete m;
        return 0;
    }
    return m;
}
예제 #12
0
void
PitchBendSequenceDialog::accept()
{
    /* The user has finished the dialog, other than aborting. */

    // We don't enable "OK" if the interval isn't sensible, so
    // something's badly wrong if this test fails.
    Q_ASSERT_X(m_startTime < m_endTime, "accept",
             "got a zero or negative time interval");

    /* Save current settings.  They'll be the defaults next time. */
    saveSettings();

    // TRANSLATORS: The arg value will be either a controller name or
    // Pitchbend, so the resulting text is like "Pitchbend Sequence",
    // "Expression Sequence", etc.
    QString controllerName(m_control.getName().data());
    QString commandName(tr("%1 Sequence").arg(controllerName));
    MacroCommand *macro = new MacroCommand(commandName);

    if (getReplaceMode() != OnlyAdd) {
        // Selection initially contains no event, and we add all the
        // relevant ones.  
        EventSelection *selection = new EventSelection(*m_segment);
        for (Segment::const_iterator i = m_segment->findTime(m_startTime);
             i != m_segment->findTime(m_endTime);
             ++i) {
            Event *e = *i;
            if (m_control.matches(e)) {
                selection->addEvent(e, false);
            }
        }

        // EraseCommand takes ownership of "selection".
        macro->addCommand(new EraseCommand(*selection));
    }

    if (getReplaceMode() != OnlyErase) {
        if ((getRampMode() == Linear) &&
            (getStepSizeCalculation() == StepSizeByCount)) {
            addLinearCountedEvents(macro);
        } else {
            addStepwiseEvents(macro);
        }
    }
    CommandHistory::getInstance()->addCommand(macro);

    QDialog::accept();
}
MacroCommand *TaskDescriptionPanel::buildCommand()
{
    QString s = i18n("Modify task description");
    if ( m_node.type() == Node::Type_Milestone ) {
        s = i18n("Modify milestone description");
    } else if ( m_node.type() == Node::Type_Summarytask ) {
        s = i18n("Modify summary task description");
    } else if ( m_node.type() == Node::Type_Project ) {
        s = i18n("Modify project description");
    }
    MacroCommand *cmd = new MacroCommand(s);
    bool modified = false;

    if ( m_node.description() != descriptionfield->textOrHtml() ) {
        cmd->addCommand(new NodeModifyDescriptionCmd(m_node, descriptionfield->textOrHtml()));
        modified = true;
    }
    if (!modified) {
        delete cmd;
        return 0;
    }
    return cmd;
}
예제 #14
0
void
ControllerEventsRuler::addControlLine(float x1, float y1, float x2, float y2, bool eraseExistingControllers)
{
    std::cout << "ControllerEventsRuler::addControlLine()";
    clearSelectedItems();

    // get a timeT for one end point of our line
    timeT originTime = m_rulerScale->getTimeForX(x1);

    // get a timeT for the other end point of our line
    timeT destinationTime = m_rulerScale->getTimeForX(x2);

    // get a value for one end point of our line
    long originValue = yToValue(y1);
    
    // get a value for the other end point
    long destinationValue = yToValue(y2);

    if (originTime == destinationTime || originValue == destinationValue) return;

    // If the "anchor point" was to the right of the newly clicked destination
    // point, we're drawing a line from right to left.  We simply swap origin
    // for destination and calculate all lines as drawn from left to right, for
    // convenience and sanity.
    if (originTime > destinationTime) {
        timeT swapTime = originTime;
        originTime = destinationTime;
        destinationTime = swapTime;

        long swapValue = originValue;
        originValue = destinationValue;
        destinationValue = swapValue;
    }

    // save a list of existing events that occur within the span of the new line
    // for later deletion, if desired
    std::vector<Event*> eventsToClear;

    if (eraseExistingControllers) {
        for (Segment::iterator si = m_segment->begin();
             si != m_segment->end(); ++si) {

            timeT t = (*si)->getNotationAbsoluteTime();
            if (t >= originTime && t <= destinationTime) {
                eventsToClear.push_back(*si);
            }
        }
    }

    // rise and run
    long rise = destinationValue - originValue;
    timeT run = destinationTime - originTime;

    std::cout << "Drawing a line from origin time: " << originTime << " to " << destinationTime
              << " rising from: " << originValue << " to " << destinationValue 
              << " with a rise of: " << rise << " and run of: " << run
              << std::endl;

    // avoid divide by 0 potential, rise is always at least 1
    if (rise == 0) rise = 1;

    // are we rising or falling?
    bool rising = (rise > 0);

    // always calculate step on a positive value for rise, and make sure it's at
    // least 1
    float step = run / (float)(rising ? rise : rise * -1);

    // Trying this with pitch bend with a rise approaching the maximum over a
    // span of around four bars generated over 15,000 pitch bend events!  That's
    // super duper fine resolution, but it's too much for anything to handle.
    // Let's try to do some sensible thinning without getting too complicated...
    // bool isPitchBend = (m_controller->getType() == Rosegarden::PitchBend::EventType);
    int thinningHackCounter = 1;
    
    long intermediateValue = originValue;    
    long controllerNumber = 0;

    if (m_controller) {
        controllerNumber = m_controller->getControllerValue();
    } else {
        std::cout << "No controller number set.  Time to panic!  Line drawing aborted." << std::endl;
        return;
    }

    MacroCommand *macro = new MacroCommand(tr("Insert Line of Controllers"));

    bool failsafe = false;

    // if we're clearing existing events, add that to the macro command
    for (std::vector<Event*>::iterator ei = eventsToClear.begin();
         ei != eventsToClear.end(); ++ei) {

        // if the event was a controller or pitch bend, and it is on this ruler,
        // add it to the list
        if (((*ei)->isa(Controller::EventType) || (*ei)->isa(PitchBend::EventType))
            && isOnThisRuler(*ei)) {

            bool collapseRests = true;
            macro->addCommand(new EraseEventCommand(*m_segment,
                                                    *ei,
                                                    collapseRests));
       }
    }

    if (macro->haveCommands()) {
        CommandHistory::getInstance()->addCommand(macro);
        macro = new MacroCommand(tr("Insert Line of Controllers"));
    }

    for (float i = originTime; i <= destinationTime; i += step) {

        if (failsafe) continue;

        if (rising) intermediateValue++;
        else intermediateValue--;

        if (rising && intermediateValue > destinationValue) failsafe = true;
        else if (!rising && intermediateValue < destinationValue) failsafe = true;

//        std::cout << "creating event at time: " << i << " of value: " << intermediateValue << std::endl;
//        continue;

        Event *controllerEvent = new Event(m_controller->getType(), (timeT) i);

        if (m_controller->getType() == Rosegarden::Controller::EventType) {

            controllerEvent->set<Rosegarden::Int>(Rosegarden::Controller::VALUE, intermediateValue);
            controllerEvent->set<Rosegarden::Int>(Rosegarden::Controller::NUMBER, controllerNumber);

        } else if (m_controller->getType() == Rosegarden::PitchBend::EventType)   {

            // always set the first and last events, then only set every 25th,
            // 50th, and 75th event for pitch bend
            if (thinningHackCounter++ > 100) thinningHackCounter = 1;
            if (thinningHackCounter != 25 &&
                thinningHackCounter != 50 &&
                thinningHackCounter != 75 &&
                i != originTime           &&
                i != destinationTime) continue;

            std::cout << "intermediate value: " << intermediateValue << std::endl;

            // Convert to PitchBend MSB/LSB
            int lsb = intermediateValue & 0x7f;
            int msb = (intermediateValue >> 7) & 0x7f;
            controllerEvent->set<Rosegarden::Int>(Rosegarden::PitchBend::MSB, msb);
            controllerEvent->set<Rosegarden::Int>(Rosegarden::PitchBend::LSB, lsb);
        }

        if (failsafe) std::cout << "intermediate value: " << intermediateValue << " exceeded target: " << destinationValue << std::endl;

        macro->addCommand(new EventInsertionCommand (*m_segment, controllerEvent));
    }

    m_moddingSegment = true;
    CommandHistory::getInstance()->addCommand(macro);
    m_moddingSegment = false;
    
    // How else to re-initialize and bring things into view?  I'm missing
    // something, but this works...
    init();
}
예제 #15
0
MacroCommand *AddRelationDialog::buildCommand() {
    MacroCommand *c = new MacroCommand( kundo2_i18n("Add task dependency") );
    c->addCommand( new AddRelationCmd(m_project, m_relation ) );
    m_deleterelation = false; // don't delete
    return c;
}
void 
SegmentTransposeCommand::processSegment(Segment &segment, bool changeKey, int steps, int semitones, bool transposeSegmentBack)
{
    MacroCommand * macroCommand = this;

    // TODO delete it somewhere.
    EventSelection * wholeSegment = new EventSelection(segment, segment.getStartTime(), segment.getEndMarkerTime());
    macroCommand->addCommand(new TransposeCommand
        (semitones, steps, *wholeSegment));
    
    // Key insertion can do transposition, but a C4 to D becomes a D4, while
    //  a C4 to G becomes a G3. Because we let the user specify an explicit number
    //  of octaves to move the notes up/down, we add the keys without transposing
    //  and handle the transposition seperately:
    if (changeKey)
    {
        Rosegarden::Key initialKey = segment.getKeyAtTime(segment.getStartTime());
        Rosegarden::Key newInitialKey = initialKey.transpose(semitones, steps);

        EventSelection::eventcontainer::iterator i;
        //std::list<KeyInsertionCommand*> commands;

        for (i = wholeSegment->getSegmentEvents().begin();
            i != wholeSegment->getSegmentEvents().end(); ++i) {
                // transpose key
                if ((*i)->isa(Rosegarden::Key::EventType)) {
                    Rosegarden::Key trKey = (Rosegarden::Key (**i)).transpose(semitones, steps); 
                    //commands.push_front
                    macroCommand->addCommand
                        (new KeyInsertionCommand
                         (segment,
                           (*i)->getAbsoluteTime(),
                           trKey,
                          false,
                          false,
                          false,
			  true));
                    }
            }
        std::list<KeyInsertionCommand*>::iterator ci;
        //for (ci=commands.begin(); ci!=commands.end(); ci++)
        //{
        //    commandHistory->addCommand(*ci);
        //}
            
        KeyInsertionCommand *firstKeyCommand = new KeyInsertionCommand
             (segment,
              segment.getStartTime(),
              newInitialKey,
              false,
              false,
              false,
	      true);
        //commandHistory->addCommand(firstKeyCommand);
        macroCommand->addCommand(firstKeyCommand);
    }
        
    if (transposeSegmentBack)
    {
        // Transpose segment in opposite direction
        int newTranspose = segment.getTranspose() - semitones;
        macroCommand->addCommand(new SegmentChangeTransposeCommand(newTranspose, &segment));
    }
}
예제 #17
0
MacroCommand *AddRelationDialog::buildCommand() {
    MacroCommand *c = new MacroCommand( i18n("Add Relation") );
    c->addCommand( new AddRelationCmd(m_project, m_relation ) );
    return c;
}
MacroCommand *RequestResourcesPanel::buildCommand()
{
    Task *t = m_view->task();
    if ( t == 0 ) {
        return 0;
    }
    MacroCommand *cmd = new MacroCommand( i18nc( "(qtundo-format)", "Modify resource allocations" ) );
    /*Project *p = */m_view->project();
    const QMap<const Resource*, ResourceRequest*> &rmap = m_view->resourceCache();

    // First remove all that should be removed
    for( QMap<const Resource*, ResourceRequest*>::const_iterator rit = rmap.constBegin(); rit != rmap.constEnd(); ++rit ) {
        if ( rit.value()->units() == 0 ) {
            ResourceRequest *rr = t->requests().find( rit.key() );
            if ( rr ) {
                cmd->addCommand( new RemoveResourceRequestCmd( rr->parent(), rr ) );
            }
        }
    }

    QMap<const ResourceGroup*, ResourceGroupRequest*> groups;
    // Add/modify
    const QMap<const ResourceGroup*, ResourceGroupRequest*> &gmap = m_view->groupCache();
    for( QMap<const ResourceGroup*, ResourceGroupRequest*>::const_iterator git = gmap.constBegin(); git != gmap.constEnd(); ++git ) {
        ResourceGroupRequest *gr = t->requests().find( git.key() );
        if ( gr == 0 ) {
            if ( git.value()->units() > 0 ) {
                gr = new ResourceGroupRequest( const_cast<ResourceGroup*>( git.key() ), git.value()->units() );
                cmd->addCommand( new AddResourceGroupRequestCmd( *t, gr ) );
                groups[ git.key() ] = gr;
            } // else nothing
        } else {
            cmd->addCommand( new ModifyResourceGroupRequestUnitsCmd( gr, gr->units(), git.value()->units() ) );
        }
    }
    for( QMap<const Resource*, ResourceRequest*>::const_iterator rit = rmap.constBegin(); rit != rmap.constEnd(); ++rit ) {
        Resource *resource = const_cast<Resource*>( rit.key() );
        ResourceGroup *group = resource->parentGroup();
        if ( rit.value()->units() > 0 ) {
            ResourceRequest *rr = t->requests().find( resource );
            if ( rr == 0 ) {
                ResourceGroupRequest *gr = t->requests().find( group );
                if ( gr == 0 ) {
                    if ( groups.contains( group ) ) {
                        gr = groups[ group ];
                    } else {
                        gr = new ResourceGroupRequest( group, 0 );
                        groups[ group ] = gr;
                        cmd->addCommand( new AddResourceGroupRequestCmd( *t, gr ) );
                    }
                }
                ResourceRequest *rr = new ResourceRequest( resource, rit.value()->units() );
                rr->setRequiredResources( rit.value()->requiredResources() );
                cmd->addCommand( new AddResourceRequestCmd( gr, rr ) );
            } else {
                if ( rit.value()->units() != rr->units() ) {
                    cmd->addCommand( new ModifyResourceRequestUnitsCmd( rr, rr->units(), rit.value()->units() ) );
                }
                if ( rit.value()->requiredResources() != rr->requiredResources() ) {
                    cmd->addCommand( new ModifyResourceRequestRequiredCmd( rr, rit.value()->requiredResources() ) );
                }
            }
        }
    }
    if ( cmd->isEmpty() ) {
        delete cmd;
        return 0;
    }
    return cmd;
}
예제 #19
0
void
MatrixResizer::handleMouseRelease(const MatrixMouseEvent *e)
{
    if (!e || !m_currentElement || !m_currentViewSegment) return;

    // snap in the closest direction
    timeT snapTime = e->snappedLeftTime;
    if (e->snappedRightTime - e->time < e->time - e->snappedLeftTime) {
        snapTime = e->snappedRightTime;
    }

    timeT newDuration = snapTime - m_currentElement->getViewAbsoluteTime();
    timeT durationDiff = newDuration - m_currentElement->getViewDuration();

    EventSelection *selection = m_scene->getSelection();
    if (!selection || selection->getAddedEvents() == 0) return;

    QString commandLabel = tr("Resize Event");
    if (selection->getAddedEvents() > 1) commandLabel = tr("Resize Events");

    MacroCommand *macro = new MacroCommand(commandLabel);

    EventSelection::eventcontainer::iterator it =
        selection->getSegmentEvents().begin();

    Segment &segment = m_currentViewSegment->getSegment();

    EventSelection *newSelection = new EventSelection(segment);

    timeT normalizeStart = selection->getStartTime();
    timeT normalizeEnd = selection->getEndTime();

    for (; it != selection->getSegmentEvents().end(); ++it) {

        timeT t = (*it)->getAbsoluteTime();
        timeT d = (*it)->getDuration();

        MATRIX_DEBUG << "MatrixResizer::handleMouseRelease - "
                     << "Time = " << t
                     << ", Duration = " << d << endl;

        d = d + durationDiff;
        if (d < 0) {
            t = t + d;
            d = -d;
        } else if (d == 0) {
            d = getSnapGrid()->getSnapTime(t);
        }

        if (t + d > segment.getEndMarkerTime()) {
            d = segment.getEndMarkerTime() - t;
            if (d <= 0) {
                d = segment.getEndMarkerTime();
                t = d - getSnapGrid()->getSnapTime(t);
            }
        }

        Event *newEvent = new Event(**it, t, d);

        macro->addCommand(new MatrixModifyCommand(segment,
                                                  *it,
                                                  newEvent,
                                                  false,
                                                  false));

        newSelection->addEvent(newEvent);
    }

    normalizeStart = std::min(normalizeStart, newSelection->getStartTime());
    normalizeEnd = std::max(normalizeEnd, newSelection->getEndTime());

    macro->addCommand(new NormalizeRestsCommand(segment,
                                                normalizeStart,
                                                normalizeEnd));

    m_scene->setSelection(0, false);
    CommandHistory::getInstance()->addCommand(macro);
    m_scene->setSelection(newSelection, false);

//    m_mParentView->update();
    m_currentElement = 0;
    setBasicContextHelp();
}
예제 #20
0
void ControlRuler::updateSegment()
{
    // Bring the segment up to date with the ControlRuler's items
    // A number of different actions take place here:
    // 1) m_eventSelection is empty
    // 2) m_eventSelection has events
    //      a) Events in the selection have been modified in value only
    //      b) Events in the selection have moved in time
    //
    // Either run through the ruler's EventSelection, updating from each item
    //  or, if there isn't one, go through m_selectedItems
    timeT start,end;
    // bool segmentModified = false;

    QString commandLabel = "Adjust control/property";

    MacroCommand *macro = new MacroCommand(commandLabel);

    // Find the extent of the selected items
    float xmin=FLT_MAX,xmax=-1.0;

    // EventSelection::addEvent adds timeT(1) to its extentt for zero duration events so need to mimic this here
    timeT durationAdd = 0;

    for (ControlItemList::iterator it = m_selectedItems.begin(); it != m_selectedItems.end(); ++it) {
        if ((*it)->xStart() < xmin) xmin = (*it)->xStart();
        if ((*it)->xEnd() > xmax) {
            xmax = (*it)->xEnd();
            if ((*it)->xEnd() == (*it)->xStart())
                durationAdd = 1;
            else
                durationAdd = 0;
        }
    }

    start = getRulerScale()->getTimeForX(xmin);
    end = getRulerScale()->getTimeForX(xmax)+durationAdd;

    if (m_eventSelection->getAddedEvents() == 0) {
        // We do not have a valid set of selected events to update
        if (m_selectedItems.size() == 0) {
            // There are no selected items, nothing to update
            return;
        }

        // Events will be added by the controlItem->updateSegment methods
        commandLabel = "Add control";
        macro->setName(commandLabel);

        // segmentModified = true;
    } else {
        // Check for movement in time here and delete events if necessary
        if (start != m_eventSelection->getStartTime() || end != m_eventSelection->getEndTime()) {
            commandLabel = "Move control";
            macro->setName(commandLabel);

            // Get the limits of the change for undo
            start = std::min(start,m_eventSelection->getStartTime());
            end = std::max(end,m_eventSelection->getEndTime());

            // segmentModified = true;
        }
    }

    // Add change command to macro
    // ControlChangeCommand calls each selected items updateSegment method
    // Note that updateSegment deletes and renews the event whether it has moved or not
    macro->addCommand(new ControlChangeCommand(m_selectedItems,
                                    *m_segment,
                                    start,
                                    end));

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

    updateSelection();
}
예제 #21
0
void
MatrixMover::handleMouseRelease(const MatrixMouseEvent *e)
{
    if (!e) return;

    MATRIX_DEBUG << "MatrixMover::handleMouseRelease() - newPitch = "
                 << e->pitch << endl;

    if (!m_currentElement || !m_currentViewSegment) return;

    timeT newTime = m_currentElement->getViewAbsoluteTime() +
        (e->snappedLeftTime - m_clickSnappedLeftTime);
    int newPitch = e->pitch;

    if (newPitch > 127) newPitch = 127;
    if (newPitch < 0) newPitch = 0;

    // get a basic pitch difference calculation comparing the current element's
    // pitch to the pitch the mouse was released at (see note in
    // handleMouseMove)
    using BaseProperties::PITCH;
    timeT diffTime = newTime - m_currentElement->getViewAbsoluteTime();
    int diffPitch = 0;
    if (m_currentElement->event()->has(PITCH)) {
        diffPitch = newPitch - m_currentElement->event()->get<Int>(PITCH);
    }

    EventSelection* selection = m_scene->getSelection();

    // factor in transpose to adjust the height calculation
    long pitchOffset = selection->getSegment().getTranspose();
    diffPitch += (pitchOffset * -1);

    if ((diffTime == 0 && diffPitch == 0) || selection->getAddedEvents() == 0) {
        for (size_t i = 0; i < m_duplicateElements.size(); ++i) {
            delete m_duplicateElements[i]->event();
            delete m_duplicateElements[i];
        }
        m_duplicateElements.clear();
        m_currentElement = 0;
        return;
    }

    if (newPitch != m_lastPlayedPitch) {
        long velocity = m_widget->getCurrentVelocity();
        m_currentElement->event()->get<Int>(BaseProperties::VELOCITY, velocity);
        m_scene->playNote(m_currentViewSegment->getSegment(), newPitch + (pitchOffset * -1), velocity);
        m_lastPlayedPitch = newPitch;
    }

    QString commandLabel;
    if (m_quickCopy) {
        if (selection->getAddedEvents() < 2) {
            commandLabel = tr("Copy and Move Event");
        } else {
            commandLabel = tr("Copy and Move Events");
        }
    } else {
        if (selection->getAddedEvents() < 2) {
            commandLabel = tr("Move Event");
        } else {
            commandLabel = tr("Move Events");
        }
    }

    MacroCommand *macro = new MacroCommand(commandLabel);

    EventSelection::eventcontainer::iterator it =
        selection->getSegmentEvents().begin();

    Segment &segment = m_currentViewSegment->getSegment();

    EventSelection *newSelection = new EventSelection(segment);

    timeT normalizeStart = selection->getStartTime();
    timeT normalizeEnd = selection->getEndTime();

    if (m_quickCopy) {
        for (size_t i = 0; i < m_duplicateElements.size(); ++i) {
            timeT time = m_duplicateElements[i]->getViewAbsoluteTime();
            timeT endTime = time + m_duplicateElements[i]->getViewDuration();
            if (time < normalizeStart) normalizeStart = time;
            if (endTime > normalizeEnd) normalizeEnd = endTime;
            macro->addCommand(new MatrixInsertionCommand
                              (segment, time, endTime, 
                               m_duplicateElements[i]->event()));
            delete m_duplicateElements[i]->event();
            delete m_duplicateElements[i];
        }
        m_duplicateElements.clear();
        m_quickCopy = false;
    }
        
    for (; it != selection->getSegmentEvents().end(); ++it) {

        timeT newTime = (*it)->getAbsoluteTime() + diffTime;

        int newPitch = 60;
        if ((*it)->has(PITCH)) {
            newPitch = (*it)->get<Int>(PITCH) + diffPitch;
        }

        Event *newEvent = 0;

        if (newTime < segment.getStartTime()) {
            newTime = segment.getStartTime();
        }

        if (newTime + (*it)->getDuration() >= segment.getEndMarkerTime()) {
            timeT limit = getSnapGrid()->snapTime
                (segment.getEndMarkerTime() - 1, SnapGrid::SnapLeft);
            if (newTime > limit) newTime = limit;
            timeT newDuration = std::min
                ((*it)->getDuration(), segment.getEndMarkerTime() - newTime);
            newEvent = new Event(**it, newTime, newDuration);
        } else {
            newEvent = new Event(**it, newTime);
        }

        newEvent->set<Int>(BaseProperties::PITCH, newPitch);

        macro->addCommand(new MatrixModifyCommand(segment,
                                                  (*it),
                                                  newEvent,
                                                  true,
                                                  false));
        newSelection->addEvent(newEvent);
    }

    normalizeStart = std::min(normalizeStart, newSelection->getStartTime());
    normalizeEnd = std::max(normalizeEnd, newSelection->getEndTime());
    
    macro->addCommand(new NormalizeRestsCommand(segment,
                                                normalizeStart,
                                                normalizeEnd));
    
    m_scene->setSelection(0, false);
    CommandHistory::getInstance()->addCommand(macro);
    m_scene->setSelection(newSelection, false);

//    m_mParentView->canvas()->update();
    m_currentElement = 0;

    setBasicContextHelp();
}
예제 #22
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;
}
예제 #23
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);
}