コード例 #1
0
ファイル: tracklistview.cpp プロジェクト: peter1000/los
void TrackListView::toggleTrackPart(QStandardItem* item)/*{{{*/
{
    if(!item)
        return;
    m_editing = true;
    int type = item->data(TrackRole).toInt();
    int column = item->column();
    bool checked = (item->checkState() == Qt::Checked);
    qint64 tid = item->data(TrackIdRole).toLongLong();
    QString trackName = item->data(TrackNameRole).toString();
    QString partName;
    m_selectedIndex = item->row();
    QString newName = item->text();
    if(type == 1)
    {
        if(trackName == newName)
            column = 0;
        else
            column = 1;
    }
    else
    {
        partName = item->data(PartNameRole).toString();
        if(partName == newName)
            column = 0;
        else
            column = 1;
    }

    MidiTrack* track = song->findTrackById(tid);
    if(!track || !m_editor)
    {
        m_editing = false;
        return;
    }

    PartList* list = track->parts();
    if(list->empty())
    {
        m_editing = false;
        updateCheck();
        return;
    }
    switch(type)
    {
        case 1: //Track
        {
            if(!column)
            {
                if(checked)
                {
                    m_editor->addParts(list);
                    m_selectedTracks.append(track->id());
                    if(!list->empty())
                    {
                        updatePartSelection(list->begin()->second);

                        updateCheck(list, checked);
                    }
                }
                else
                {
                    m_editor->removeParts(list);
                    m_editor->updateCanvas();
                    m_selectedTracks.removeAll(track->id());
                    updateCheck();
                    song->update(SC_SELECTION);
                }
            }
            else
            {
                bool valid = true;
                if(newName.isEmpty())
                {
                    valid = false;
                }
                if(valid)
                {
                    for (iMidiTrack i = song->tracks()->begin(); i != song->tracks()->end(); ++i)
                    {
                        if ((*i)->name() == newName)
                        {
                            valid = false;
                            break;
                        }
                    }
                }
                if(!valid)
                {
                    QMessageBox::critical(this, tr("LOS: bad trackname"),
                            tr("please choose a unique track name"),
                            QMessageBox::Ok, Qt::NoButton, Qt::NoButton);
                    m_model->blockSignals(true);
                    item->setText(item->data(TrackNameRole).toString());
                    m_model->blockSignals(false);
                    update();
                    m_editing = false;
                    return;
                }
                m_model->blockSignals(true);
                item->setData(newName, TrackNameRole);
                m_model->blockSignals(false);

                Track* newTrack = track->clone(false);
                newTrack->setName(newName);
                track->setName(newName);
                audio->msgChangeTrack((MidiTrack*)newTrack, track);
            }
        }
        break;
        case 2: //Part
        {
            int sn = item->data(PartRole).toInt();
            unsigned tick = item->data(TickRole).toInt();
            Part* part = list->find(tick, sn);
            if(part)
            {
                if(!column)
                {
                    if(checked)
                    {
                        m_editor->addPart(part);
                        updatePartSelection(part);
                    }
                    else
                    {
                        m_editor->removePart(sn);
                        m_editor->updateCanvas();
                        updateCheck();
                        song->update(SC_SELECTION);
                    }
                }
                else
                {
                    if(partName.isEmpty())
                    {
                        QMessageBox::critical(this, tr("LOS: Invalid part name"),
                                tr("Please choose a name with at least one charactor"),
                                QMessageBox::Ok, Qt::NoButton, Qt::NoButton);

                        m_model->blockSignals(true);
                        item->setText(item->data(PartNameRole).toString());
                        m_model->blockSignals(false);
                        update();
                        m_editing = false;
                        return;
                    }

                    m_model->blockSignals(true);
                    item->setData(newName, PartNameRole);
                    m_model->blockSignals(false);

                    Part* newPart = part->clone();
                    newPart->setName(newName);
                    // Indicate do undo, and do port controller values but not clone parts.
                    audio->msgChangePart(part, newPart, true, true, false);
                    song->update(SC_PART_MODIFIED);
                }
            }
        }
        break;
    }
    update();
    if(m_selectedIndex < m_model->rowCount())
    {
        m_table->selectRow(m_selectedIndex);
        m_table->scrollTo(m_model->index(m_selectedIndex, 0));
    }
    m_editing = false;
}/*}}}*/
コード例 #2
0
ファイル: importmidi.cpp プロジェクト: peter1000/los
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MType t = song->midiType();
    if (!merge)
    {
        t = mf.mtype();
        song->setMType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MT_UNKNOWN) || (t == MIDI_TYPE_GM)))
                || ((mi->iname() == "GS") && (t == MT_GS))
                || ((mi->iname() == "XG") && (t == MT_XG)))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    int mPort = getFreeMidiPort();
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        // somewhat silly and slooow:
        QList<QPair<int, int> > eventChannelList;
        if(mPort >= 0 && mPort < kMaxMidiPorts)
        {
            for (int channel = 0; channel < kMaxMidiChannels; ++channel)
            {
                //
                // check if there are any events for port/channel in track:
                //
                iMPEvent i;
                for (i = el->begin(); i != el->end(); ++i)
                {
                    MidiPlayEvent ev = *i;
                    if (ev.type() != ME_SYSEX && ev.type() != ME_META && ev.channel() == channel)
                        break;
                }
                if (i == el->end())
                    continue;
                MidiTrack* track = new MidiTrack();
                track->setDefaultName();
                track->setMasterFlag(true);

                track->setOutChannel(channel);
                track->setOutPort(mPort);

                MidiPort* mport = &midiPorts[track->outPort()];
                // this overwrites any instrument set for this port:
                mport->setInstrument(instr);

                EventList* mel = track->events();
                buildMidiEventList(mel, el, track, division, first, false, false);

                first = false;

                processTrack(track);

                song->insertTrack(track, -1);
                //Create the Audio input side of the track
                Track* input = song->addTrackByName(QString("i").append(track->name()), Track::AUDIO_INPUT, -1, false, false);
                if(input)
                {
                    input->setMasterFlag(false);
                    input->setChainMaster(track->id());
                    track->addManagedTrack(input->id());
                }
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setDefaultName();
            track->setMasterFlag(true);
            track->setOutChannel(0);
            track->setOutPort(mPort);
            EventList* mel = track->events();
            //buildMidiEventList(mel, el, track, division, true);
            // Do SysexMeta. Don't do loops.
            buildMidiEventList(mel, el, track, division, true, false, false);
            processTrack(track);
            song->insertTrack(track, -1);
            //Create the Audio input side of the track
            Track* input = song->addTrackByName(QString("i").append(track->name()), Track::AUDIO_INPUT, -1, false, false);
            if(input)
            {
                input->setMasterFlag(false);
                input->setChainMaster(track->id());
                track->addManagedTrack(input->id());
            }
        }
        mPort++;
        //FIXME: Provice a non-iterative way to do this using the new losMidiPorts hash
        //Or maintain a list of configured or inuse ports
        while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
            mPort++;//Just incase we have a configured port after an empty one
    }

    if (!merge)
    {
        TrackList* tl = song->tracks();
        if (!tl->empty())
        {
            Track* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
コード例 #3
0
ファイル: tracklistview.cpp プロジェクト: peter1000/los
void TrackListView::populateTable()/*{{{*/
{
    if(debugMsg)
        printf("TrackListView::populateTable\n");
    QScrollBar *bar = m_table->verticalScrollBar();
    int barPos = 0;
    if(bar)
        barPos = bar->sliderPosition();

    m_model->clear();
    for(iMidiTrack i = song->artracks()->begin(); i != song->artracks()->end(); ++i)
    {
        MidiTrack* track = (MidiTrack*)(*i);
        PartList* pl = track->parts();
        if(m_displayRole == PartRole && pl->empty())
        {
            continue;
        }

        QStandardItem* trackName = new QStandardItem();
        trackName->setForeground(QBrush(QColor(205,209,205)));
        trackName->setBackground(QBrush(QColor(20,20,20)));
        trackName->setFont(QFont("fixed-width", 10, QFont::Bold));
        trackName->setText(track->name());
        trackName->setCheckable(true);
        trackName->setCheckState(m_selectedTracks.contains(track->id()) ? Qt::Checked : Qt::Unchecked);

        trackName->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        trackName->setData(1, TrackRole);
        trackName->setData(track->name(), TrackNameRole);
        trackName->setData(track->id(), TrackIdRole);
        trackName->setEditable(true);
        m_model->appendRow(trackName);

        for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
        {
            Part* part = ip->second;
            QStandardItem* partName = new QStandardItem();
            partName->setFont(QFont("fixed-width", 9, QFont::Bold));
            partName->setText(part->name());
            partName->setData(part->sn(), PartRole);
            partName->setData(2, TrackRole);
            partName->setData(track->name(), TrackNameRole);
            partName->setData(part->name(), PartNameRole);
            partName->setData(part->tick(), TickRole);
            partName->setData(track->id(), TrackIdRole);
            partName->setEditable(true);
            partName->setCheckable(true);
            partName->setCheckState(m_editor->hasPart(part->sn()) ? Qt::Checked : Qt::Unchecked);

            if(!partColorIcons.isEmpty() && part->colorIndex() < partColorIcons.size())
                partName->setIcon(partColorIcons.at(part->colorIndex()));

            m_model->appendRow(partName);
        }
    }
    m_model->setHorizontalHeaderLabels(m_headers);
    if(m_selectedIndex < m_model->rowCount())
    {
        m_table->selectRow(m_selectedIndex);
        m_table->scrollTo(m_model->index(m_selectedIndex, 0));
    }
    if(bar)
        bar->setSliderPosition(barPos);
}/*}}}*/