⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lilypondexporter.cpp

📁 LINUX下的混音软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    tmpStr.replace(QRegExp("\\^"), "\\^");    tmpStr.replace(QRegExp("%"), "\\%");    tmpStr.replace(QRegExp("<"), "\\<");    tmpStr.replace(QRegExp(">"), "\\>");    tmpStr.replace(QRegExp("\\["), "");    tmpStr.replace(QRegExp("\\]"), "");    tmpStr.replace(QRegExp("\\{"), "");    tmpStr.replace(QRegExp("\\}"), "");    //    // LilyPond uses utf8 encoding.    //    return tmpStr.utf8().data();}boolLilypondExporter::write(){    QString tmpName = strtoqstr(m_fileName);    // dmm - modified to act upon the filename itself, rather than the whole    // path; fixes bug #855349    // split name into parts:    QFileInfo nfo(tmpName);    QString dirName = nfo.dirPath();    QString baseName = nfo.fileName();    // sed Lilypond-choking chars out of the filename proper    bool illegalFilename = (baseName.contains(' ') || baseName.contains("\\"));    baseName.replace(QRegExp(" "), "");    baseName.replace(QRegExp("\\\\"), "");    baseName.replace(QRegExp("'"), "");    baseName.replace(QRegExp("\""), "");    // cat back together    tmpName = dirName + '/' + baseName;    if (illegalFilename) {        CurrentProgressDialog::freeze();        int reply = KMessageBox::warningContinueCancel(                        0, i18n("Lilypond does not allow spaces or backslashes in filenames.\n\n"                                "Would you like to use\n\n %1\n\n instead?").arg(baseName));        if (reply != KMessageBox::Continue)            return false;    }    std::ofstream str(qstrtostr(tmpName).c_str(), std::ios::out);    if (!str) {        std::cerr << "LilypondExporter::write() - can't write file " << tmpName << std::endl;        return false;    }    str << "% This LilyPond file was generated by Rosegarden " << protectIllegalChars(VERSION) << std::endl;    switch (m_languageLevel) {    case LILYPOND_VERSION_2_6:        str << "\\version \"2.6.0\"" << std::endl;        break;    case LILYPOND_VERSION_2_8:        str << "\\version \"2.8.0\"" << std::endl;        break;    case LILYPOND_VERSION_2_10:        str << "\\version \"2.10.0\"" << std::endl;        break;    case LILYPOND_VERSION_2_12:        str << "\\version \"2.12.0\"" << std::endl;        break;    default:        // force the default version if there was an error        std::cerr << "ERROR: Unknown language level " << m_languageLevel	    << ", using \\version \"2.6.0\" instead" << std::endl;        str << "\\version \"2.6.0\"" << std::endl;        m_languageLevel = LILYPOND_VERSION_2_6;    }    // enable "point and click" debugging via pdf to make finding the    // unfortunately inevitable errors easier    if (m_exportPointAndClick) {        str << "% point and click debugging is enabled" << std::endl;    } else {        str << "% point and click debugging is disabled" << std::endl;        str << "#(ly:set-option 'point-and-click #f)" << std::endl;    }    // Lilypond \header block    // set indention level to make future changes to horizontal layout less    // tedious, ++col to indent a new level, --col to de-indent    int col = 0;    // grab user headers from metadata    Configuration metadata = m_composition->getMetadata();    std::vector<std::string> propertyNames = metadata.getPropertyNames();    // open \header section if there's metadata to grab, and if the user    // wishes it    if (!propertyNames.empty()) {        str << "\\header {" << std::endl;        col++;  // indent+        bool userTagline = false;        for (unsigned int index = 0; index < propertyNames.size(); ++index) {            std::string property = propertyNames [index];            if (property == headerDedication || property == headerTitle ||                    property == headerSubtitle || property == headerSubsubtitle ||                    property == headerPoet || property == headerComposer ||                    property == headerMeter || property == headerOpus ||                    property == headerArranger || property == headerInstrument ||                    property == headerPiece || property == headerCopyright ||                    property == headerTagline) {                std::string header = protectIllegalChars(metadata.get<String>(property));                if (header != "") {                    str << indent(col) << property << " = \"" << header << "\"" << std::endl;                    // let users override defaults, but allow for providing                    // defaults if they don't:                    if (property == headerTagline)                        userTagline = true;                }            }        }        // default tagline        if (!userTagline) {            str << indent(col) << "tagline = \""            << "Created using Rosegarden " << protectIllegalChars(VERSION) << " and LilyPond"            << "\"" << std::endl;        }        // close \header        str << indent(--col) << "}" << std::endl;    }    // Lilypond \paper block (optional)    if (m_raggedBottom) {        str << indent(col) << "\\paper {" << std::endl;        str << indent(++col) << "ragged-bottom=##t" << std::endl;        str << indent(--col) << "}" << std::endl;    }    // Lilypond music data!   Mapping:    // Lilypond Voice = Rosegarden Segment    // Lilypond Staff = Rosegarden Track    // (not the cleanest output but maybe the most reliable)    // paper/font sizes    int font;    switch (m_fontSize) {    case 0 :        font = 11;        break;    case 1 :        font = 13;        break;    case 2 :        font = 16;        break;    case 3 :        font = 19;        break;    case 4 :        font = 20;        break;    case 5 :        font = 23;        break;    case 6 :        font = 26;        break;    default :	font = 20; // if config problem    }    str << indent(col) << "#(set-global-staff-size " << font << ")" << std::endl;    // write user-specified paper type as default paper size    std::string paper = "";    switch (m_paperSize) {    case PAPER_A3 :        paper += "a3";        break;    case PAPER_A4 :        paper += "a4";        break;    case PAPER_A5 :        paper += "a5";        break;    case PAPER_A6 :        paper += "a6";        break;    case PAPER_LEGAL :        paper += "legal";        break;    case PAPER_LETTER :        paper += "letter";        break;    case PAPER_TABLOID :        paper += "tabloid";        break;    case PAPER_NONE :        paper = "";        break; // "do not specify"    }    if (paper != "") {        str << indent(col) << "#(set-default-paper-size \"" << paper << "\"" 	    << (m_paperLandscape ? " 'landscape" : "") << ")"	    << std::endl;    }    // Find out the printed length of the composition    Composition::iterator i = m_composition->begin();    if ((*i) == NULL) {        str << indent(col) << "\\score {" << std::endl;        str << indent(++col) << "% no segments found" << std::endl;        // bind staffs with or without staff group bracket        str << indent(col) // indent	    << "<<" << " s4 " << ">>" << std::endl;        str << indent(col) << "\\layout { }" << std::endl;        str << indent(--col) << "}" << std::endl;        return true;    }    timeT compositionStartTime = (*i)->getStartTime();    timeT compositionEndTime = (*i)->getEndMarkerTime();    for (; i != m_composition->end(); ++i) {        if (compositionStartTime > (*i)->getStartTime() && (*i)->getTrack() >= 0) {            compositionStartTime = (*i)->getStartTime();        }        if (compositionEndTime < (*i)->getEndMarkerTime()) {            compositionEndTime = (*i)->getEndMarkerTime();        }    }    // define global context which is common for all staffs    str << indent(col++) << "global = { " << std::endl;    TimeSignature timeSignature = m_composition->                                  getTimeSignatureAt(m_composition->getStartMarker());    if (m_composition->getBarStart(m_composition->getBarNumber(compositionStartTime)) < compositionStartTime) {        str << indent(col) << "\\partial ";        // Arbitrary partial durations are handled by the following way:        // split the partial duration to 64th notes: instead of "4" write "64*16". (hjj)        Note partialNote = Note::getNearestNote(1, MAX_DOTS);        int partialDuration = m_composition->getBarStart(m_composition->getBarNumber(compositionStartTime) + 1) - compositionStartTime;        writeDuration(1, str);        str << "*" << ((int)(partialDuration / partialNote.getDuration()))        << std::endl;    }    int leftBar = 0;    int rightBar = leftBar;    do {        bool isNew = false;        m_composition->getTimeSignatureInBar(rightBar + 1, isNew);        if (isNew || (m_composition->getBarStart(rightBar + 1) >= compositionEndTime)) {            //  - set initial time signature; further time signature changes            //    are defined within the segments, because they may be hidden            str << indent(col) << (leftBar == 0 ? "" : "% ") << "\\time "            << timeSignature.getNumerator() << "/"            << timeSignature.getDenominator() << std::endl;            //  - place skips upto the end of the composition;            //    this justifies the printed staffs            str << indent(col);            timeT leftTime = m_composition->getBarStart(leftBar);            timeT rightTime = m_composition->getBarStart(rightBar + 1);            if (leftTime < compositionStartTime) {                leftTime = compositionStartTime;            }            writeSkip(timeSignature, leftTime, rightTime - leftTime, false, str);            str << " %% " << (leftBar + 1) << "-" << (rightBar + 1) << std::endl;            timeSignature = m_composition->getTimeSignatureInBar(rightBar + 1, isNew);            leftBar = rightBar + 1;        }    } while (m_composition->getBarStart(++rightBar) < compositionEndTime);    str << indent(--col) << "}" << std::endl;    // time signatures changes are in segments, reset initial value    timeSignature = m_composition->                    getTimeSignatureAt(m_composition->getStartMarker());    // All the tempo changes are included in "globalTempo" context.    // This context contains only skip notes between the tempo changes.    // First tempo marking should still be include in \midi{ } block.    // If tempo marks are printed in future, they should probably be    // included in this context and the note duration in the tempo    // mark should be according to the time signature. (hjj)    int tempoCount = m_composition->getTempoChangeCount();    if (tempoCount > 0) {        timeT prevTempoChangeTime = m_composition->getStartMarker();        int tempo = int(Composition::getTempoQpm(m_composition->getTempoAtTime(prevTempoChangeTime)));        bool tempoMarksInvisible = false;        str << indent(col++) << "globalTempo = {" << std::endl;        if (m_exportTempoMarks == EXPORT_NONE_TEMPO_MARKS && tempoMarksInvisible == false) {            str << indent(col) << "\\override Score.MetronomeMark #'transparent = ##t" << std::endl;            tempoMarksInvisible = true;        }        str << indent(col) << "\\tempo 4 = " << tempo << "  ";        int prevTempo = tempo;        for (int i = 0; i < tempoCount; ++i) {            std::pair<timeT, long> tempoChange =                m_composition->getTempoChange(i);            timeT tempoChangeTime = tempoChange.first;            tempo = int(Composition::getTempoQpm(tempoChange.second));            // First tempo change may be before the first segment.            // Do not apply it before the first segment appears.            if (tempoChangeTime < compositionStartTime) {                tempoChangeTime = compositionStartTime;            } else if (tempoChangeTime >= compositionEndTime) {                tempoChangeTime = compositionEndTime;            }            if (prevTempoChangeTime < compositionStartTime) {                prevTempoChangeTime = compositionStartTime;            } else if (prevTempoChangeTime >= compositionEndTime) {                prevTempoChangeTime = compositionEndTime;            }            writeSkip(m_composition->getTimeSignatureAt(tempoChangeTime),                      tempoChangeTime, tempoChangeTime - prevTempoChangeTime, false, str);            // add new \tempo only if tempo was changed            if (tempo != prevTempo) {                if (m_exportTempoMarks == EXPORT_FIRST_TEMPO_MARK && tempoMarksInvisible == false) {                    str << std::endl << indent(col) << "\\override Score.MetronomeMark #'transparent = ##t";                    tempoMarksInvisible = true;                }                str << std::endl << indent(col) << "\\tempo 4 = " << tempo << "  ";            }            prevTempo = tempo;            prevTempoChangeTime = tempoChangeTime;            if (prevTempoChangeTime == compositionEndTime)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -