//============================================== // MuseScore // // Quena Notation plugin for MuseScore Ver. 2.0 // // Copyright (C)2012-2015 Hiroshi Tachibana // // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . //============================================== import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import MuseScore 1.0 import FileIO 1.0 MuseScore { menuPath: "Plugins.Quena Fingerings" version: "2.0.02" description: qsTr("Quena fingerings, Note names") pluginType: "dialog" id: window width:285 // menu window size height:285 ExclusiveGroup { id: exclusiveGroupKey } property var fileExist :true property var seplines property var quenaLengthListInit : 12 property var fontListInit : 0 property var fontSizeInit : 16 property var yPositionInit : 0 property var xPositionInit : 0 property var partListInit : 0 property var colorListInit : 0 property var itemX1 : 10 property var itemX2 : 150 property var itemY1 : 10 property var itemDY : 25 RowLayout { //====================== Length id: row0 x :itemX1 y :itemY1+itemDY*0 Label { font.pointSize: 14 text: "Quena type" } } RowLayout { id: row0R x :itemX2 y :itemY1+itemDY*0 ComboBox { currentIndex: quenaLengthListInit model: ListModel { id: quenaLengthList property var key ListElement { text: "High G5"; fName: -12 } ListElement { text: "High F#5"; fName: -11 } ListElement { text: "High F5"; fName: -10 } ListElement { text: "High E5"; fName: -9 } ListElement { text: "High D#5"; fName: -8 } ListElement { text: "High D5"; fName: -7 } ListElement { text: "C#5"; fName: -6 } ListElement { text: "C5"; fName: -5 } ListElement { text: "B4"; fName: -4 } ListElement { text: "A#4"; fName: -3 } ListElement { text: "A4"; fName: -2 } ListElement { text: "G#4"; fName: -1 } ListElement { text: "G4 ====="; fName: 0 } ListElement { text: "F#4"; fName: 1 } ListElement { text: "F4"; fName: 2 } ListElement { text: "E4"; fName: 3 } ListElement { text: "D#4"; fName: 4 } ListElement { text: "D4"; fName: 5 } ListElement { text: "Low C#4 Low"; fName: 6 } ListElement { text: "Low C4 Low"; fName: 7 } ListElement { text: "Low B3 Low"; fName: 8 } ListElement { text: "Low A#3 Low"; fName: 9 } ListElement { text: "Low A3 Low"; fName: 10 } ListElement { text: "Low G#3 Low"; fName: 11 } ListElement { text: "Low G3 Low"; fName: 12 } } width: 100 onCurrentIndexChanged: { // console.debug(quenaLengthList.get(currentIndex).text + ", " + quenaLengthList.get(currentIndex).fName) // console.debug(", " + quenaLengthList.get(currentIndex).fName) quenaLengthList.key = quenaLengthList.get(currentIndex).fName } } // end ComboBox } RowLayout { //====================== Font type, Fingering or Note name id: row1 x :itemX1 y :itemY1+itemDY*1 Label { font.pointSize: 14 text: "Display" } } RowLayout { id: row1R x :itemX2 y :itemY1+itemDY*1 ComboBox { currentIndex: fontListInit model: ListModel { id: fontList property var key ListElement { text: "DoReMi+Fingering"; fName:1 } ListElement { text: "CDE+Fingering"; fName:2 } ListElement { text: "Fingering"; fName:3 } ListElement { text: "DoReMi"; fName:4 } ListElement { text: "CDEFG"; fName:5 } } width: 100 onCurrentIndexChanged: { console.debug("fontList "+fontList.get(currentIndex).text + ", " + fontList.get(currentIndex).fName) fontList.key = fontList.get(currentIndex).fName } } // end ComboBox } RowLayout { //====================== FONT SIZE id: row2 x :itemX1 y :itemY1+itemDY*2+5 Label { font.pointSize: 14 text: "Font Size" } } RowLayout { id: row2R x :itemX2 y :itemY1+itemDY*2+5 SpinBox { id: valFontSize implicitWidth: 55 decimals: 0 minimumValue: 4 maximumValue: 36 value: fontSizeInit font.pointSize: 14 } } RowLayout { //====================== Y POSITION id: row3 x :itemX1 y :itemY1+itemDY*3+5 Label { font.pointSize: 14 text: "Y Position" } } RowLayout { id: row3R x :itemX2 y :itemY1+itemDY*3+5 SpinBox { id: valYPosition implicitWidth: 55 decimals: 0 minimumValue: -20 maximumValue: 30 value: yPositionInit font.pointSize: 14 } } RowLayout { //====================== X POSITION id: row4 x :itemX1 y :itemY1+itemDY*4+40 Label { font.pointSize: 14 text: "X Position" } } RowLayout { id: row4R x :itemX2 y :itemY1+itemDY*4+40 SpinBox { id: valXPosition implicitWidth: 55 decimals: 1 minimumValue: -5 maximumValue: 5 value: xPositionInit stepSize: 0.1 font.pointSize: 14 } } RowLayout { //====================== PART id: row5 x :itemX1 y :itemY1+itemDY*5+40 Label { font.pointSize: 14 text: "Part" } } RowLayout { id: row5R x :itemX2 y :itemY1+itemDY*5+40 ComboBox { currentIndex: partListInit model: ListModel { id: partList property var key ListElement { text: "Part 1"; pName: 0 } ListElement { text: "Part 2"; pName: 1 } ListElement { text: "Part 3"; pName: 2 } ListElement { text: "Part 4"; pName: 3 } } width: 60 onCurrentIndexChanged: { //console.debug(partList.get(currentIndex).text + ", " + partList.get(currentIndex).pName) partList.key = partList.get(currentIndex).pName } } // end ComboBox } RowLayout { //====================== COLOR id: row6 x :itemX1 y :itemY1+itemDY*6+40 Label { font.pointSize: 14 text: "Color" } } RowLayout { id: row6R x :itemX2 y :itemY1+itemDY*6+40 ComboBox { currentIndex: colorListInit model: ListModel { id: colorList property var key ListElement { text: "Black"; cName: 0 } ListElement { text: "Red"; cName: 1 } ListElement { text: "Blue"; cName: 2 } ListElement { text: "Green"; cName: 3 } ListElement { text: "Purple"; cName: 4 } ListElement { text: "Gray"; cName: 5 } } width: 60 onCurrentIndexChanged: { //console.debug(colorList.get(currentIndex).text + ", " + colorList.get(currentIndex).cName) colorList.key = colorList.get(currentIndex).cName } } // end ComboBox } RowLayout { //====================== CANCEL / OK id: row7 x : 150 y : 250 Button { id: closeButton text: "Cancel" onClicked: { Qt.quit() } } Button { id: okButton text: "Ok" onClicked: { apply() Qt.quit() } } } function apply() { curScore.startCmd() var cursor = curScore.newCursor(); var startStaff; var endStaff; var endTick; var fullScore = false; var quenaLength = Number(quenaLengthList.key); //console.log("QuenaLength="+quenaLength); var fingerings = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", // "Q", "R", "S", "T", "U", "V", "W", "X","Y", "Z", "a", "b", "c", "d", // "e", "f", "g", "h", "i", "j", "k"] // 1-37 // 3オクターブのG ソまで, "l", "m", "n", "o", "p", "q", "r"] // 1- 44 (0-43) length=44 var noteNameS = [ "C","C#","D","D#","E","F","F#","G","G#","A","A#","B" ] var noteNameF = [ "C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B" ] //console.log("fingerings.length="+fingerings.length); // RGB color Black , Red , Blue , Green , Purple , Gray var colorData= [ "#000000" ,"#FF0000" ,"#0000FF" ,"#00D000" ,"#C007C0" ,"#888888" ]; var fontColor=colorData[colorList.key]; //console.log(fontName); // var fontSizeTag=""; var fontFaceTag =""; var fontFaceTagS=""; var fontFaceTagF=""; var fontFaceTagE=""; var selPart=0; cursor.rewind(1); // 選択範囲の最初に移動 if (!cursor.segment) { // 選択がない場合 fullScore = true; startStaff = 0; // 最初 endStaff = curScore.nstaves - 1; // 終わり } else { startStaff = cursor.staffIdx; cursor.rewind(2); // 選択範囲の最後 if (cursor.tick == 0) { endTick = curScore.lastSegment.tick + 1; } else { endTick = cursor.tick; } endStaff = cursor.staffIdx; } //console.log("Part: "+partList.key); //console.log(startStaff + " - " + endStaff + " - " + endTick); for (var staff = startStaff; staff <= endStaff; staff++) { // 対象となった音符の最初から最後まで // for (var voice = 0; voice < 4; voice++) { // var voice=partList.key; // 声部の指定 cursor.rewind(1); // beginning of selection cursor.voice = partList.key; // 声部の指定 cursor.staffIdx = staff; if (fullScore) cursor.rewind(0); // 選択範囲がない場合は先頭から while (cursor.segment && (fullScore || cursor.tick < endTick)) { if (cursor.element && cursor.element.type == Element.CHORD) { var text = newElement(Element.STAFF_TEXT); // 指使い表示用 var text2 = newElement(Element.STAFF_TEXT); // ドレミ、CDE用 // ######################## GRACE ##################################### //#################################################################### var notes = cursor.element.notes; var pitchFing; var fontSizeTag; for (var i = 0; i < notes.length; i++) { // 和音の場合のループ // for (var i = 0; i < 1;i++) { // 和音の場合は、一番下の音のみ if(notes[i].tieBack == null ) { // タイの後ろ側の音譜でない場合 if(fontList.key==3) { // 指使いのみの表示------------------------------------- pitchFing=notes[i].pitch-55+quenaLength; if(pitchFing<0 || pitchFing>=fingerings.length) { // text.text=" "+text.text; // 演奏可能な音域外の場合 } else{ text.text = fingerings[pitchFing]+text.text ; text.color = fontColor; text.pos.x = valXPosition.value; text.pos.y = valYPosition.value+12; fontSizeTag=""; text.text = fontSizeTag + fontFaceTag + text.text; } if(i == notes.length-1) cursor.add(text); // if文としないと、MuseScoreがクラッシュする。 //console.log("text.text="+text.text) } else if(fontList.key==2) { // 指使いとCDE --------------------------------- pitchFing=notes[i].pitch-55+quenaLength; if(pitchFing<0 || pitchFing>=fingerings.length) { // 演奏可能な音域外の場合は半角スペース // text.text=" "+text.text; // text2.text=" "+text.text; } else{ // 演奏可能な音内の場合 // 運指 text.text = fingerings[pitchFing]+text.text ; // 運指の文字コードを与える text.color = fontColor; // 運指の色を与える text.pos.x = valXPosition.value; // 運指のX方向位置を与える text.pos.y = valYPosition.value+15; // 運指のY方向位置を与える fontSizeTag=""; // 運指図の場合、文字サイズを拡大 text.text = fontSizeTag + fontFaceTag + text.text; // 文字サイズと運指用フォント名を与える // CDE if(notes[i].tpc>=6 && notes[i].tpc<=12 ) { // プロパティーtpcで判定、 flat ♭の場合 text2.text=noteNameF[(notes[i].pitch % 12)] +text2.text; // ♭場合の英語音名を与える } else if ( notes[i].tpc>=20 && notes[i].tpc<=26 ){ // sharp ♯の場合 text2.text=qsTr(noteNameS[(notes[i].pitch % 12)]) +text2.text ; // ♯場合の英語音名を与える } else{ // ♯♭でない場合は、♯♭どちらのフォントでもよい text2.text=qsTr(noteNameF[(notes[i].pitch % 12)]) +text2.text; } text2.color= fontColor; // 英語音名の色を与える text2.pos.x= valXPosition.value; // 英語音名のX方向位置を与える text2.pos.y = valYPosition.value+12; // 英語音名のY方向位置を与える fontSizeTag=""; text2.text= fontSizeTag + fontFaceTagE + text2.text; // 文字サイズと英語音名用フォント名を与える } if(i == notes.length-1) cursor.add(text); // 運指を表示する if(i == notes.length-1) cursor.add(text2); // CDEを表示する //console.log("text.text="+text.text) //console.log("text2.text="+text2.text) } else if(fontList.key==1) { // 指使いとドレミDoReMi--------------------------- pitchFing=notes[i].pitch-55+quenaLength; if(pitchFing<0 || pitchFing>=fingerings.length) { // 演奏可能な音域外の場合 // text.text=" "+text.text; // text2.text=" "+text.text; } else{ // 演奏可能な音内の場合 // 運指 text.text = fingerings[pitchFing]+text.text ; text.color = fontColor; text.pos.x = valXPosition.value; text.pos.y = valYPosition.value+15; fontSizeTag=""; text.text = fontSizeTag +fontFaceTag+ text.text; // ドレミ // pitchFing=(notes[i].pitch +quenaLength) % 12 ; //移動ドに対応する場合 pitchFing=(notes[i].pitch ) % 12 ; text2.text=fingerings[pitchFing]+text2.text ; fontSizeTag=""; if(notes[i].tpc>=6 && notes[i].tpc<=12 ) { // Flat ドレミ♭ text2.text= fontSizeTag + fontFaceTagF + text2.text; } else if ( notes[i].tpc>=20 && notes[i].tpc<=26 ){ // Sharp ドレミ♯ text2.text= fontSizeTag + fontFaceTagS + text2.text; } else { text2.text= fontSizeTag + fontFaceTagS + text2.text; } text2.color = fontColor; text2.pos.x = valXPosition.value; text2.pos.y = valYPosition.value+12; //console.log("text.text="+text.text) //console.log("text2.text="+text2.text) } if(i == notes.length-1) cursor.add(text); if(i == notes.length-1) cursor.add(text2); } else if(fontList.key==5) { // CDEのみ---------------------------------- if ( i > 0 ) text2.text = "\n"+ text2.text; // 和音の場合は、順次改行して縦に表示する。 if(notes[i].tpc>=6 && notes[i].tpc<=12 ) { // flat ♭の場合 text2.text=noteNameF[(notes[i].pitch % 12)] +text2.text; // ♭場合の英語音名を与える } else if ( notes[i].tpc>=20 && notes[i].tpc<=26 ){ // sharp ♯の場合 text2.text=qsTr(noteNameS[(notes[i].pitch % 12)]) +text2.text ; } else{ text2.text=qsTr(noteNameF[(notes[i].pitch % 12)]) +text2.text ; } text2.color= fontColor; text2.pos.x= valXPosition.value; text2.pos.y = valYPosition.value+12; fontSizeTag=""; text2.text= fontSizeTag + fontFaceTagE + text2.text; if(i == notes.length-1) cursor.add(text2); //console.log("text2.text="+text2.text) } else if(fontList.key==4) { // DoReMiのみ------------------------------- if ( i > 0 ) text2.text = "\n"+ text2.text; // 和音の場合は、順次改行して縦に表示する。 // pitchFing=(notes[i].pitch +quenaLength) % 12 ; pitchFing=(notes[i].pitch) % 12 ; text2.text=fingerings[pitchFing]+text2.text ; fontSizeTag=""; // 英語音名より少し小さめとする。 if(notes[i].tpc>=6 && notes[i].tpc<=12 ) { // Flat ドレミ♭ text2.text= fontSizeTag + fontFaceTagF + text2.text; } else if ( notes[i].tpc>=20 && notes[i].tpc<=26 ) { // Sharp ドレミ♯ text2.text= fontSizeTag + fontFaceTagS + text2.text; } else { text2.text= fontSizeTag + fontFaceTagS + text2.text; } text2.color = fontColor; text2.pos.x = valXPosition.value; text2.pos.y = valYPosition.value+12; if(i == notes.length-1) cursor.add(text2); //console.log("text2.text="+text2.text) } } // end != Tie /* switch (voice) { case 0: text.pos.y = yPos; break; case 1: text.pos.y = yPos+2; break; case 2: text.pos.y = yPos+4; break; case 3: text.pos.y = yPos+6; break; } */ } // end for note i 和音 } // end if CHORD cursor.next(); // 次の音符へ移動する } // end while segment } // end for staff // Qt.quit(); curScore.endCmd() // write to file /// my_file1.write(quenaLengthList.key+"\n"+fontList.key+"\n"+valFontSize.value+"\n"+valYPosition.value+"\n"+valXPosition.value+"\n"+partList.key+"\n"+colorList.key) //console.log("quenaLengthList.key="+quenaLengthList.key) Qt.quit(); } // end apply onRun: { /*/ if( fileExist ) var fileContents = my_file1.read(); if( !fileExist ) var fileContents="12\n0\n16\n0\n0\n0\n0\n0"; console.log("fileExist="+fileExist); //console.log("fileContents="+fileContents); seplines=fileContents.split("\n"); quenaLengthListInit=Number(seplines[0]); fontListInit=Number(seplines[1]); fontSizeInit=Number(seplines[2]); yPositionInit=Number(seplines[3]); xPositionInit=Number(seplines[4]); partListInit=Number(seplines[5]); colorListInit=Number(seplines[6]); /*/ if (typeof curScore === 'undefined') Qt.quit(); // Qt.quit(); } // end onRun FileIO { id: my_file1 /// source: tempPath() + "/temp9999q.txt" /// source: "/Users/tac201403/Documents/temp9999q.txt" /// source: "/Users/tac/Documents/temp9999q.txt" onError: fileExist=false // console.log(msg) } } // end MuseScore